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 cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.*; 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.ItemGeneratorUtil; import com.by4cloud.platformx.business.utils.NetworkFileToBase64; import com.by4cloud.platformx.business.vo.ContractDetailVo; import com.by4cloud.platformx.business.vo.ContractInvoiceVo; import com.by4cloud.platformx.business.vo.ContractSlipVo; import com.by4cloud.platformx.business.vo.FourAssociationPageVo; import com.by4cloud.platformx.common.core.util.R; import com.by4cloud.platformx.common.data.datascope.DataScope; 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 lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.OutputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; /** * @author cd * @description * @date 2026/4/29 14:07 **/ @Slf4j @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 MeterReadRecordMapper meterReadRecordMapper; private final ContractExecDateMapper contractExecDateMapper; private final RemoteFlowProcessService remoteFlowProcessService; private final ProductMapper productMapper; private final RemoteDeptService remoteDeptService; private final ContractDelayOutMapper contractDelayOutMapper; private final ErpRequestRecordMapper erpRequestRecordMapper; private final PaymentSlipMapper paymentSlipMapper; private final ContractInvoiceMapper contractInvoiceMapper; private final StringRedisTemplate redisTemplate; @Value("${erp.ymj}") private String ymjErp; @Value("${erp.smj}") private String smjErp; @Value("${erp.sgb}") private String sgbErp; @Value("${erp.jxc}") private String jxcErp; @Value("${erp.tfgs}") private String tfgsErp; @Value("${dept.smj}") private String smj; @Value("${dept.sgb}") private String sgb; @Value("${dept.jxc}") private String jxc; @Value("${dept.tfgs}") private String tfgs; @Value("${dept.ymj}") private String ymj; @Override public R add(ContractAddDTO addDTO) { Contract contract = BeanUtil.copyProperties(addDTO, Contract.class); contract.setPartyBId(SecurityUtils.getUser().getCompId()); contract.setPartyB(SecurityUtils.getUser().getCompName()); if (StrUtil.isEmpty(addDTO.getPartyA())){ BusinessCustomer bc = businessCustomerMapper.selectById(addDTO.getPartyAId()); if (ObjUtil.isNotNull(bc)){ contract.setPartyA(bc.getCompanyName()); } if (!StrUtil.equals(SecurityUtils.getUser().getCompId()+"",sgb)&&StrUtil.isEmpty(bc.getErpCompanyCode())){ return R.failed("请完善客户ERP编码"); } } contract.setPaidAmount(new BigDecimal("0")); contract.setBillingStatus("1"); contract.setBillingAmout(new BigDecimal("0")); contract.setErpPushFlag("0"); contract.setNickName(SecurityUtils.getUser().getNickname()); if (ObjUtil.isNotNull(addDTO.getDeliveryCycle())){ contract.setExpirationDate(DateUtil.offsetDay(addDTO.getSignDate(),addDTO.getDeliveryCycle())); } if (StrUtil.equals(addDTO.getContractCategory(), "water_house")){ if(!addDTO.getContractSubjectMatter().stream().allMatch(item->StrUtil.equals(item.getMaterialCode(), "water_bill")|| StrUtil.equals(item.getMaterialCode(), "house_rental")||StrUtil.equals(item.getMaterialCode(), "electricity_bill"))){ return R.failed("请新增水/电代缴房屋租赁合同!"); } }else { if(addDTO.getContractSubjectMatter().stream().anyMatch(item->StrUtil.equals(item.getMaterialCode(), "water_bill")|| StrUtil.equals(item.getMaterialCode(), "house_rental")||StrUtil.equals(item.getMaterialCode(), "electricity_bill"))){ return R.failed("水电代缴、房屋租赁产品只能在水/电代缴房屋租赁合同!"); } // 假设 list 是你的 List Optional maxDateObj = addDTO.getContractSubjectMatter().stream() .filter(item -> item.getPlannedDeliveryDate() != null) // 过滤掉日期为空的项,避免 NullPointerException .max(Comparator.comparing(ContractSubjectMatterAddDTO::getPlannedDeliveryDate)); if (maxDateObj.isPresent()) { contract.setExpirationDate(maxDateObj.get().getPlannedDeliveryDate()); } } if (ArrayUtil.isEmpty(addDTO.getContractSubjectMatter().toArray())){ return R.failed("标的物不能为空"); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",smj)){ contract.setContractNo(generateSMJContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",sgb)){ contract.setContractNo(generateGYBContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",ymj)){ contract.setContractNo(generateYMJContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",tfgs)){ contract.setContractNo(generateTFContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",jxc)){ contract.setContractNo(generateJXCContractNo()); } if (StrUtil.isNotEmpty(contract.getContractCategory())&&(StrUtil.equals(contract.getContractCategory(),"ymjjgcl") ||StrUtil.equals(contract.getContractCategory(),"ymjgypmm")||StrUtil.equals(contract.getContractCategory(),"ymjgkcpmm") ||StrUtil.equals(contract.getContractCategory(),"ymjcg")||StrUtil.equals(contract.getContractCategory(),"tfgsgypmm") ||StrUtil.equals(contract.getContractCategory(),"smjgypmm")||StrUtil.equals(contract.getContractCategory(),"jxcxsht")) ){ contract.setContractName(contract.getContractName()+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.setLineNo(ItemGeneratorUtil.nextId()); subjectMatter.setDeliveredQuantity(new BigDecimal("0")); subjectMatter.setDeliveryStatus(0); subjectMatter.setTotalAmount(contractSubjectMatterAddDTO.getQuantity().multiply(contractSubjectMatterAddDTO.getUnitPrice())); contractSubjectMatterMapper.insert(subjectMatter); //水电类必须有初次表号 if (StrUtil.isNotEmpty(contractSubjectMatterAddDTO.getMeterReadCode()) && ObjUtil.isNotNull(contractSubjectMatterAddDTO.getMeterReadNum())) { MeterReadRecord record = BeanUtil.copyProperties(contractSubjectMatterAddDTO, MeterReadRecord.class,"id"); record.setContractId(contract.getId()); record.setMatterId(subjectMatter.getId()); record.setContractName(contract.getContractName()); record.setBusGuestId(contract.getPartyAId()); record.setBusGuestName(contract.getPartyA()); record.setMeterReadTime(new Date()); meterReadRecordMapper.insert(record); } if (StrUtil.isNotEmpty(addDTO.getContractCategory()) && StrUtil.equals(addDTO.getContractCategory(), "ymjcg") &&ObjUtil.isNotNull(subjectMatter.getPlannedDeliveryDate())&&ObjUtil.isNotNull(contract.getExpirationDate()) &&DateUtil.compare(contract.getExpirationDate(),subjectMatter.getPlannedDeliveryDate())>0) { contract.setExpirationDate(subjectMatter.getPlannedDeliveryDate()); baseMapper.updateById(contract); } }); } 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.setEffectiveEndDate(DateUtil.offsetDay(contract.getSignDate(), contractPaymentScheduleAddDTO.getAgreedDays())); } if (ObjUtil.isNotNull(schedule.getEffectiveDate())) { if (schedule.getEffectiveDate().before(DateUtil.date())) { schedule.setFulfillmentStatus(1); } else { schedule.setFulfillmentStatus(0); } } if (contractPaymentScheduleAddDTO.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { schedule.setPaymentStatus(0); } else { schedule.setPaymentStatus(3); } 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); } if (contractPaymentScheduleAddDTO.getStageName().equals("质保金")) { contract.setWarrantyScheduleId(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("当前状态无法修改合同"); } if (StrUtil.isEmpty(updateDTO.getPartyA())){ BusinessCustomer bc = businessCustomerMapper.selectById(updateDTO.getPartyAId()); if (ObjUtil.isNotNull(bc)){ updateDTO.setPartyA(bc.getCompanyName()); } if (StrUtil.isEmpty(bc.getErpCompanyCode())||StrUtil.isEmpty(bc.getRegisterName())|| StrUtil.isEmpty(bc.getBankName())||StrUtil.isEmpty(bc.getBankAccount())){ return R.failed("请完善改客户数据后再添加合同"); } } Contract contract = BeanUtil.copyProperties(updateDTO, Contract.class); contract.setBillingStatus("1"); contract.setErpPushFlag("0"); contract.setPaidAmount(new BigDecimal("0")); contract.setBillingAmout(new BigDecimal("0")); contract.setNickName(SecurityUtils.getUser().getNickname()); if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",smj)){ contract.setContractNo(generateSMJContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",sgb)){ contract.setContractNo(generateGYBContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",ymj)){ contract.setContractNo(generateYMJContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",tfgs)){ contract.setContractNo(generateTFContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",jxc)){ contract.setContractNo(generateJXCContractNo()); } if (ObjUtil.isNotNull(updateDTO.getDeliveryCycle())){ contract.setExpirationDate(DateUtil.offsetDay(updateDTO.getSignDate(),updateDTO.getDeliveryCycle())); } if (StrUtil.equals(updateDTO.getContractCategory(), "water_house")){ if(!updateDTO.getContractSubjectMatter().stream().allMatch(item->StrUtil.equals(item.getMaterialCode(), "water_bill")|| StrUtil.equals(item.getMaterialCode(), "house_rental")||StrUtil.equals(item.getMaterialCode(), "electricity_bill"))){ return R.failed("请新增水/电代缴房屋租赁合同!"); } }else { if(updateDTO.getContractSubjectMatter().stream().anyMatch(item->StrUtil.equals(item.getMaterialCode(), " ")|| StrUtil.equals(item.getMaterialCode(), "house_rental")||StrUtil.equals(item.getMaterialCode(), "electricity_bill"))){ return R.failed("水电代缴、房屋租赁产品只能在水/电代缴房屋租赁合同!"); } // 假设 list 是你的 List // 假设 list 是你的 List Optional maxDateObj = updateDTO.getContractSubjectMatter().stream() .filter(item -> item.getPlannedDeliveryDate() != null) // 过滤掉日期为空的项,避免 NullPointerException .max(Comparator.comparing(ContractSubjectMatterAddDTO::getPlannedDeliveryDate)); if (maxDateObj.isPresent()) { contract.setExpirationDate(maxDateObj.get().getPlannedDeliveryDate()); } } 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.setLineNo(ItemGeneratorUtil.nextId()); subjectMatter.setDeliveredQuantity(new BigDecimal("0")); subjectMatter.setDeliveryStatus(0); subjectMatter.setTotalAmount(contractSubjectMatterAddDTO.getQuantity().multiply(contractSubjectMatterAddDTO.getUnitPrice())); contractSubjectMatterMapper.insert(subjectMatter); //水电类必须有初次表号 if (StrUtil.isNotEmpty(contractSubjectMatterAddDTO.getMeterReadCode()) && ObjUtil.isNotNull(contractSubjectMatterAddDTO.getMeterReadNum())) { meterReadRecordMapper.delete(Wrappers.lambdaQuery().eq(MeterReadRecord::getContractId, contract.getId())); MeterReadRecord record = BeanUtil.copyProperties(contractSubjectMatterAddDTO, MeterReadRecord.class,"id"); record.setContractId(contract.getId()); record.setMatterId(subjectMatter.getId()); record.setContractName(contract.getContractName()); record.setBusGuestId(contract.getPartyAId()); record.setBusGuestName(contract.getPartyA()); record.setMeterReadTime(new Date()); meterReadRecordMapper.insert(record); } }); } 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); if (contractPaymentScheduleAddDTO.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { schedule.setPaymentStatus(0); } else { schedule.setPaymentStatus(3); } 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); } if (contractPaymentScheduleAddDTO.getStageName().equals("质保金")) { contract.setWarrantyScheduleId(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); BusinessCustomer a = businessCustomerMapper.selectById(contract.getPartyAId()); if (ObjUtil.isNotNull(a)){ detailVo.setPartyAOrgCode(a.getCreditCode()); } 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); List subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.lambdaQuery() .eq(ContractSubjectMatter::getContractId,id)); if (StrUtil.isNotEmpty(contract.getContractCategory()) && StrUtil.equals(contract.getContractCategory(), "water_house")) { if (ArrayUtil.isNotEmpty(subjectMatterList.toArray())) { for (ContractSubjectMatter contractSubjectMatter: subjectMatterList) { if (StrUtil.equals(contract.getExecFrequency(), "1")) { Long weeksTrue = DateUtil.betweenWeek(DateUtil.beginOfWeek(contract.getEffectiveDate()), DateUtil.endOfWeek(contract.getExpirationDate()), true)+1; //循环日期 Date execDate0 = DateUtil.offsetDay(DateUtil.beginOfWeek(contract.getEffectiveDate()), contract.getExecDay()); for (int i = 0; i < weeksTrue.intValue(); i++) { Date execDatei = DateUtil.offsetWeek(execDate0, i); ContractExecDate execDate = new ContractExecDate(); execDate.setContractId(contract.getId()); execDate.setMatterId(contractSubjectMatter.getId()); execDate.setExecDate(execDatei); execDate.setGenFlag("0"); if (DateUtil.isIn(execDatei,contract.getEffectiveDate(),contract.getExpirationDate())) { contractExecDateMapper.insert(execDate); } } } if (StrUtil.equals(contract.getExecFrequency(), "2")) { Long weeksTrue = DateUtil.betweenMonth(DateUtil.beginOfMonth(contract.getEffectiveDate()), DateUtil.endOfMonth(contract.getExpirationDate()), true)+1; //循环日期 Date execDate0 = DateUtil.offsetDay(DateUtil.beginOfMonth(contract.getEffectiveDate()), contract.getExecDay()); for (int i = 0; i < weeksTrue.intValue(); i++) { Date execDatei = DateUtil.offsetMonth(execDate0, i); ContractExecDate execDate = new ContractExecDate(); execDate.setContractId(contract.getId()); execDate.setMatterId(contractSubjectMatter.getId()); execDate.setExecDate(execDatei); execDate.setGenFlag("0"); if (DateUtil.isIn(execDatei,contract.getEffectiveDate(),contract.getExpirationDate())) { contractExecDateMapper.insert(execDate); } } } if (StrUtil.equals(contract.getExecFrequency(), "3")) { Long weeksTrue = (DateUtil.betweenMonth(DateUtil.beginOfQuarter(contract.getEffectiveDate()), DateUtil.endOfQuarter(contract.getExpirationDate()), true)+1)/3; //循环日期 Date execDate0 = DateUtil.offsetDay(DateUtil.beginOfQuarter(contract.getEffectiveDate()), contract.getExecDay()); for (int i = 0; i < weeksTrue.intValue(); i++) { Date execDatei = DateUtil.offsetMonth(execDate0, i*3); ContractExecDate execDate = new ContractExecDate(); execDate.setContractId(contract.getId()); execDate.setMatterId(contractSubjectMatter.getId()); execDate.setExecDate(execDatei); execDate.setGenFlag("0"); if (DateUtil.isIn(execDatei,contract.getEffectiveDate(),contract.getExpirationDate())) { contractExecDateMapper.insert(execDate); } } } if (StrUtil.equals(contract.getExecFrequency(), "4")) { Date startDate = contract.getEffectiveDate(); Date endDate = contract.getExpirationDate(); Integer startMonth = DateUtil.month(contract.getEffectiveDate()); Integer endMonth = DateUtil.month(contract.getExpirationDate()); if (1<=startMonth&&startMonth<=6){ startDate = DateUtil.beginOfYear(startDate); } if (7<=startMonth&&startMonth<=12){ startDate = DateUtil.offsetMonth(DateUtil.beginOfYear(startDate),6); } if (1<=endMonth&&endMonth<=6){ endDate = DateUtil.offsetMonth(DateUtil.endOfYear(endDate),-6); } if (7<=endMonth&&endMonth<=12){ endDate = DateUtil.endOfYear(endDate); } Long weeksTrue = (DateUtil.betweenMonth(startDate,endDate, true)+1)/6; //循环日期 Date execDate0 = DateUtil.offsetDay(startDate, contract.getExecDay()); for (int i = 0; i < weeksTrue.intValue(); i++) { Date execDatei = DateUtil.offsetMonth(execDate0, i*6); ContractExecDate execDate = new ContractExecDate(); execDate.setContractId(contract.getId()); execDate.setMatterId(contractSubjectMatter.getId()); execDate.setExecDate(execDatei); execDate.setGenFlag("0"); if (DateUtil.isIn(execDatei,contract.getEffectiveDate(),contract.getExpirationDate())) { contractExecDateMapper.insert(execDate); } } } if (StrUtil.equals(contract.getExecFrequency(), "5")) { Long weeksTrue = DateUtil.betweenWeek(DateUtil.beginOfYear(contract.getEffectiveDate()), DateUtil.endOfYear(contract.getExpirationDate()), true)+1; //循环日期 Date execDate0 = DateUtil.offsetDay(DateUtil.beginOfYear(contract.getEffectiveDate()), contract.getExecDay()); for (int i = 0; i < weeksTrue.intValue(); i++) { Date execDatei = DateUtil.offsetWeek(execDate0, i); ContractExecDate execDate = new ContractExecDate(); execDate.setContractId(contract.getId()); execDate.setMatterId(contractSubjectMatter.getId()); execDate.setExecDate(execDatei); execDate.setGenFlag("0"); if (DateUtil.isIn(execDatei,contract.getEffectiveDate(),contract.getExpirationDate())) { contractExecDateMapper.insert(execDate); } } } } } } else { 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.setEffectiveEndDate(DateUtil.offsetDay(new Date(),endSchedule.getAgreedDays())); // contractPaymentScheduleMapper.updateById(endSchedule); //最后阶段应收 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.setEffectiveEndDate(DateUtil.offsetDay(contract.getSignDate(),fitstSchedule.getAgreedDays())); // contractPaymentScheduleMapper.updateById(fitstSchedule); //更新合同下个阶段 contract.setNextScheduleName(afterSchedule.get(0).getStageName()); baseMapper.updateById(contract); } //只有当前合同签字阶段 // if(ArrayUtil.isEmpty(afterSchedule.toArray())){ // fitstSchedule.setEffectiveEndDate(DateUtil.offsetDay(contract.getSignDate(),fitstSchedule.getAgreedDays())); // contractPaymentScheduleMapper.updateById(fitstSchedule); // } } //erp推送 new Thread(()->{ try { Thread.sleep(500); JSONObject request = new JSONObject(); BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId()); request.put("contractNo",contract.getContractNo()); request.put("partyA",contract.getPartyA()); request.put("partyACode",customer.getErpCompanyCode()); if (StrUtil.equals(contract.getPartyBId()+"",ymj)&&StrUtil.isNotEmpty(ymjErp)){ request.put("customerCode",customer.getErpCompanyCode()); request.put("currencyId","RMB"); request.put("signDate",DateUtil.format(contract.getSignDate(),DatePattern.NORM_DATETIME_PATTERN)); request.put("dateDeliver",DateUtil.format(contract.getExpirationDate(),DatePattern.NORM_DATETIME_PATTERN)); request.put("moneySum",contract.getAmount()); request.put("signManner","面签"); request.put("salesman",""); if (ArrayUtil.isNotEmpty(subjectMatterList.toArray())){ JSONArray subjectMatter = new JSONArray(); subjectMatterList.stream().forEach(contractSubjectMatter -> { JSONObject subjectMatterItem = new JSONObject(); subjectMatterItem.put("itemNo",contractSubjectMatter.getMaterialCode()); subjectMatterItem.put("salePrice",contractSubjectMatter.getUnitPrice()); subjectMatterItem.put("qtyRequired",contractSubjectMatter.getQuantity()); subjectMatterItem.put("money",contractSubjectMatter.getQuantity().multiply(contractSubjectMatter.getUnitPrice())); Product product = productMapper.selectOne(Wrappers.lambdaQuery().eq(Product::getCompId,contract.getCompId()) .eq(Product::getErpCode,contractSubjectMatter.getMaterialCode())); if (ObjUtil.isNotNull(product)){ subjectMatterItem.put("taxRate",new BigDecimal(product.getTaxRate()).divide(new BigDecimal("100"))); } subjectMatterItem.put("dateDeliver",ObjUtil.isNotNull(contractSubjectMatter.getPlannedDeliveryDate())? DateUtil.format(contractSubjectMatter.getPlannedDeliveryDate(),DatePattern.NORM_DATETIME_PATTERN): DateUtil.format(contract.getExpirationDate(),DatePattern.NORM_DATETIME_PATTERN)); subjectMatter.add(subjectMatterItem); }); request.put("details",subjectMatter); } JSONObject loginJson = new JSONObject(); loginJson.put("username","admin"); loginJson.put("password","admin123"); log.info("一煤机合同推送获取token入参:{}",loginJson.toJSONString()); String loginResp = HttpUtil.post(ymjErp+"/api/account/v1/login",loginJson.toJSONString()); log.info("一煤机合同推送获取token回参:{}",loginResp); JSONObject respJson = JSONObject.parseObject(loginResp); if (respJson.getInteger("code")==0){ JSONObject dataJson = JSONObject.parseObject(respJson.getString("data")); log.info("一煤机合同推送erp入参:{}",request.toJSONString()); HttpResponse response = HttpRequest.post(ymjErp+"/api/contract-staging/v1/receive") .header("token", dataJson.getString("token")) // 添加认证头 .header("Content-Type", "application/json") // 设置内容类型 .body(request.toJSONString()) // 设置请求体 .execute(); // 执行请求.post(ymjErp,request.toJSONString()); log.info("一煤机合同推送erp回参:{}",response.body()); //保存请求记录 saveErpRequestRecord("ymj",request.toJSONString(),response.body()); //更新合同erp推送标识 contract.setErpPushFlag("1"); baseMapper.updateById(contract); } } if (StrUtil.equals(contract.getPartyBId()+"",smj)&&StrUtil.isNotEmpty(smjErp)){ log.info("石煤机合同推送erp入参:{}",request.toJSONString()); String result = HttpUtil.post(smjErp,request.toJSONString()); log.info("石煤机合同推送erp回参:{}",result); //保存请求记录 saveErpRequestRecord("smj",request.toJSONString(),result); //更新合同erp推送标识 contract.setErpPushFlag("1"); baseMapper.updateById(contract); } if (StrUtil.equals(contract.getPartyBId()+"",jxc)&&StrUtil.isNotEmpty(jxcErp)){ log.info("机械厂合同推送erp入参:{}",request.toJSONString()); String result = HttpUtil.post(jxcErp,request.toJSONString()); log.info("机械厂合同推送erp回参:{}",result); //保存请求记录 saveErpRequestRecord("jxc",request.toJSONString(),result); //更新合同erp推送标识 contract.setErpPushFlag("1"); baseMapper.updateById(contract); } if (StrUtil.equals(contract.getPartyBId()+"",tfgs)&&StrUtil.isNotEmpty(tfgsErp)){ //通方公司通过系统录入 } if (StrUtil.equals(contract.getPartyBId()+"",sgb)&&StrUtil.isNotEmpty(sgbErp)){ //石工泵主动推送系统 } } catch (Exception e) { e.printStackTrace(); } }).start(); //合同中心推送 new Thread(()->{ try { JSONObject requestApply = new JSONObject(); requestApply.put("fd_selectionmethod","公开招标"); requestApply.put("fd_isrelated","是"); requestApply.put("fd_bizId",contract.getId()); requestApply.put("fd_remark",contract.getRemark()); requestApply.put("fd_MainContent",""); requestApply.put("fd_settlementType","00"); requestApply.put("fd_applyType","外销"); requestApply.put("fd_contractsubject ",subjectMatterList.stream().map(item->item.getMaterialName()).collect(Collectors.joining(","))); requestApply.put("fd_docNumber",contract.getContractNo()); requestApply.put("fd_templateId","19e39bb6c1edadbdb162c434274a8a18"); requestApply.put("fd_name",contract.getContractName()); requestApply.put("fd_signDate",DateUtil.formatDate(contract.getSignDate())); requestApply.put("fd_endDate",DateUtil.formatDate(contract.getExpirationDate())); requestApply.put("fd_contractCreater",contract.getNickName()); requestApply.put("fd_currency","人民币"); requestApply.put("fd_ContractAmount",contract.getAmount()); requestApply.put("fd_finAmount",contract.getAmount().divide(new BigDecimal("113"),2,RoundingMode.HALF_UP) .multiply(new BigDecimal("87"))); requestApply.put("fd_docStatus","20"); requestApply.put("fd_taxRates",13); requestApply.put("fd_customerName",contract.getPartyA()); requestApply.put("fd_systemSource","非煤销售系统"); requestApply.put("fd_type","00"); log.info("合同中心合同起草接口入参:{}",requestApply.toJSONString()); String respApply = HttpUtil.post("https://oatest.res.jzeg.cn/ekp/api/km-agreement/kmAgreementWebService/addSupplyContractApply",requestApply.toJSONString()); log.info("合同中心合同起草接口回参:{}",respApply); JSONObject applyResp = JSONObject.parseObject(respApply); if (applyResp.getString("code").equals("00")) { JSONObject request = new JSONObject(); request.put("fd_docNumber", contract.getContractNo()); request.put("fd_singer", contract.getNickName()); request.put("fd_signTime", DateUtil.formatDate(contract.getSignDate())); request.put("fd_linkPerson", ""); request.put("fd_linkPhone", ""); request.put("fd_address", contract.getSignPlace()); request.put("fd_receivedTime", DateUtil.format(contract.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN)); request.put("fd_receivedNum", 1); request.put("fd_effedate", DateUtil.formatDate(contract.getSignDate())); request.put("fd_enddate", DateUtil.formatDate(contract.getExpirationDate())); request.put("fd_reviewerNo", contract.getNickName()); request.put("fd_docStatus", "20"); request.put("fd_templateId", "19e39bb6c1edadbdb162c434274a8a18"); request.put("fd_attName", contract.getAttachmentName()); request.put("fd_attcontent", NetworkFileToBase64.convertNetworkFileToBase64("https://zbjt.res.jzeg.cn/api" + contract.getAttachmentUrl())); log.info("合同中心同步合同接口入参:{}", request.toJSONString()); String resp = HttpUtil.post("https://oatest.res.jzeg.cn/ekp/api/km-agreement/kmAgreementWebService/addContractReview", request.toJSONString()); log.info("合同中心同步合同接口回参:{}", resp); JSONObject respJson = JSONObject.parseObject(resp); if (respJson.getString("code").equals("00")) { contract.setCenterPushFlag("1"); baseMapper.updateById(contract); } } } catch (Exception e) { e.printStackTrace(); } }).start(); } private void saveErpRequestRecord(String ymj, String toJSONString, String result) { ErpRequestRecord record = new ErpRequestRecord(); record.setErpName(ymj); record.setRequestParams(toJSONString); record.setResponseParams(result); erpRequestRecordMapper.insert(record); } 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 (ObjUtil.isNotNull(contractLastConfirm)&&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 currentInSum = outAmountList.stream().reduce(BigDecimal.ZERO, BigDecimal::add); //新增当前合同 资金转入 PaymentConfirm inConfirm = BeanUtil.copyProperties(paymentConfirm, PaymentConfirm.class, "id", "transationAmount", "advanceAmount", "receivableAmount", "overdueAmount", "totalAmount"); inConfirm.setBusinessType("资金转入"); inConfirm.setConfirmTime(new Date()); inConfirm.setTransationAmount(currentInSum); inConfirm.setTotalAmount(paymentConfirm.getTotalAmount().add(currentInSum)); //更新当前阶段实际收款 和 收款状态 schedule.setActualAmount(inConfirm.getTransationAmount()); schedule.setPaymentStatus(2); 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"))); schedule.setActualAmount(currentInSum); schedule.setPaymentStatus(1); } paymentConfirmMapper.insert(inConfirm); //更新当前阶段实际收款 和 收款状态 contractPaymentScheduleMapper.updateById(schedule); } } else { paymentConfirmMapper.insert(paymentConfirm); } } @Override public R genCurrentOverdue() { List scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.lambdaQuery() .lt(ContractPaymentSchedule::getEffectiveEndDate, DateUtil.today()) .ne(ContractPaymentSchedule::getPaymentStatus, "2") .ne(ContractPaymentSchedule::getPaymentStatus, 3)); if (ArrayUtil.isNotEmpty(scheduleList.toArray())) { scheduleList.stream().forEach(contractPaymentSchedule -> { Contract contract = baseMapper.selectById(contractPaymentSchedule.getContractId()); if (ObjUtil.isNotNull(contract)) { //应收超期 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")); if (ObjUtil.isNotNull(newLastConfirm)) { 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) { 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)) { 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.setOutBoundAmout(new BigDecimal("0")); newContract.setPaidAmount(new BigDecimal("0")); newContract.setBillingStatus("1"); newContract.setErpPushFlag("0"); newContract.setContractStatus(0); newContract.setBillingAmout(new BigDecimal("0")); if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",smj)){ newContract.setContractNo(generateSMJContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",sgb)){ newContract.setContractNo(generateGYBContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",ymj)){ newContract.setContractNo(generateYMJContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",tfgs)){ newContract.setContractNo(generateTFContractNo()); } if (StrUtil.equals(SecurityUtils.getUser().getCompId()+"",jxc)){ newContract.setContractNo(generateJXCContractNo()); } 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", contractSubjectMatter.getSpecification()); item.put("unit", contractSubjectMatter.getUnit()); item.put("quantity", contractSubjectMatter.getQuantity()); item.put("danzhong", contractSubjectMatter.getSingleWight()); item.put("zongzhong", contractSubjectMatter.getTotalWight()); 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", contract.getPartyA()); 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/ymj/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(); } } @Override public R genCycleReceiced() { List execDateList = contractExecDateMapper.selectList(Wrappers.lambdaQuery() .le(ContractExecDate::getExecDate, DateUtil.today()).eq(ContractExecDate::getGenFlag,"0")); if (ArrayUtil.isNotEmpty(execDateList.toArray())) { execDateList.stream().forEach(contractExecDate -> { Contract contract = baseMapper.selectById(contractExecDate.getContractId()); ContractSubjectMatter subjectMatter = contractSubjectMatterMapper.selectOne(Wrappers.lambdaQuery() .eq(ContractSubjectMatter::getContractId, contractExecDate.getContractId()) .eq(ContractSubjectMatter::getId, contractExecDate.getMatterId())); //生成抄表单 if (StrUtil.isNotEmpty(subjectMatter.getMeterReadCode()) && ObjUtil.isNotNull(subjectMatter.getMeterReadNum())) { MeterReadRecord record = BeanUtil.copyProperties(subjectMatter, MeterReadRecord.class, "id","meterReadNum"); record.setContractName(contract.getContractName()); record.setMatterId(subjectMatter.getId()); record.setBusGuestId(contract.getPartyAId()); record.setBusGuestName(contract.getPartyA()); meterReadRecordMapper.insert(record); }else { //创建收款节点 //查询上次收款节点 ContractPaymentSchedule lastSchedule = contractPaymentScheduleMapper.selectOne(Wrappers.lambdaQuery() .eq(ContractPaymentSchedule::getContractId,contract.getId()) .orderByDesc(ContractPaymentSchedule::getCreateTime).last("limit 1")); ContractPaymentSchedule schedule = new ContractPaymentSchedule(); schedule.setStageName("房租租赁缴费"); schedule.setContractId(contract.getId()); schedule.setContractName(contract.getContractName()); schedule.setPlannedAmount(subjectMatter.getUnitPrice().multiply(subjectMatter.getQuantity())); schedule.setEffectiveEndDate(contractExecDate.getExecDate()); schedule.setStageOrder(1); if (ObjUtil.isNotNull(lastSchedule)){ schedule.setStageOrder(lastSchedule.getStageOrder()+1); } schedule.setPaymentStatus(0); schedule.setActualAmount(new BigDecimal("0")); schedule.setCompId(contract.getCompId()); schedule.setSubjectMatterCode(subjectMatter.getMaterialCode()); schedule.setSubjectMatterName(subjectMatter.getMaterialInternalName()); schedule.setRemark(DateUtil.formatDate(contractExecDate.getExecDate())+schedule.getStageName()); schedule.setInvoiceFlag("0"); contractPaymentScheduleMapper.insert(schedule); //房屋租赁生成应收 PaymentConfirm confirm = new PaymentConfirm(); confirm.setBusinessType("房屋租赁应收"); confirm.setBusGuestId(contract.getPartyAId()); confirm.setBusGuestName(contract.getPartyA()); confirm.setContractId(contract.getId()); confirm.setContractName(contract.getContractName()); confirm.setContractNo(contract.getContractNo()); confirm.setScheduleId(schedule.getId()); confirm.setScheduleName(schedule.getStageName()); confirm.setConfirmTime(contractExecDate.getExecDate()); confirm.setTransationAmount(subjectMatter.getUnitPrice().multiply(subjectMatter.getQuantity())); confirm.setTotalAmount(confirm.getTransationAmount().multiply(new BigDecimal("-1"))); PaymentConfirm lastConfirm = paymentConfirmMapper.selectOne(Wrappers.lambdaQuery().eq(PaymentConfirm::getContractId, contract.getId()) .orderByDesc(PaymentConfirm::getCreateTime).last("limit 1")); if (ObjUtil.isNotNull(lastConfirm)) { BigDecimal total = lastConfirm.getTotalAmount().add(confirm.getTotalAmount()); if (total.compareTo(new BigDecimal("0")) > 0) { confirm.setAdvanceAmount(total); confirm.setTotalAmount(total); } else if (total.compareTo(new BigDecimal("0")) == 0) { confirm.setTotalAmount(total); } else { confirm.setReceivableAmount(total.multiply(new BigDecimal("-1"))); confirm.setTotalAmount(total); } confirm.setCompId(contract.getCompId()); paymentConfirmMapper.insert(confirm); } else { confirm.setReceivableAmount(confirm.getTransationAmount()); confirm.setTotalAmount(confirm.getReceivableAmount().multiply(new BigDecimal("-1"))); confirm.setCompId(contract.getCompId()); paymentConfirmMapper.insert(confirm); } } contractExecDate.setGenFlag("1"); contractExecDateMapper.updateById(contractExecDate); }); } return R.ok(); } @Override public void exportContractYMJGYPMMWord(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", contractSubjectMatter.getSpecification()); item.put("unit", contractSubjectMatter.getUnit()); item.put("quantity", contractSubjectMatter.getQuantity()); item.put("danzhong", contractSubjectMatter.getSingleWight()); item.put("zongzhong", contractSubjectMatter.getTotalWight()); item.put("unitPrice", contractSubjectMatter.getUnitPrice()); item.put("price", contractSubjectMatter.getTotalAmount()); if (no.get().equals(Integer.valueOf(0))){ item.put("deliveryCycle",contract.getDeliveryCycle()); } items.add(item); no.updateAndGet(v -> v + 1); }); map.put("items", items); //定制方 BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId()); map.put("companyName", customer.getRegisterName()); 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("orgName", 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/ymj/ymjgypmmht.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(); } } @Override public void exportContractYMJGKCPMMWord(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())); map.put("deliveryCycle",contract.getDeliveryCycle()); //标的物 List> items = 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", contractSubjectMatter.getSpecification()); item.put("unit", contractSubjectMatter.getUnit()); item.put("quantity", contractSubjectMatter.getQuantity()); item.put("danzhong", contractSubjectMatter.getSingleWight()); item.put("zongzhong", contractSubjectMatter.getTotalWight()); 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.getRegisterName()); 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("orgName", 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/ymj/ymjgkcpmmht.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(); } } @Override public void exportContractYMJCGWord(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())); map.put("environment",contract.getEnvironment()); map.put("standard",contract.getStandard()); map.put("useMonth",contract.getUseMonth()); map.put("afterShipMonth",contract.getAfterShipMonth()); map.put("shipMethod",contract.getShipMethod()); map.put("shipAddress",contract.getShipAddress()); map.put("packaging",contract.getPackaging()); map.put("repairPeriod",contract.getRepairPeriod()); map.put("repairBreachAmount",contract.getRepairBreachAmount()); map.put("goodsShort",contract.getGoodsShort()); map.put("goodsShortBreachAmount",contract.getGoodsShortBreachAmount()); map.put("overdueBreachAmount",contract.getOverdueBreachAmount()); map.put("terminateContract",contract.getTerminateContract()); map.put("court",contract.getCourt()); map.put("contractAttchment",contract.getContractAttchment()); map.put("invoiceNotice",contract.getInvoiceNotice()); map.put("city",contract.getCity()); map.put("region",contract.getRegion()); //标的物 List> items = new ArrayList<>(); AtomicReference no = new AtomicReference<>(0); subjectMatterList.stream().forEach(contractSubjectMatter -> { Product product = productMapper.selectOne(Wrappers.lambdaQuery().eq(Product::getErpCode,contractSubjectMatter.getMaterialCode()).last("limit 1")); Map item = new HashMap<>(); item.put("no", no); item.put("materialName", contractSubjectMatter.getMaterialName()); item.put("guige", contractSubjectMatter.getSpecification()); item.put("unit", contractSubjectMatter.getUnit()); item.put("quantity", contractSubjectMatter.getQuantity()); item.put("unitPrice", contractSubjectMatter.getUnitPrice()); item.put("priceTax", contractSubjectMatter.getUnitPrice().multiply(contractSubjectMatter.getQuantity()).setScale(2, RoundingMode.HALF_UP)); item.put("priceNoTax", contractSubjectMatter.getUnitPrice().multiply(contractSubjectMatter.getQuantity()) .subtract(contractSubjectMatter.getUnitPrice().multiply(contractSubjectMatter.getQuantity()) .divide(new BigDecimal("100").add(new BigDecimal(product.getTaxRate())),2, RoundingMode.HALF_UP).multiply(new BigDecimal(product.getTaxRate()))) .setScale(2, RoundingMode.HALF_UP)); item.put("deliveryDate", DateUtil.formatDate(contractSubjectMatter.getPlannedDeliveryDate())); item.put("remarks", contractSubjectMatter.getRemarks()); map.put("taxRate",product.getTaxRate()); items.add(item); no.updateAndGet(v -> v + 1); }); //付款 List scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.lambdaQuery() .eq(ContractPaymentSchedule::getContractId, id).orderByAsc(ContractPaymentSchedule::getCreateTime)); scheduleList.stream().forEach(contractPaymentSchedule -> { if (contractPaymentSchedule.getStageName().equals("合同签订")){ map.put("htqdbl",contractPaymentSchedule.getPaymentRatio()); map.put("htqdje",contractPaymentSchedule.getPlannedAmount()); map.put("htqdjr",contractPaymentSchedule.getAgreedDays()); } if (contractPaymentSchedule.getStageName().equals("发货前")){ map.put("fhqbl",contractPaymentSchedule.getPaymentRatio()); map.put("fhqje",contractPaymentSchedule.getPlannedAmount()); } if (contractPaymentSchedule.getStageName().equals("调试完成或验收")){ map.put("ysbl",contractPaymentSchedule.getPaymentRatio()); map.put("ysje",contractPaymentSchedule.getPlannedAmount()); map.put("ysjr",contractPaymentSchedule.getAgreedDays()); } if (contractPaymentSchedule.getStageName().equals("质保金")){ map.put("zbjbl",contractPaymentSchedule.getPaymentRatio()); map.put("zbjje",contractPaymentSchedule.getPlannedAmount()); map.put("zbjjr",contractPaymentSchedule.getAgreedDays()); } }); map.put("items", items); //定制方 BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId()); map.put("companyName", customer.getRegisterName()); 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("orgName", 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/ymj/ymjcght.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(); } } @Override public R delayOutApproval(DelayOutApprovalDTO dto) { Contract contract = baseMapper.selectById(dto.getContractId()); ContractDelayOut delayOut = BeanUtil.copyProperties(dto,ContractDelayOut.class); delayOut.setApplyTime(new Date()); delayOut.setApplyName(SecurityUtils.getUser().getUsername()); delayOut.setDelayStatus("0"); Map map = new HashMap<>(); map.put("contractId",contract.getId()); map.put("contractName",contract.getContractName()); map.put("partyA",contract.getPartyA()); map.put("partyB",contract.getPartyB()); map.put("delayDay",dto.getDelayDay()); map.put("contractNo",contract.getContractNo()); map.put("applyName",SecurityUtils.getUser().getUsername()); map.put("applyTime",DateUtil.format(delayOut.getApplyTime(),DatePattern.NORM_DATETIME_FORMAT)); //启动流程 ProcessInstanceParamDto paramDto = new ProcessInstanceParamDto(); paramDto.setParamMap(map); paramDto.setFlowName(FlowNameEnum.延期出货审批.name()); R r1 = remoteFlowProcessService.startProcessInstance(paramDto); if (r1.getCode() == 1) { return R.failed("流程启动失败"); } contractDelayOutMapper.insert(delayOut); return R.ok(); } @Override public Page pageScope(Page page, ContracQueryDTO queryDTO) { return baseMapper.pageScope(page,queryDTO, DataScope.of("comp_id")); } @Override public void exportContractTFGSGYPMMWord(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("materialName", contractSubjectMatter.getMaterialName()); item.put("guige", contractSubjectMatter.getSpecification()); item.put("unit", contractSubjectMatter.getUnit()); item.put("quantity", contractSubjectMatter.getQuantity()); 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.getRegisterName()); 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("orgName", 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/tfgs/tfgsgypmmht.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(); } } @Override public R addContractSgb(ContractAddDTO addDTO) { if (ArrayUtil.isEmpty(addDTO.getContractSubjectMatter().toArray())){ return R.failed("请添加标的物"); } if (ArrayUtil.isEmpty(addDTO.getContractPaymentSchedule().toArray())){ return R.failed("请添加付款阶段或付款阶段缺少"); } if (!isValidPaymentStages(addDTO.getContractPaymentSchedule())){ return R.failed("付款阶段信息异常"); } if (addDTO.getContractPaymentSchedule().stream().map(item->item.getPaymentRatio()).reduce(BigDecimal.ZERO,BigDecimal::add) .compareTo(new BigDecimal("100.00"))!=0){ return R.failed("付款阶段比例异常"); } Contract contract = BeanUtil.copyProperties(addDTO, Contract.class); contract.setErpContractNo(contract.getContractNo()); contract.setPartyBId(SecurityUtils.getUser().getCompId()); contract.setPartyB(SecurityUtils.getUser().getCompName()); contract.setContractStatus(2); contract.setPaidAmount(new BigDecimal("0")); contract.setBillingStatus("1"); contract.setErpPushFlag("1"); contract.setBillingAmout(new BigDecimal("0")); BusinessCustomer bc = businessCustomerMapper.selectOne(Wrappers.lambdaQuery().eq(BusinessCustomer::getErpCompanyCode, addDTO.getPartyACode()).last("limit 1")); if (ObjUtil.isNull(bc)){ return R.failed("erp客户编码不存在"); } contract.setPartyAId(bc.getId()); contract.setPartyA(bc.getCompanyName()); if (ObjUtil.isNotNull(addDTO.getDeliveryCycle())){ contract.setExpirationDate(DateUtil.offsetDay(addDTO.getSignDate(),addDTO.getDeliveryCycle())); } contract.setContractNo(generateGYBContractNo()); if (!StrUtil.equals(addDTO.getContractCategory(), "water_house")){ // 假设 list 是你的 List Optional maxDateObj = addDTO.getContractSubjectMatter().stream() .filter(item -> item.getPlannedDeliveryDate() != null) // 过滤掉日期为空的项,避免 NullPointerException .max(Comparator.comparing(ContractSubjectMatterAddDTO::getPlannedDeliveryDate)); if (maxDateObj.isPresent()) { contract.setExpirationDate(maxDateObj.get().getPlannedDeliveryDate()); } } 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.setDeliveredQuantity(new BigDecimal("0")); subjectMatter.setDeliveryStatus(0); subjectMatter.setTotalAmount(contractSubjectMatterAddDTO.getQuantity().multiply(contractSubjectMatterAddDTO.getUnitPrice())); contractSubjectMatterMapper.insert(subjectMatter); //水电类必须有初次表号 if (StrUtil.isNotEmpty(contractSubjectMatterAddDTO.getMeterReadCode()) && ObjUtil.isNotNull(contractSubjectMatterAddDTO.getMeterReadNum())) { MeterReadRecord record = BeanUtil.copyProperties(contractSubjectMatterAddDTO, MeterReadRecord.class,"id"); record.setContractId(contract.getId()); record.setMatterId(subjectMatter.getId()); record.setContractName(contract.getContractName()); record.setBusGuestId(contract.getPartyAId()); record.setBusGuestName(contract.getPartyA()); record.setMeterReadTime(new Date()); meterReadRecordMapper.insert(record); } if (StrUtil.isNotEmpty(addDTO.getContractCategory()) && StrUtil.equals(addDTO.getContractCategory(), "ymjcg") &&ObjUtil.isNotNull(subjectMatter.getPlannedDeliveryDate())&&ObjUtil.isNotNull(contract.getExpirationDate()) &&DateUtil.compare(contract.getExpirationDate(),subjectMatter.getPlannedDeliveryDate())>0) { contract.setExpirationDate(subjectMatter.getPlannedDeliveryDate()); baseMapper.updateById(contract); } }); } 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.setEffectiveEndDate(DateUtil.offsetDay(contract.getSignDate(), contractPaymentScheduleAddDTO.getAgreedDays())); } if (ObjUtil.isNotNull(schedule.getEffectiveDate())) { if (schedule.getEffectiveDate().before(DateUtil.date())) { schedule.setFulfillmentStatus(1); } else { schedule.setFulfillmentStatus(0); } } if (contractPaymentScheduleAddDTO.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { schedule.setPaymentStatus(0); } else { schedule.setPaymentStatus(3); } 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(contract.getContractNo()); } @Override public R updateContractSgb(ContractUpdateDTO updateDTO) { if (ArrayUtil.isEmpty(updateDTO.getContractSubjectMatter().toArray())){ return R.failed("请添加标的物"); } if (ArrayUtil.isEmpty(updateDTO.getContractPaymentSchedule().toArray())){ return R.failed("请添加付款阶段或付款阶段缺少"); } if (!isValidPaymentStages(updateDTO.getContractPaymentSchedule())){ return R.failed("付款阶段信息异常"); } if (updateDTO.getContractPaymentSchedule().stream().map(item->item.getPaymentRatio()).reduce(BigDecimal.ZERO,BigDecimal::add) .compareTo(new BigDecimal("100.00"))!=0){ return R.failed("付款阶段比例异常"); } Contract contractOld = baseMapper.selectOne(Wrappers.lambdaQuery().eq(Contract::getDataId,updateDTO.getDataId()).last("limit 1")); if (ObjUtil.isNull(contractOld)){ return R.failed("合同数据ID:{}不存在,请先新增后再修改",updateDTO.getDataId()); } Contract contract = BeanUtil.copyProperties(updateDTO, Contract.class); contract.setId(contractOld.getId()); if (ObjUtil.isNotNull(updateDTO.getDeliveryCycle())){ contract.setExpirationDate(DateUtil.offsetDay(updateDTO.getSignDate(),updateDTO.getDeliveryCycle())); } if (!StrUtil.equals(updateDTO.getContractCategory(), "water_house")){ // 假设 list 是你的 List Optional maxDateObj = updateDTO.getContractSubjectMatter().stream() .filter(item -> item.getPlannedDeliveryDate() != null) // 过滤掉日期为空的项,避免 NullPointerException .max(Comparator.comparing(ContractSubjectMatterAddDTO::getPlannedDeliveryDate)); if (maxDateObj.isPresent()) { contract.setExpirationDate(maxDateObj.get().getPlannedDeliveryDate()); } } 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.setDeliveredQuantity(new BigDecimal("0")); subjectMatter.setDeliveryStatus(0); contractSubjectMatterMapper.insert(subjectMatter); //水电类必须有初次表号 if (StrUtil.isNotEmpty(contractSubjectMatterAddDTO.getMeterReadCode()) && ObjUtil.isNotNull(contractSubjectMatterAddDTO.getMeterReadNum())) { meterReadRecordMapper.delete(Wrappers.lambdaQuery().eq(MeterReadRecord::getContractId, contract.getId())); MeterReadRecord record = BeanUtil.copyProperties(contractSubjectMatterAddDTO, MeterReadRecord.class,"id"); record.setContractId(contract.getId()); record.setMatterId(subjectMatter.getId()); record.setContractName(contract.getContractName()); record.setBusGuestId(contract.getPartyAId()); record.setBusGuestName(contract.getPartyA()); record.setMeterReadTime(new Date()); meterReadRecordMapper.insert(record); } }); } 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); if (contractPaymentScheduleAddDTO.getPaymentRatio().compareTo(new BigDecimal("0")) > 0) { schedule.setPaymentStatus(0); } else { schedule.setPaymentStatus(3); } 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(); } // 定义标准的五个阶段 private static final Set VALID_STAGES = new HashSet<>(Arrays.asList( "合同签订", "发货前", "货到签收", "调试完成或验收", "质保金" )); /** * 判断付款阶段列表是否符合标准 * @param scheduleList 付款阶段列表 * @return true 如果包含且仅包含标准的五个阶段,false 否则 */ public static boolean isValidPaymentStages(List scheduleList) { if (scheduleList == null || scheduleList.isEmpty()) { return false; } // 1. 提取所有非空的 stageName List actualStages = scheduleList.stream() .map(ContractPaymentScheduleAddDTO::getStageName) .filter(stage -> stage != null && !stage.trim().isEmpty()) .map(String::trim) .collect(Collectors.toList()); // 2. 基本数量检查:必须正好是5个 if (actualStages.size() != VALID_STAGES.size()) { return false; } // 3. 内容检查:所有实际阶段都必须在标准集合中 // 使用 Set 去重后比较,防止列表中有重复阶段但总数凑够5个的情况 Set actualStageSet = new HashSet<>(actualStages); // 检查实际集合大小是否也为5(确保无重复)且包含于标准集合 return VALID_STAGES.equals(actualStageSet); } /** * 生成格式为: yyyyMMdd + 4位序列号 (例如: 20260629000001) */ public String generateSMJContractNo() { // 1. 获取当前日期字符串 String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 String key = "ZB-SMJ:" + dateStr; // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) Long sequence = redisTemplate.opsForValue().increment(key, 1); redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); // 4. 格式化序列号,不足6位前补0 String seqStr = String.format("%04d", sequence); // 5. 拼接返回 return "ZB-SMJ-"+dateStr + seqStr; } public String generateYMJContractNo() { // 1. 获取当前日期字符串 String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 String key = "ZB-YMJ:" + dateStr; // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) Long sequence = redisTemplate.opsForValue().increment(key, 1); redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); // 4. 格式化序列号,不足6位前补0 String seqStr = String.format("%04d", sequence); // 5. 拼接返回 return "ZB-YMJ-"+dateStr + seqStr; } public String generateJXCContractNo() { // 1. 获取当前日期字符串 String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 String key = "ZB-JXC:" + dateStr; // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) Long sequence = redisTemplate.opsForValue().increment(key, 1); redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); // 4. 格式化序列号,不足6位前补0 String seqStr = String.format("%04d", sequence); // 5. 拼接返回 return "ZB-JXC-"+dateStr + seqStr; } public String generateTFContractNo() { // 1. 获取当前日期字符串 String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 String key = "ZB-TF:" + dateStr; // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) Long sequence = redisTemplate.opsForValue().increment(key, 1); redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); // 4. 格式化序列号,不足6位前补0 String seqStr = String.format("%04d", sequence); // 5. 拼接返回 return "ZB-TF-"+dateStr + seqStr; } public String generateGYBContractNo() { // 1. 获取当前日期字符串 String dateStr = DateUtil.format(new Date(), "yyyyMMdd"); // 2. 构建 Redis Key,按天隔离,例如: order:no:20260629 String key = "ZB-GYB:" + dateStr; // 3. Redis 原子递增,设置过期时间为2天(防止Key堆积,同时覆盖跨天边界情况) Long sequence = redisTemplate.opsForValue().increment(key, 1); redisTemplate.expire(key, 1, java.util.concurrent.TimeUnit.DAYS); // 4. 格式化序列号,不足6位前补0 String seqStr = String.format("%04d", sequence); // 5. 拼接返回 return "ZB-GYB-"+dateStr + seqStr; } @Override public R abortContractSgb(String dataId) { Contract contractOld = baseMapper.selectOne(Wrappers.lambdaQuery().eq(Contract::getDataId,dataId).last("limit 1")); if (ObjUtil.isNull(contractOld)){ return R.failed("合同数据ID:{}不存在,请先新增后再操作",dataId); } contractOld.setContractStatus(4); baseMapper.updateById(contractOld); return R.ok(); } @Override public R delContractSgb(String dataId) { Contract contractOld = baseMapper.selectOne(Wrappers.lambdaQuery().eq(Contract::getDataId,dataId).last("limit 1")); if (ObjUtil.isNull(contractOld)){ return R.failed("合同数据ID:{}不存在,请先新增后再操作",dataId); } contractPaymentScheduleMapper.delete(Wrappers.lambdaQuery().eq(ContractPaymentSchedule::getContractId,contractOld.getId())); contractSubjectMatterMapper.delete(Wrappers.lambdaQuery().eq(ContractSubjectMatter::getContractId,contractOld.getId())); paymentConfirmMapper.delete(Wrappers.lambdaQuery().eq(PaymentConfirm::getContractId,contractOld.getId())); baseMapper.deleteById(contractOld); return R.ok(); } @Override public Page fourAssociation(Page page,ContractQueryDTO queryDTO) { Page page1 = baseMapper.fourAssociation(page,queryDTO,DataScope.of("comp_id")); if (ArrayUtil.isNotEmpty(page1.getRecords().toArray())){ page1.getRecords().stream().forEach(fourAssociationPageVo -> { List slips = paymentSlipMapper.selectList(Wrappers.lambdaQuery().eq(PaymentSlip::getContractId,fourAssociationPageVo.getId()) .orderByAsc(PaymentSlip::getPaymentTime)); if (ArrayUtil.isNotEmpty(slips.toArray())){ fourAssociationPageVo.setSlipVoList(BeanUtil.copyToList(slips,ContractSlipVo.class)); } List invoices = contractInvoiceMapper.selectList(Wrappers.lambdaQuery().eq(ContractInvoice::getContractId,fourAssociationPageVo.getId()) .orderByAsc(ContractInvoice::getInvoiceTime)); if (ArrayUtil.isNotEmpty(invoices.toArray())){ fourAssociationPageVo.setInvoiceVoList(BeanUtil.copyToList(invoices, ContractInvoiceVo.class)); } if (fourAssociationPageVo.getAmount().compareTo(fourAssociationPageVo.getPaidAmount())==0&& fourAssociationPageVo.getAmount().compareTo(fourAssociationPageVo.getBillingAmout())==0){ fourAssociationPageVo.setAssociation("已完成"); } }); } return page1; } @Override public void exportContractSMJGYPMMWord(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("totalNoTax", contract.getAmount().divide(new BigDecimal("100").add(new BigDecimal("13")), 2, RoundingMode.HALF_UP) .multiply(new BigDecimal("87"))); map.put("amountWords", Convert.digitToChinese(contract.getAmount())); //标的物 List> items = new ArrayList<>(); subjectMatterList.stream().forEach(contractSubjectMatter -> { Map item = new HashMap<>(); item.put("materialName", contractSubjectMatter.getMaterialName()); item.put("guige", contractSubjectMatter.getSpecification()); item.put("unit", contractSubjectMatter.getUnit()); item.put("quantity", contractSubjectMatter.getQuantity()); item.put("unitPrice", contractSubjectMatter.getUnitPrice()); item.put("price", contractSubjectMatter.getTotalAmount()); item.put("remarks", contractSubjectMatter.getRemarks()); items.add(item); }); map.put("items", items); //定制方 BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId()); map.put("companyName", customer.getRegisterName()); 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("orgName", 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/smj/smjgypmmht.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(); } } @Override public void exportContractJXCXSWord(Long id, HttpServletResponse response) { Contract contract = baseMapper.selectById(id); List subjectMatterList = contractSubjectMatterMapper.selectList(Wrappers.lambdaQuery() .eq(ContractSubjectMatter::getContractId, id).orderByAsc(ContractSubjectMatter::getCreateTime)); List scheduleList = contractPaymentScheduleMapper.selectList(Wrappers.lambdaQuery() .eq(ContractPaymentSchedule::getContractId, id).orderByAsc(ContractPaymentSchedule::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())); //正文 map.put("standard", contract.getStandard()); map.put("useMonth", contract.getUseMonth()); map.put("afterShipMonth", contract.getAfterShipMonth()); map.put("deliveryCycle", contract.getDeliveryCycle()); map.put("advancePayment", contract.getAdvancePayment()+"%"); map.put("inspectDay", contract.getInspectDay()); map.put("acceptDay", contract.getAcceptDay()); map.put("delayAcceptDay", contract.getDelayAcceptDay()); map.put("acceptPassDay", contract.getAcceptPassDay()); map.put("acceptPassAmount", contract.getAcceptPassAmount()+"%"); map.put("deliverDay", contract.getDeliverDay()); map.put("deliverCompleteDay", contract.getDeliverCompleteDay()); map.put("shipAddress", contract.getShipAddress()); map.put("htqdr", scheduleList.get(0).getAgreedDays()); map.put("htqdq", scheduleList.get(0).getPaymentRatio()+"%"); map.put("fhqq", scheduleList.get(1).getPaymentRatio()+"%"); map.put("dhhr", scheduleList.get(2).getAgreedDays()); map.put("dhhq", scheduleList.get(2).getPaymentRatio()+"%"); map.put("zbjq", scheduleList.get(4).getPaymentRatio()+"%"); map.put("zbqm", scheduleList.get(4).getAgreedDays()); map.put("paymentMethod", contract.getPaymentMethod()); map.put("invoiceNotice", contract.getInvoiceNotice()); map.put("supplierAgent", contract.getSupplierAgent()); map.put("supplierAgentIDCard", contract.getSupplierAgentIdCard()); map.put("buyerAgent", contract.getBuyerAgent()); map.put("buyerAgentIDCard", contract.getBuyerAgentIdCard()); map.put("agentAuthority", contract.getAgentAuthority()); map.put("delayPayAdvancePayment", contract.getDelayPayAdvancePayment()+"%"); map.put("delayPayAProcessPayment", contract.getDelayPayProcessPayment()+"%"); map.put("receiveAdvancePaymentMonth", contract.getReceiveAdvancePaymentMonth()); map.put("noticeSupplierAcceptDay", contract.getNoticeSupplierAcceptDay()); map.put("overdueDay", contract.getOverdueDay()); map.put("lossAmount", contract.getLossAmount()+"%"); map.put("liquidatedDamagesHighSupplier", contract.getLiquidatedDamagesHighSupplier()+"%"); map.put("overdueDayXf", contract.getOverdueDayXf()); map.put("lossAmountXf", contract.getLossAmountXf()+"%"); map.put("liquidatedDamagesHighBuyer", contract.getLiquidatedDamagesHighBuyer()+"%"); map.put("contractAttchment", contract.getContractAttchment()); map.put("totalParts", contract.getTotalParts()); map.put("supplierPart", contract.getSupplierPart()); map.put("buyerPart", contract.getBuyerPart()); //标的物 List> items = new ArrayList<>(); subjectMatterList.stream().forEach(contractSubjectMatter -> { Map item = new HashMap<>(); item.put("materialName", contractSubjectMatter.getMaterialName()); item.put("guige", contractSubjectMatter.getSpecification()); item.put("unit", contractSubjectMatter.getUnit()); item.put("quantity", contractSubjectMatter.getQuantity()); item.put("unitPrice", contractSubjectMatter.getUnitPrice()); item.put("price", contractSubjectMatter.getTotalAmount()); item.put("remarks", contractSubjectMatter.getRemarks()); items.add(item); }); map.put("items", items); //定制方 BusinessCustomer customer = businessCustomerMapper.selectById(contract.getPartyAId()); map.put("companyName", customer.getRegisterName()); 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("orgName", 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/jxc/jxcxsht.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(); } } }