package com.by4cloud.platformx.business.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.by4cloud.platformx.admin.api.entity.SysDept; import com.by4cloud.platformx.admin.api.feign.RemoteDeptService; import com.by4cloud.platformx.business.api.feign.RemoteFlowProcessService; import com.by4cloud.platformx.business.constant.FlowNameEnum; import com.by4cloud.platformx.business.dto.ContractAddDTO; import com.by4cloud.platformx.business.dto.ContractUpdateDTO; import com.by4cloud.platformx.business.entity.*; import com.by4cloud.platformx.business.mapper.*; import com.by4cloud.platformx.business.service.ContractService; import com.by4cloud.platformx.business.utils.ContractNumberGenerator; import com.by4cloud.platformx.business.vo.ContractDetailVo; import com.by4cloud.platformx.common.core.util.R; import com.by4cloud.platformx.common.security.util.SecurityUtils; import com.by4cloud.platformx.flow.task.dto.ProcessInstanceParamDto; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.RowRenderData; import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.OutputStream; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; /** * @author cd * @description * @date 2026/4/29 14:07 **/ @Service @RequiredArgsConstructor public class ContractServiceImpl extends ServiceImpl implements ContractService { private final ContractSubjectMatterMapper contractSubjectMatterMapper; private final ContractPaymentScheduleMapper contractPaymentScheduleMapper; private final ContractPaymentScheduleProcessMapper contractPaymentScheduleProcessMapper; private final PaymentConfirmMapper paymentConfirmMapper; private final CurrentOverdueMapper currentOverdueMapper; private final BusinessCustomerMapper businessCustomerMapper; private final RemoteFlowProcessService remoteFlowProcessService; private final ContractTemplateMapper contractTemplateMapper; private final RemoteDeptService remoteDeptService; @Value("${file.local.base-path}") private String basePath; @Override public R add(ContractAddDTO addDTO) { Contract contract = BeanUtil.copyProperties(addDTO,Contract.class); contract.setPartyBId(SecurityUtils.getUser().getCompId()); contract.setPartyB(SecurityUtils.getUser().getCompName()); contract.setContractNo(ContractNumberGenerator.generateContractNumber()); contract.setPaidAmount(new BigDecimal("0")); contract.setBillingStatus("0"); contract.setErpPushFlag("0"); List contracts; contracts = baseMapper.selectList(Wrappers.lambdaQuery().eq(Contract::getContractNo,contract.getContractNo())); while (ArrayUtil.isNotEmpty(contracts.toArray())){ contract.setContractNo(ContractNumberGenerator.generateContractNumber()); contracts = baseMapper.selectList(Wrappers.lambdaQuery().eq(Contract::getContractNo,contract.getContractNo())); } baseMapper.insert(contract); if (ArrayUtil.isNotEmpty(addDTO.getContractSubjectMatter())){ addDTO.getContractSubjectMatter().stream().forEach(contractSubjectMatterAddDTO -> { ContractSubjectMatter subjectMatter = BeanUtil.copyProperties(contractSubjectMatterAddDTO, ContractSubjectMatter.class); subjectMatter.setContractId(contract.getId()); subjectMatter.setContractName(contract.getContractName()); subjectMatter.setDeliveredQuantity(new BigDecimal("0")); subjectMatter.setDeliveryStatus(0); subjectMatter.setTotalAmount(contractSubjectMatterAddDTO.getQuantity().multiply(contractSubjectMatterAddDTO.getUnitPrice())); contractSubjectMatterMapper.insert(subjectMatter); }); } if (ArrayUtil.isNotEmpty(addDTO.getContractPaymentSchedule())){ AtomicInteger index = new AtomicInteger(1); addDTO.getContractPaymentSchedule().stream().forEach(contractPaymentScheduleAddDTO -> { int currentIndex = index.getAndIncrement(); ContractPaymentSchedule schedule = BeanUtil.copyProperties(contractPaymentScheduleAddDTO, ContractPaymentSchedule.class); if (contractPaymentScheduleAddDTO.getStageName().equals("合同签订")){ schedule.setEffectiveDate(DateUtil.offsetDay(contract.getSignDate(),contractPaymentScheduleAddDTO.getAgreedDays())); } if (ObjUtil.isNotNull(schedule.getEffectiveDate())) { if (schedule.getEffectiveDate().before(DateUtil.date())) { schedule.setFulfillmentStatus(1); } else { schedule.setFulfillmentStatus(0); } } schedule.setPaymentStatus(0); schedule.setContractId(contract.getId()); schedule.setContractName(contract.getContractName()); schedule.setPlannedAmount(contract.getAmount().multiply(schedule.getPaymentRatio().divide(new BigDecimal("100")))); schedule.setStageOrder(currentIndex); contractPaymentScheduleMapper.insert(schedule); if (contractPaymentScheduleAddDTO.getStageName().equals("货到签收")){ contract.setArrivalScheduleId(schedule.getId()); baseMapper.updateById(contract); } if (contractPaymentScheduleAddDTO.getStageName().equals("调试完成或验收")){ contract.setAcceptScheduleId(schedule.getId()); baseMapper.updateById(contract); } }); } return R.ok(); } @Override public R edit(ContractUpdateDTO updateDTO) { Contract entity = baseMapper.selectById(updateDTO.getId()); if (!StrUtil.equals(entity.getContractStatus()+"","0")){ return R.failed("当前状态无法修改合同"); } Contract contract = BeanUtil.copyProperties(updateDTO,Contract.class); contract.setContractNo(ContractNumberGenerator.generateContractNumber()); contract.setBillingStatus("0"); contract.setErpPushFlag("0"); contract.setPaidAmount(new BigDecimal("0")); List contracts; contracts = baseMapper.selectList(Wrappers.lambdaQuery().eq(Contract::getContractNo,contract.getContractNo())); while (ArrayUtil.isNotEmpty(contracts.toArray())){ contract.setContractNo(ContractNumberGenerator.generateContractNumber()); contracts = baseMapper.selectList(Wrappers.lambdaQuery().eq(Contract::getContractNo,contract.getContractNo())); } baseMapper.updateById(contract); if (ArrayUtil.isNotEmpty(updateDTO.getContractSubjectMatter())){ contractSubjectMatterMapper.delete(Wrappers.lambdaQuery().eq(ContractSubjectMatter::getContractId,contract.getId())); updateDTO.getContractSubjectMatter().stream().forEach(contractSubjectMatterAddDTO -> { ContractSubjectMatter subjectMatter = BeanUtil.copyProperties(contractSubjectMatterAddDTO, ContractSubjectMatter.class); subjectMatter.setContractId(contract.getId()); subjectMatter.setContractName(contract.getContractName()); subjectMatter.setDeliveredQuantity(new BigDecimal("0")); subjectMatter.setDeliveryStatus(0); contractSubjectMatterMapper.insert(subjectMatter); }); } if (ArrayUtil.isNotEmpty(updateDTO.getContractPaymentSchedule())){ contractPaymentScheduleMapper.delete(Wrappers.lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId())); AtomicInteger index = new AtomicInteger(1); updateDTO.getContractPaymentSchedule().stream().forEach(contractPaymentScheduleAddDTO -> { int currentIndex = index.getAndIncrement(); ContractPaymentSchedule schedule = BeanUtil.copyProperties(contractPaymentScheduleAddDTO, ContractPaymentSchedule.class); schedule.setContractId(contract.getId()); schedule.setContractName(contract.getContractName()); schedule.setPlannedAmount(contract.getAmount().multiply(schedule.getPaymentRatio().divide(new BigDecimal("100")))); schedule.setStageOrder(currentIndex); contractPaymentScheduleMapper.insert(schedule); if (contractPaymentScheduleAddDTO.getStageName().equals("货到签收")){ contract.setArrivalScheduleId(schedule.getId()); baseMapper.updateById(contract); } if (contractPaymentScheduleAddDTO.getStageName().equals("调试完成或验收")){ contract.setAcceptScheduleId(schedule.getId()); baseMapper.updateById(contract); } }); } return R.ok(); } @Override public ContractDetailVo detail(Long id) { Contract contract = baseMapper.selectById(id); ContractDetailVo detailVo = BeanUtil.copyProperties(contract,ContractDetailVo.class); List subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.lambdaQuery().eq(ContractSubjectMatter::getContractId,id)); detailVo.setContractSubjectMatter(subjectMatterList); List paymentScheduleList = contractPaymentScheduleMapper.selectList(Wrappers.lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId())); detailVo.setContractPaymentSchedule(paymentScheduleList); return detailVo; } @Override public R startApproval(Long id) { Contract contract = baseMapper.selectById(id); //启动流程 ProcessInstanceParamDto dto = new ProcessInstanceParamDto(); Map map = BeanUtil.beanToMap(contract); dto.setParamMap(map); dto.setFlowName(FlowNameEnum.合同审批.name()); R r1 = remoteFlowProcessService.startProcessInstance(dto); if (r1.getCode() == 1) { return R.failed("流程启动失败"); } contract.setContractStatus(1); baseMapper.updateById(contract); return R.ok(); } public void takeEffect(Long id) { Contract contract = baseMapper.selectById(id); contract.setContractStatus(2); baseMapper.updateById(contract); ContractPaymentSchedule fitstSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.lambdaQuery().eq(ContractPaymentSchedule::getContractId,contract.getId()) .orderByAsc(ContractPaymentSchedule::getCreateTime).last("limit 1")); if (fitstSchedule.getStageName().equals("合同签订")){ //新增应收 savePaymentConfirm(contract,fitstSchedule); //新增合同履约记录 ContractPaymentScheduleProcess process = new ContractPaymentScheduleProcess(); process.setContractId(contract.getId()); process.setContractName(contract.getContractName()); process.setScheduleId(fitstSchedule.getId()); process.setScheduleName(fitstSchedule.getStageName()); process.setProcessDate(contract.getSignDate()); contractPaymentScheduleProcessMapper.insert(process); // //当前为合同最后阶段 // PaymentConfirm newConfirm = paymentConfirmMapper.selectOne(Wrappers.lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId()) // .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); // if (ObjUtil.isNotNull(newConfirm)&&newConfirm.getTotalAmount().compareTo(new BigDecimal("0"))>=0){ // //有预付且超过应收 关闭合同状态 // contract.setContractStatus(3); // baseMapper.updateById(contract); // } }else if (fitstSchedule.getStageName().equals("发货前")) { //更新合同下个阶段 contract.setNextScheduleName("无"); baseMapper.updateById(contract); }else if (fitstSchedule.getStageName().equals("货到签收")) { //更新合同下个阶段 contract.setNextScheduleName("货到签收"); baseMapper.updateById(contract); }else if (fitstSchedule.getStageName().equals("调试完成或验收")) { //更新合同下个阶段 contract.setNextScheduleName("调试完成或验收"); baseMapper.updateById(contract); }else { //新增应收 savePaymentConfirm(contract,fitstSchedule); } //查询是否有后续阶段 List afterSchedule = contractPaymentScheduleMapper.selectList(Wrappers.lambdaQuery() .eq(ContractPaymentSchedule::getContractId, fitstSchedule.getContractId()) .gt(ContractPaymentSchedule::getStageOrder, fitstSchedule.getStageOrder()) .orderByAsc(ContractPaymentSchedule::getCreateTime)); if (ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()==1){ //最后阶段生效时间 ContractPaymentSchedule endSchedule = afterSchedule.get(0); if (StrUtil.equals(endSchedule.getStageName(),"质保金")){ endSchedule.setEffectiveDate(DateUtil.offsetDay(new Date(),endSchedule.getAgreedDays())); endSchedule.setEffectiveEndDate(contract.getExpirationDate()); contractPaymentScheduleMapper.updateById(endSchedule); //第一阶段生效时间 fitstSchedule.setEffectiveDate(DateUtil.offsetDay(contract.getSignDate(),fitstSchedule.getAgreedDays())); fitstSchedule.setEffectiveEndDate(endSchedule.getEffectiveDate()); contractPaymentScheduleMapper.updateById(fitstSchedule); //最后阶段应收 PaymentConfirm newConfim = new PaymentConfirm(); newConfim.setBusinessType(endSchedule.getStageName()+"应收"); newConfim.setBusGuestId(contract.getPartyAId()); newConfim.setBusGuestName(contract.getPartyA()); newConfim.setContractId(contract.getId()); newConfim.setContractName(contract.getContractName()); newConfim.setContractNo(contract.getContractNo()); newConfim.setScheduleId(endSchedule.getId()); newConfim.setScheduleName(endSchedule.getStageName()); newConfim.setConfirmTime(new Date()); newConfim.setTransationAmount(endSchedule.getPlannedAmount()); newConfim.setReceivableAmount(endSchedule.getPlannedAmount()); PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId()) .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); BigDecimal lastNewTotal = new BigDecimal("0"); if(ObjUtil.isNotNull(lastNewConfirm)){ lastNewTotal = lastNewConfirm.getTotalAmount(); } newConfim.setTotalAmount(lastNewTotal.subtract(newConfim.getReceivableAmount())); if (endSchedule.getPaymentRatio().compareTo(new BigDecimal("0"))>0) { paymentConfirmMapper.insert(newConfim); } } //更新合同下个阶段 contract.setNextScheduleName(endSchedule.getStageName()); baseMapper.updateById(contract); } if(ArrayUtil.isNotEmpty(afterSchedule.toArray())&&afterSchedule.size()>1){ //第一阶段生效时间 fitstSchedule.setEffectiveDate(DateUtil.offsetDay(contract.getSignDate(),fitstSchedule.getAgreedDays())); contractPaymentScheduleMapper.updateById(fitstSchedule); //更新合同下个阶段 contract.setNextScheduleName(afterSchedule.get(0).getStageName()); baseMapper.updateById(contract); } //只有当前合同签字阶段 if(ArrayUtil.isEmpty(afterSchedule.toArray())){ fitstSchedule.setEffectiveDate(DateUtil.offsetDay(contract.getSignDate(),fitstSchedule.getAgreedDays())); fitstSchedule.setEffectiveEndDate(contract.getExpirationDate()); contractPaymentScheduleMapper.updateById(fitstSchedule); } } private void savePaymentConfirm(Contract contract, ContractPaymentSchedule schedule) { PaymentConfirm paymentConfirm = new PaymentConfirm(); paymentConfirm.setBusinessType(schedule.getStageName()+"应收"); paymentConfirm.setBusGuestId(contract.getPartyAId()); paymentConfirm.setBusGuestName(contract.getPartyA()); paymentConfirm.setContractId(contract.getId()); paymentConfirm.setContractName(contract.getContractName()); paymentConfirm.setContractNo(contract.getContractNo()); paymentConfirm.setScheduleId(schedule.getId()); paymentConfirm.setScheduleName(schedule.getStageName()); paymentConfirm.setConfirmTime(new Date()); paymentConfirm.setTransationAmount(schedule.getPlannedAmount()); paymentConfirm.setReceivableAmount(schedule.getPlannedAmount()); paymentConfirm.setTotalAmount(schedule.getPlannedAmount().multiply(new BigDecimal("-1"))); PaymentConfirm lastNewConfirm = paymentConfirmMapper.selectOne(Wrappers.lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId()) .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); BigDecimal lastNewTotal = new BigDecimal("0"); if(ObjUtil.isNotNull(lastNewConfirm)){ lastNewTotal = lastNewConfirm.getTotalAmount(); } paymentConfirm.setTotalAmount(lastNewTotal.subtract(paymentConfirm.getReceivableAmount())); if (schedule.getPaymentRatio().compareTo(new BigDecimal("0"))>0){ paymentConfirmMapper.insert(paymentConfirm); } //客户付款完成合同 List customerCompleteContractList = baseMapper.selectList(Wrappers.lambdaQuery().eq(Contract::getPartyAId, contract.getPartyAId()) .eq(Contract::getPartyBId,SecurityUtils.getUser().getCompId()).apply(" amount = paid_amount")); if (ArrayUtil.isNotEmpty(customerCompleteContractList)){ List outAmountList = new ArrayList<>(); for (Contract completeContract:customerCompleteContractList ) { PaymentConfirm contractLastConfirm = paymentConfirmMapper.selectOne(Wrappers.lambdaQuery().eq(PaymentConfirm::getContractId,completeContract.getId()) .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); //查询客户付款完成合同中最后明细金额 有预收转入当前合同 if (contractLastConfirm.getTotalAmount().compareTo(new BigDecimal("0"))>0){ //新增完成付款合同 资金转出 PaymentConfirm outConfirm = BeanUtil.copyProperties(contractLastConfirm,PaymentConfirm.class,"id","transationAmount", "advanceAmount","receivableAmount","overdueAmount","totalAmount"); outConfirm.setBusinessType("资金转出"); outConfirm.setConfirmTime(new Date()); outConfirm.setTransationAmount(contractLastConfirm.getTotalAmount()); outConfirm.setTotalAmount(new BigDecimal("0")); paymentConfirmMapper.insert(outConfirm); outAmountList.add(outConfirm.getTransationAmount()); } } if (ArrayUtil.isNotEmpty(outAmountList.toArray())){ BigDecimal currentSum = new BigDecimal("0"); for (BigDecimal currentAmount:outAmountList ) { currentSum=currentSum.add(currentAmount); //新增当前合同 资金转入 PaymentConfirm inConfirm = BeanUtil.copyProperties(paymentConfirm,PaymentConfirm.class,"id","transationAmount", "advanceAmount","receivableAmount","overdueAmount","totalAmount"); inConfirm.setBusinessType("资金转入"); inConfirm.setConfirmTime(new Date()); inConfirm.setTransationAmount(currentSum.subtract(currentAmount)); inConfirm.setTotalAmount(paymentConfirm.getTotalAmount().add(currentSum)); if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0"))>0){ inConfirm.setAdvanceAmount(inConfirm.getTotalAmount()); }else if (inConfirm.getTotalAmount().compareTo(new BigDecimal("0"))<0){ inConfirm.setReceivableAmount(inConfirm.getTotalAmount().multiply(new BigDecimal("-1"))); } paymentConfirmMapper.insert(inConfirm); } } } } @Override public R genCurrentOverdue() { List scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.lambdaQuery() .lt(ContractPaymentSchedule::getEffectiveEndDate, DateUtil.today()) .ne(ContractPaymentSchedule::getPaymentStatus,"2")); if (ArrayUtil.isNotEmpty(scheduleList.toArray())){ scheduleList.stream().forEach(contractPaymentSchedule -> { Contract contract = baseMapper.selectById(contractPaymentSchedule.getContractId()); //应收超期 PaymentConfirm overdueConfirm = new PaymentConfirm(); overdueConfirm.setBusinessType("应收超期"); overdueConfirm.setBusGuestId(contract.getPartyAId()); overdueConfirm.setBusGuestName(contract.getPartyA()); overdueConfirm.setContractId(contract.getId()); overdueConfirm.setContractName(contract.getContractName()); overdueConfirm.setContractNo(contract.getContractNo()); overdueConfirm.setConfirmTime(new Date()); overdueConfirm.setScheduleId(contractPaymentSchedule.getId()); overdueConfirm.setScheduleName(contractPaymentSchedule.getStageName()); PaymentConfirm newLastConfirm = paymentConfirmMapper.selectOne(Wrappers.lambdaQuery().eq(PaymentConfirm::getContractId,contract.getId()) .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); overdueConfirm.setTransationAmount(StrUtil.equals(contractPaymentSchedule.getPaymentStatus()+"","0")? contractPaymentSchedule.getPlannedAmount(): contractPaymentSchedule.getPlannedAmount().subtract(contractPaymentSchedule.getActualAmount())); overdueConfirm.setReceivableAmount(newLastConfirm.getTotalAmount().multiply(new BigDecimal("-1"))); overdueConfirm.setOverdueAmount(overdueConfirm.getTransationAmount()); overdueConfirm.setTotalAmount(newLastConfirm.getTotalAmount()); overdueConfirm.setCompId(contract.getCompId()); //判断当前阶段是否已生成上阶段应收超期 PaymentConfirm oiverdueConfirm = paymentConfirmMapper.selectOne(Wrappers.lambdaQuery().eq(PaymentConfirm::getScheduleId, contractPaymentSchedule.getId()) .eq(PaymentConfirm::getBusinessType, "应收超期")); if (ObjUtil.isNull(oiverdueConfirm)&&overdueConfirm.getTransationAmount().compareTo(new BigDecimal("0"))>0) { overdueConfirm.setCompId(contractPaymentSchedule.getCompId()); paymentConfirmMapper.insert(overdueConfirm); } //当前逾期 CurrentOverdue currentOverdue = new CurrentOverdue(); currentOverdue.setBusGuestId(contract.getPartyAId()); currentOverdue.setBusGuestName(contract.getPartyA()); currentOverdue.setContractId(contractPaymentSchedule.getContractId()); currentOverdue.setContractName(contractPaymentSchedule.getContractName()); currentOverdue.setScheduleId(contractPaymentSchedule.getId()); currentOverdue.setScheduleName(contractPaymentSchedule.getStageName()); currentOverdue.setCompId(contract.getCompId()); currentOverdue.setContractExpirTime(contractPaymentSchedule.getEffectiveEndDate()); currentOverdue.setReceivableAmount(StrUtil.equals(contractPaymentSchedule.getPaymentStatus()+"","0")? contractPaymentSchedule.getPlannedAmount():contractPaymentSchedule.getPlannedAmount().subtract(contractPaymentSchedule.getActualAmount())); currentOverdue.setOverdueDuration(BigDecimal.valueOf(DateUtil.betweenDay(contractPaymentSchedule.getEffectiveEndDate(),new Date(),true))); CurrentOverdue overdue = currentOverdueMapper.selectOne(Wrappers.lambdaQuery().eq(CurrentOverdue::getContractId,currentOverdue.getContractId()) .eq(CurrentOverdue::getScheduleId,currentOverdue.getScheduleId()).last("limit 1")); if (ObjUtil.isNull(overdue)){ currentOverdue.setCompId(contractPaymentSchedule.getCompId()); if (currentOverdue.getReceivableAmount().compareTo(new BigDecimal("0"))>0){ currentOverdueMapper.insert(currentOverdue); } }else { overdue.setOverdueDuration(BigDecimal.valueOf(DateUtil.betweenDay(contractPaymentSchedule.getEffectiveEndDate(),new Date(),true))); currentOverdueMapper.updateById(overdue); } }); } return R.ok(); } @Override public R refuseApproval(Long id) { Contract contract = baseMapper.selectById(id); contract.setContractStatus(0); baseMapper.updateById(contract); return R.ok(); } @Override public R copyNewContract(Long id) { Contract oldContract = baseMapper.selectById(id); Contract newContract = BeanUtil.copyProperties(oldContract,Contract.class,"id","createTime"); newContract.setContractNo(ContractNumberGenerator.generateContractNumber()); newContract.setPaidAmount(new BigDecimal("0")); newContract.setBillingStatus("0"); newContract.setErpPushFlag("0"); newContract.setContractStatus(0); List contracts; contracts = baseMapper.selectList(Wrappers.lambdaQuery().eq(Contract::getContractNo,newContract.getContractNo())); while (ArrayUtil.isNotEmpty(contracts.toArray())){ newContract.setContractNo(ContractNumberGenerator.generateContractNumber()); contracts = baseMapper.selectList(Wrappers.lambdaQuery().eq(Contract::getContractNo,newContract.getContractNo())); } baseMapper.insert(newContract); List subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.lambdaQuery().eq(ContractSubjectMatter::getContractId,id)); subjectMatterList.stream().forEach(contractSubjectMatter -> { ContractSubjectMatter subjectMatter = BeanUtil.copyProperties(contractSubjectMatter,ContractSubjectMatter.class,"id","createTime"); subjectMatter.setContractId(newContract.getId()); subjectMatter.setDeliveryStatus(0); subjectMatter.setDeliveredQuantity(new BigDecimal("0")); subjectMatter.setRemainingQuantity(new BigDecimal("0")); contractSubjectMatterMapper.insert(subjectMatter); }); List scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.lambdaQuery().eq(ContractPaymentSchedule::getContractId,id)); scheduleList.stream().forEach(contractPaymentSchedule -> { ContractPaymentSchedule schedule = BeanUtil.copyProperties(contractPaymentSchedule,ContractPaymentSchedule.class,"id","createTime"); schedule.setContractId(newContract.getId()); schedule.setPaymentStatus(0); schedule.setActualAmount(new BigDecimal("0")); schedule.setEffectiveDate(null); schedule.setEffectiveEndDate(null); contractPaymentScheduleMapper.insert(schedule); }); return R.ok(); } @Override public void exportContractYMJJGCLWord(Long id, HttpServletResponse response) { Contract contract = baseMapper.selectById(id); List subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.lambdaQuery() .eq(ContractSubjectMatter::getContractId,id).orderByAsc(ContractSubjectMatter::getCreateTime)); Map map = new HashMap<>(); //合同基本信息 map.put("partyA",contract.getPartyA()); map.put("partyB",contract.getPartyB()); map.put("contractNo",contract.getContractNo()); map.put("signPlace",contract.getSignPlace()); map.put("signDate",DateUtil.formatDate(contract.getSignDate())); map.put("signDateYMD",DateUtil.format(contract.getSignDate(), DatePattern.CHINESE_DATE_PATTERN)); map.put("total", contract.getAmount()); map.put("amountWords", Convert.digitToChinese(contract.getAmount())); //标的物 List> items = new ArrayList<>(); List dataList = new ArrayList<>(); AtomicReference no = new AtomicReference<>(0); subjectMatterList.stream().forEach(contractSubjectMatter -> { Map item = new HashMap<>(); item.put("no",no); item.put("materialName",contractSubjectMatter.getMaterialName()); item.put("guige",""); item.put("unit",""); item.put("quantity",contractSubjectMatter.getQuantity()); item.put("danzhong",""); item.put("zongzhong",""); item.put("unitPrice",contractSubjectMatter.getUnitPrice()); item.put("price",contractSubjectMatter.getTotalAmount()); items.add(item); no.updateAndGet(v -> v + 1); }); map.put("items",items); //定制方 BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId()); map.put("companyName",customer.getCompanyName()); map.put("legalPerson",customer.getLegalPerson()); map.put("contactPhone",customer.getContactPhone()); map.put("bankName",customer.getBankName()); map.put("bankAccount",customer.getBankAccount()); //承揽方 R r = remoteDeptService.getById(contract.getPartyBId()); SysDept dept = r.getData(); map.put("companyName",dept.getOrgName()); map.put("legalPerson1",StrUtil.isNotEmpty(dept.getLegalPerson())?dept.getLegalPerson():""); map.put("entrustedAgent",StrUtil.isNotEmpty(dept.getLegalPerson())?"":dept.getEntrustedAgent()); map.put("orgContact",dept.getOrgContact()); map.put("orgBank",dept.getOrgBank()); map.put("orgBankAccount",dept.getOrgBankAccount()); //生成文件名 Long time = new Date().getTime(); // 生成的word格式 String formatSuffix = ".docx"; // 拼接后的文件名 String fileName = time + formatSuffix;//文件名 带后缀 //导出word try { // 1. 加载模版 // 假设模版在 resources/templates/template.docx ClassPathResource resource = new ClassPathResource("template/ymjjgclht.docx"); // 配置列表策略 Configure config = Configure.builder() .bind("items", new LoopRowTableRenderPolicy()) // 将 items 绑定到行循环策略 .build(); // 2. 编译并渲染数据 XWPFTemplate xwpfTemplate = XWPFTemplate.compile(resource.getInputStream(),config).render(map); // 3. 设置响应头 response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".docx"); // 4. 写入输出流 OutputStream out = response.getOutputStream(); xwpfTemplate.write(out); out.flush(); out.close(); xwpfTemplate.close(); // 重要:关闭模版释放资源 }catch (IOException e) { e.printStackTrace(); } } }