龙伟 vor 1 Jahr
Ursprung
Commit
57ca6c2eca

+ 32 - 0
summary/pom.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.ruoyi</groupId>
+        <artifactId>Visible</artifactId>
+        <version>3.8.6</version>
+    </parent>
+
+    <artifactId>summary</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>base</artifactId>
+            <version>3.8.6</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 33 - 0
summary/src/main/java/com/ruoyi/projetctCost/ThreadPool/SingletonThreadPool.java

@@ -0,0 +1,33 @@
+package com.ruoyi.projetctCost.ThreadPool;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+public class SingletonThreadPool {
+    private static volatile SingletonThreadPool instance;
+    private final ThreadPoolExecutor executor;
+    private SingletonThreadPool() {
+        // 私有构造方法
+        int corePoolSize = 10; // 核心线程池大小
+        int maxPoolSize = 20; // 最大线程池大小
+        long keepAliveTime = 60L; // 线程空闲时间
+        TimeUnit unit = TimeUnit.SECONDS; // 线程空闲时间单位
+        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(100); // 任务队列
+        executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue);
+    }
+    public static SingletonThreadPool getInstance() {
+        if (instance == null) {
+            synchronized (SingletonThreadPool.class) {
+                if (instance == null) {
+                    instance = new SingletonThreadPool();
+                }
+            }
+        }
+        return instance;
+    }
+    public ThreadPoolExecutor getExecutor() {
+        return executor;
+    }
+}

+ 116 - 0
summary/src/main/java/com/ruoyi/projetctCost/beenfactory/ServiceBeenFactory.java

@@ -0,0 +1,116 @@
+package com.ruoyi.projetctCost.beenfactory;
+
+
+import com.ruoyi.contractInfo.service.IComContractInfoExchangeService;
+import com.ruoyi.depart.service.ISysDepartService;
+import com.ruoyi.financeBudget.service.IFinanceBudgetService;
+import com.ruoyi.kyBg.service.IKyBgInfoService;
+import com.ruoyi.kyTask.service.IKyTaskInfoService;
+import com.ruoyi.mesInfo.service.IMesInfoService;
+import com.ruoyi.projectChbSwf.service.IKzksProjectChbSwfService;
+import com.ruoyi.projectChbWxf.service.IKzksProjectChbWxfService;
+import com.ruoyi.projectChbZyf.service.IKzksProjectChbZyfService;
+import com.ruoyi.projectCost.service.IProjectCostService;
+import com.ruoyi.wzCk.ckDetail.service.IWzOutboundOrderBService;
+import com.ruoyi.wzCk.ckInfo.service.IWzOutboundOrderHService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ServiceBeenFactory {
+
+    /*科研任务service*/
+    @Autowired
+    private IKyTaskInfoService taskInfoService;
+
+    /*科研报工service*/
+    @Autowired
+    private IKyBgInfoService KyBgInfoService;
+
+    @Autowired
+    private IFinanceBudgetService financeBudgetService;
+
+    /*合同宽表service*/
+    @Autowired
+    private IComContractInfoExchangeService comContractInfoExchangeService;
+
+    /*物资出库明细service*/
+    @Autowired
+    private IWzOutboundOrderBService wzOutboundOrderBService;
+
+    /*物资出库单service*/
+    @Autowired
+    private IWzOutboundOrderHService wzOutboundOrderHService;
+
+    /*事务费service*/
+    @Autowired
+    private IKzksProjectChbSwfService projectChbSwfService;
+
+    /*外协费service*/
+    @Autowired
+    private IKzksProjectChbWxfService projectChbWxfService;
+
+    /*专用费service*/
+    @Autowired
+    private IKzksProjectChbZyfService projectChbZyfService;
+
+    /*组织部门service*/
+    @Autowired
+    private ISysDepartService departService;
+
+    /*mes装机信息卡service*/
+    @Autowired
+    private IMesInfoService mesInfoService;
+
+    /*项目成本service*/
+    @Autowired
+    private IProjectCostService projectCostService;
+
+    public IMesInfoService getMesInfoService() {
+        return mesInfoService;
+    }
+
+    public IProjectCostService getProjectCostService() {
+        return projectCostService;
+    }
+
+    public ISysDepartService getDepartService() {
+        return departService;
+    }
+
+    public IKzksProjectChbSwfService getProjectChbSwfService() {
+        return projectChbSwfService;
+    }
+
+    public IKzksProjectChbWxfService getProjectChbWxfService() {
+        return projectChbWxfService;
+    }
+
+    public IKzksProjectChbZyfService getProjectChbZyfService() {
+        return projectChbZyfService;
+    }
+
+    public IWzOutboundOrderBService getWzOutboundOrderBService() {
+        return wzOutboundOrderBService;
+    }
+
+    public IWzOutboundOrderHService getWzOutboundOrderHService() {
+        return wzOutboundOrderHService;
+    }
+
+    public IKyTaskInfoService getTaskInfoService() {
+        return taskInfoService;
+    }
+
+    public IKyBgInfoService getKyBgInfoService() {
+        return KyBgInfoService;
+    }
+
+    public IFinanceBudgetService getFinanceBudgetService() {
+        return financeBudgetService;
+    }
+
+    public IComContractInfoExchangeService getComContractInfoExchangeService() {
+        return comContractInfoExchangeService;
+    }
+}

+ 360 - 0
summary/src/main/java/com/ruoyi/projetctCost/run/projectCostSummaryRunnable.java

@@ -0,0 +1,360 @@
+package com.ruoyi.projetctCost.run;
+
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.contractInfo.domain.ComContractInfoExchange;
+import com.ruoyi.contractInfo.service.IComContractInfoExchangeService;
+import com.ruoyi.contractInfo.contractInfoEnum.ContractInfoSjly;
+import com.ruoyi.depart.departEnum.DepartType;
+import com.ruoyi.depart.domain.SysDepart;
+import com.ruoyi.depart.service.ISysDepartService;
+import com.ruoyi.financeBudget.domain.FinanceBudget;
+import com.ruoyi.financeBudget.service.IFinanceBudgetService;
+import com.ruoyi.kyBg.domain.KyBgInfo;
+import com.ruoyi.kyBg.service.IKyBgInfoService;
+import com.ruoyi.kyTask.domain.KyTaskInfo;
+import com.ruoyi.kyTask.service.IKyTaskInfoService;
+import com.ruoyi.mesInfo.service.IMesInfoService;
+import com.ruoyi.projectChbSwf.service.IKzksProjectChbSwfService;
+import com.ruoyi.projectChbWxf.service.IKzksProjectChbWxfService;
+import com.ruoyi.projectChbZyf.service.IKzksProjectChbZyfService;
+import com.ruoyi.projectCost.domain.ProjectCost;
+import com.ruoyi.projectCost.service.IProjectCostService;
+import com.ruoyi.projetctCost.beenfactory.ServiceBeenFactory;
+import com.ruoyi.wzCk.ckDetail.domain.WzOutboundOrderB;
+import com.ruoyi.wzCk.ckDetail.service.IWzOutboundOrderBService;
+import com.ruoyi.wzCk.ckInfo.domain.WzOutboundOrderH;
+import com.ruoyi.wzCk.ckInfo.service.IWzOutboundOrderHService;
+import org.apache.commons.lang3.ObjectUtils;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+
+public class projectCostSummaryRunnable implements Runnable {
+
+    private final Integer i;
+    private final ServiceBeenFactory serviceBeenFactory;
+    private final RedisCache redisCache;
+
+    public projectCostSummaryRunnable(Integer i, ServiceBeenFactory serviceBeenFactory, RedisCache redisCache) {
+        this.i = i;
+        this.serviceBeenFactory = serviceBeenFactory;
+        this.redisCache = redisCache;
+    }
+
+    @Override
+    public void run() {
+
+        /*合同宽表service*/
+        IComContractInfoExchangeService comContractInfoExchangeService = serviceBeenFactory.getComContractInfoExchangeService();
+        /*科研报工service*/
+        IKyBgInfoService kyBgInfoService = serviceBeenFactory.getKyBgInfoService();
+        /*科研任务service*/
+        IKyTaskInfoService kyTaskInfoService = serviceBeenFactory.getTaskInfoService();
+        /*物资出库明细service*/
+        IWzOutboundOrderBService ckDetail = serviceBeenFactory.getWzOutboundOrderBService();
+        /*物资出库单service*/
+        IWzOutboundOrderHService ckInfo = serviceBeenFactory.getWzOutboundOrderHService();
+        /*事务费service*/
+        IKzksProjectChbSwfService swfService = serviceBeenFactory.getProjectChbSwfService();
+        /*外协费service*/
+        IKzksProjectChbWxfService wxfService = serviceBeenFactory.getProjectChbWxfService();
+        /*专用费service*/
+        IKzksProjectChbZyfService zyfService = serviceBeenFactory.getProjectChbZyfService();
+        /*部门service*/
+        ISysDepartService departService = serviceBeenFactory.getDepartService();
+        /*财务预算service*/
+        IFinanceBudgetService financeBudgetService = serviceBeenFactory.getFinanceBudgetService();
+        /*mes装机信息卡service*/
+        IMesInfoService mesInfoService = serviceBeenFactory.getMesInfoService();
+        /*项目成本service*/
+        IProjectCostService projectCostService = serviceBeenFactory.getProjectCostService();
+
+        final BigDecimal cpt = BigDecimal.valueOf(0); //值是0的固定比较值
+
+        int beginOffset = 0;
+        int size = 1000;
+        if (i != 0) {
+            beginOffset = i * 1000;
+        }
+        List<KyTaskInfo> taskList = kyTaskInfoService.selectKyTaskInfoListByRange(beginOffset, size);
+        List<ProjectCost> projectCosts = new ArrayList<>();  //项目成本对象集合,for循环完之后批量插入数据
+
+        for (KyTaskInfo kyTaskInfo : taskList) {
+            ProjectCost projectCost;   //项目成本对象
+            projectCost = new ProjectCost();
+            projectCost.setId(null); //主键自增
+            if (kyTaskInfo.getTaskno() != null) projectCost.setTaskno(kyTaskInfo.getTaskno());  //任务号
+            if (kyTaskInfo.getTaskname() != null) projectCost.setTaskname(kyTaskInfo.getTaskname()); //任务名称
+            if (kyTaskInfo.getXhname() != null) projectCost.setXhname(kyTaskInfo.getXhname()); //型号名称
+            if (kyTaskInfo.getJhwcsj() != null) projectCost.setJhwcsj(kyTaskInfo.getJhwcsj()); //计划完成时间(进度要求)
+            if (kyTaskInfo.getYzjdname() != null) projectCost.setYzjdname(kyTaskInfo.getYzjdname()); //研制阶段
+            if (kyTaskInfo.getProcessPercent() != null)
+                projectCost.setProcessPercent(BigDecimal.valueOf(Double.parseDouble(kyTaskInfo.getProcessPercent())).setScale(2, RoundingMode.HALF_UP)); //项目进度
+            if (kyTaskInfo.getYzsl() != null) projectCost.setYzsl(kyTaskInfo.getYzsl()); //研制数量
+            if (kyTaskInfo.getZrbm() != null) projectCost.setZrbm(kyTaskInfo.getZrbm()); //责任部门
+            if (kyTaskInfo.getJycsid() != null) projectCost.setJycsid(Long.getLong(kyTaskInfo.getJycsid())); //下达部门ID
+            if (kyTaskInfo.getJycs() != null) projectCost.setJycs(kyTaskInfo.getJycs()); //下达部门
+            if (kyTaskInfo.getHxzxid() != null) projectCost.setHxzxid(kyTaskInfo.getHxzxid()); //1:横向 2:纵向
+            if (kyTaskInfo.getHxzxname() != null) projectCost.setHxzxname(kyTaskInfo.getHxzxname()); //横向纵向
+            if (kyTaskInfo.getTasktype() != null) projectCost.setTasktype(kyTaskInfo.getTasktype()); //任务类型
+            if (kyTaskInfo.getAuditPrice() != null) projectCost.setAuditPrice(kyTaskInfo.getAuditPrice()); //审计审价
+            if (kyTaskInfo.getIflag() != null) projectCost.setIflag(kyTaskInfo.getIflag()); //任务状态
+            if (kyTaskInfo.getBrief() != null) projectCost.setBrief(kyTaskInfo.getBrief()); //用户简称
+            if (kyTaskInfo.getRefTaskNo() != null)
+                projectCost.setRefTaskNo(Long.getLong(kyTaskInfo.getRefTaskNo())); //父级任务号
+            if (kyTaskInfo.getPccode() != null) projectCost.setPcCode(Long.getLong(kyTaskInfo.getPccode())); //批产任务号
+            if (kyTaskInfo.getBlcode() != null) projectCost.setBlCode(Long.getLong(kyTaskInfo.getBlcode())); //备料任务号
+            if (kyTaskInfo.getBusinessMan() != null) projectCost.setBusinessMan(kyTaskInfo.getBusinessMan()); //业务员
+
+
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*合同额*/
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            List<ComContractInfoExchange> contractTask =
+                    comContractInfoExchangeService.selectProjectCostFromCOmContractInfoExchangeByTaskNo(kyTaskInfo.getTaskno(), ContractInfoSjly.CONTRACT_TASK);
+
+            BigDecimal htfpe = BigDecimal.valueOf(0); //初始化合同额,默认为0
+            if (ObjectUtils.isNotEmpty(contractTask)) {
+                for (ComContractInfoExchange comContractInfoExchange : contractTask)
+                    if (comContractInfoExchange.getHtfpe() != null)
+                        htfpe = htfpe.add(comContractInfoExchange.getHtfpe());
+            }
+            projectCost.setContractfpe(htfpe.setScale(2, RoundingMode.HALF_UP)); //合同额
+
+            /* todo 根据签署日期(qsrq)计算每年的任务合同额 */
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*已收款*/
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            List<ComContractInfoExchange> contractPay =
+                    comContractInfoExchangeService.selectProjectCostFromCOmContractInfoExchangeByTaskNo(kyTaskInfo.getTaskno(), ContractInfoSjly.CONTRACT_PAY);
+
+            BigDecimal rwskje = BigDecimal.valueOf(0); //初始化已收款金额,默认为0
+            if (ObjectUtils.isNotEmpty(contractPay)) {
+                for (ComContractInfoExchange comContractInfoExchange : contractPay) {
+                    if (comContractInfoExchange.getRwskje() != null)
+                        rwskje = rwskje.add(comContractInfoExchange.getRwskje());
+                }
+            }
+            projectCost.setTaskMoney(rwskje.setScale(2, RoundingMode.HALF_UP)); //已收款
+
+            /* todo 根据到款日期/汇票到期日期(dkhpdqrq)计算每年的任务已收款*/
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/           /*材料费*/
+            /*材料费*/
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/         /* 计算材料费,查询物资出库明细*/
+
+            BigDecimal clfSum = BigDecimal.valueOf(0); //初始化材料费,默认为0
+
+            /*根据任务号查询对应的出库单号集合*/
+            List<WzOutboundOrderH> ckdhList = ckInfo.selectCkdhListFromCkinfoByTaskNo(kyTaskInfo.getTaskno());
+
+            if (ckdhList != null) {
+                for (WzOutboundOrderH wzOutboundOrderH : ckdhList) {
+                    Integer count = ckDetail.getCkDetailDataCountByCkdh(wzOutboundOrderH.getCkdh());
+                    /*经过跟沈工沟通,如果一个出库单对应的物料单超过5000,确认为异常数据,跳过计算*/
+                    if (count > 5000) continue;
+
+                    /*根据每个出库单号,查询物资出库明细中对应的物料单*/
+                    List<WzOutboundOrderB> ckDetailDataList = ckDetail.selectProjectCostFromCkDetailByCkdh(wzOutboundOrderH.getCkdh());
+                    /*循环每个物料单,求材料费*/
+                    BigDecimal clf = BigDecimal.valueOf(0);
+                    for (WzOutboundOrderB ckDetailData : ckDetailDataList) {
+                        BigDecimal cgdj = ckDetailData.getCgdj(); //采购单价
+                        BigDecimal nbdj = ckDetailData.getNbdj(); //内部单价
+                        BigDecimal sfzsl = ckDetailData.getSfzsl(); //实发主数量
+
+                        /*如果实发主数量为空,则给默认值0*/
+                        Optional<BigDecimal> sfzsl1 = Optional.ofNullable(sfzsl);
+                        sfzsl = sfzsl1.orElse(BigDecimal.valueOf(0));
+
+                        /*计算:采购单价或内部单价*实发主数量 (若没有采购单价,则使用内部单价)*/
+                        BigDecimal wlf = BigDecimal.valueOf(0);
+                        if (cgdj != null) {
+                            wlf = cgdj.multiply(sfzsl);
+                        } else if (nbdj != null) {
+                            wlf = nbdj.multiply(sfzsl);
+                        }
+                        clf = clf.add(wlf);
+                    }
+                    clfSum = clfSum.add(clf);
+                }
+            }
+
+            projectCost.setClf(clfSum.setScale(2, RoundingMode.HALF_UP)); //材料费
+
+            /* todo 根据制单日期(zdrq)计算每年的任务材料费*/
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*事务费*///同任务号的事务费数据,辅助金额累加
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            BigDecimal swf = swfService.selectSwfByTaskno(kyTaskInfo.getTaskno());
+            BigDecimal swfSum = Optional.ofNullable(swf).orElse(BigDecimal.valueOf(0));
+            projectCost.setSwf(swfSum.setScale(2, RoundingMode.HALF_UP)); //事务费
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*外协费*///同任务号的外协费数据,辅助金额累加
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            BigDecimal wxf = wxfService.selectWxfByTaskno(kyTaskInfo.getTaskno());
+            BigDecimal wxfSum = Optional.ofNullable(wxf).orElse(BigDecimal.valueOf(0));
+            projectCost.setWxf(wxfSum.setScale(2, RoundingMode.HALF_UP)); //外协费
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*专用费*///同任务号的专用费数据,辅助金额累加
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            BigDecimal zyf = zyfService.selectZyfByTaskno(kyTaskInfo.getTaskno());
+            BigDecimal zyfSum = Optional.ofNullable(zyf).orElse(BigDecimal.valueOf(0));
+            projectCost.setZyf(zyfSum.setScale(2, RoundingMode.HALF_UP)); //专用费
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*设计工时,生产工时,总工时*///和任务号关联得类型为设计部门的科研报工工时累加
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            List<KyBgInfo> kyBgInfoList = kyBgInfoService.selectKyBgInfoListByTaskno(kyTaskInfo.getTaskno());
+            BigDecimal sjgs = BigDecimal.valueOf(0); //初始化设计工时,默认为0
+            BigDecimal scgs = BigDecimal.valueOf(0); //初始化生产工时,默认为0
+            if (kyBgInfoList != null) {
+                for (KyBgInfo kyBgInfo : kyBgInfoList) {
+                    SysDepart sysDepart = departService.selectDeptTypeByDeptName(kyBgInfo.getUserdept());
+                    if (sysDepart != null) {
+                        if (Objects.equals(sysDepart.getDeptType(), DepartType.DESIGN_TIME)) {
+                            BigDecimal workhour = kyBgInfo.getWorkhour();
+                            BigDecimal bigDecimal = Optional.ofNullable(workhour).orElse(BigDecimal.valueOf(0));
+                            sjgs = sjgs.add(bigDecimal);
+                        } else if (Objects.equals(sysDepart.getDeptType(), DepartType.PRODUCE_TIME)) {
+                            BigDecimal workhour = kyBgInfo.getWorkhour();
+                            BigDecimal bigDecimal = Optional.ofNullable(workhour).orElse(BigDecimal.valueOf(0));
+                            scgs = scgs.add(bigDecimal);
+                        }
+                    }
+                }
+            }
+            projectCost.setSjgs(sjgs.setScale(2, RoundingMode.HALF_UP)); //设计工时
+            projectCost.setScgs(scgs.setScale(2, RoundingMode.HALF_UP)); //生产工时
+            projectCost.setWorkhour(sjgs.add(scgs)); //总工时
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*燃动费*///前:直接成本*1.5% 后:(设计工时+生产工时)*6.78 备:直接成本:(材料费+事务费+外协费+专用费)
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*固资费*///前:直接成本*2.5% 后:(设计工时+生产工时)*15.97 备:直接成本:(材料费+事务费+外协费+专用费)
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*工资费*///前:直接成本*17% 后:设计工时*211.25+生产工时*130 备:直接成本:(材料费+事务费+外协费+专用费)
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*管理费*///前:直接成本*5%
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            BigDecimal directCosts = clfSum.add(swfSum).add(wxfSum).add(zyfSum); //直接成本
+
+            BigDecimal rdfSum; //燃动费
+            BigDecimal gzzjSum; // 固定资产折旧费
+            BigDecimal gzfSum; //工资费
+            BigDecimal glfSum = BigDecimal.valueOf(0); //管理费,默认为0
+            if (!(sjgs.compareTo(cpt) == 0) || !(scgs.compareTo(cpt) == 0)) { //如果设计工时或者生产工时有一个不为0,则根据后方法计算
+                BigDecimal gsSum = sjgs.add(scgs); //工时总和
+                rdfSum = gsSum.multiply(BigDecimal.valueOf(6.78)); //求燃动费
+                gzzjSum = gsSum.multiply(BigDecimal.valueOf(15.97)); //求固资费
+                //求工资费
+                BigDecimal sjgz = sjgs.multiply(BigDecimal.valueOf(211.25));//设计工资
+                BigDecimal scgz = scgs.multiply(BigDecimal.valueOf(130)); //生产工资
+                gzfSum = sjgz.add(scgz); //工资费
+            } else {
+                rdfSum = directCosts.multiply(BigDecimal.valueOf(0.015)); //求燃动费
+                gzzjSum = directCosts.multiply(BigDecimal.valueOf(0.025)); //求固资费
+                gzfSum = directCosts.multiply(BigDecimal.valueOf(0.17)); //求工资费
+                glfSum = directCosts.multiply(BigDecimal.valueOf(0.05)); //求管理费
+            }
+            projectCost.setRldlf(rdfSum.setScale(2, RoundingMode.HALF_UP)); //设置燃料动力费
+            projectCost.setGdzczj(gzzjSum.setScale(2, RoundingMode.HALF_UP)); //设置固定资产折旧费
+            projectCost.setGzjlwf(gzfSum.setScale(2, RoundingMode.HALF_UP)); //设置工资费
+            projectCost.setGlf(glfSum.setScale(2, RoundingMode.HALF_UP)); //设置管理费
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*总成本*///材料费+事务费+外协费+专用费+燃动费+固资费+工资+管理费
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            BigDecimal zcb = clfSum.add(swfSum).add(wxfSum).add(zyfSum).add(rdfSum).add(gzzjSum).add(gzfSum).add(glfSum); //求总成本
+            projectCost.setZcb(zcb.setScale(2, RoundingMode.HALF_UP)); //设置总成本
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*预估价*///科研平台财务预算的预估价,根据科研任务号查找
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            FinanceBudget financeBudget = financeBudgetService.selectEstimationCoatByTaskno(kyTaskInfo.getTaskno());
+            String estimationCoat = financeBudget.getEstimationCoat();
+            BigDecimal ygj = BigDecimal.valueOf(0);
+            if (ObjectUtils.isNotEmpty(estimationCoat)) {
+                ygj = BigDecimal.valueOf(Double.parseDouble(estimationCoat));
+            }
+            projectCost.setEstimationCoat(ygj.setScale(2, RoundingMode.HALF_UP)); //设置预估价
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*利润额*///合同额或预估价-总成本,优先合同额
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*利润率*///利润额 /(合同额或预估价)
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            BigDecimal lre = BigDecimal.valueOf(0); //初始化利润额,默认为0
+            BigDecimal lrl = BigDecimal.valueOf(0); //利润率
+            if (!(htfpe.compareTo(lre) == 0)) { //有合同额,优先合同额-总成本
+                lre = htfpe.subtract(zcb);
+                lrl = lre.divide(htfpe, 2, RoundingMode.HALF_UP); //避免除不尽,设置保留两位小数
+            } else if (!(ygj.compareTo(lre) == 0)) {
+                lre = ygj.subtract(zcb);
+                lrl = lre.divide(ygj, 2, RoundingMode.HALF_UP); //避免除不尽,设置保留两位小数
+            }
+            projectCost.setLre(lre.setScale(2, RoundingMode.HALF_UP)); //设置利润额
+            projectCost.setLrl(lrl.setScale(2, RoundingMode.HALF_UP)); //设置利润率
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*单台收入*///(合同额或预估价)/数量 有合同额,优先合同额
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            BigDecimal dtsr = BigDecimal.valueOf(0); //初始化单台收入,默认为0
+            if (!(htfpe.compareTo(lre) == 0)) {
+                dtsr = htfpe.divide(BigDecimal.valueOf(kyTaskInfo.getYzsl()), 2, RoundingMode.HALF_UP); //避免除不尽,设置保留两位小数
+            } else if (!(ygj.compareTo(lre) == 0)) {
+                dtsr = ygj.divide(BigDecimal.valueOf(kyTaskInfo.getYzsl()), 2, RoundingMode.HALF_UP); //避免除不尽,设置保留两位小数
+            }
+            projectCost.setOneIncome(dtsr.setScale(2, RoundingMode.HALF_UP)); //设置单台收入
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*单台成本*///(总成本/数量)
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            BigDecimal dtcb = zcb.divide(BigDecimal.valueOf(kyTaskInfo.getYzsl()), 2, RoundingMode.HALF_UP); //避免除不尽,设置保留两位小数
+            projectCost.setOneCost(dtcb);
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*单台利润*/// 单台收入-单台成本
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            BigDecimal dtlr = dtsr.subtract(dtcb);
+            projectCost.setOneProfit(dtlr.setScale(2, RoundingMode.HALF_UP));  //设置单台利润
+
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+            /*成本进度*/// 总成本/(合同额或预估价)
+            /*------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+            BigDecimal cbjd = BigDecimal.valueOf(0);
+            if (!(htfpe.compareTo(lre) == 0)) { //有合同额,优先合同额-总成本
+                cbjd = zcb.divide(htfpe, 2, RoundingMode.HALF_UP); //避免除不尽,设置保留两位小数
+            } else if ((!(ygj.compareTo(lre) == 0))) {
+                cbjd = zcb.divide(ygj, 2, RoundingMode.HALF_UP); //避免除不尽,设置保留两位小数
+            }
+            projectCost.setCostPercent(cbjd.setScale(2,RoundingMode.HALF_UP)); //设置成本进度
+
+            projectCosts.add(projectCost);
+        }
+        boolean flag = projectCostService.insertBatchProjectCost(projectCosts);
+    }
+}

+ 136 - 0
summary/src/main/java/com/ruoyi/projetctCost/task/projectCostTask.java

@@ -0,0 +1,136 @@
+package com.ruoyi.projetctCost.task;
+
+import com.ruoyi.common.constant.CacheConstants;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.kyTask.service.IKyTaskInfoService;
+import com.ruoyi.mesInfo.service.IMesInfoService;
+import com.ruoyi.projetctCost.ThreadPool.InstallationCostSummaryThreadPool;
+import com.ruoyi.projetctCost.ThreadPool.SingletonThreadPool;
+import com.ruoyi.projetctCost.beenfactory.ServiceBeenFactory;
+import com.ruoyi.projetctCost.run.InstallationCostSummaryCallable;
+import com.ruoyi.projetctCost.run.projectCostSummaryRunnable;
+import com.ruoyi.projetctCost.util.RedisLockMethodUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+
+
+@Component("projectCostTask")
+public class projectCostTask {
+    public projectCostTask() {
+    }
+
+    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
+        System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
+    }
+
+    public void ryParams(String params) {
+        System.out.println("执行有参方法:" + params);
+    }
+
+    public void ryNoParams() {
+        System.out.println("执行无参方法");
+    }
+
+    @Autowired
+    private IKyTaskInfoService kyTaskInfoService;
+
+    @Autowired
+    private ServiceBeenFactory serviceBeenFactory;
+    @Resource
+    private RedisCache redisCache;
+
+    /*计算项目成本的各组成部分,不包含装机成本,装机成本是增量计算的数据*/
+    public void projectCostSummaryTask() {
+
+        /*单例固定大小线程池*/
+        ThreadPoolExecutor executor = SingletonThreadPool.getInstance().getExecutor();
+        //当前科研任务总数
+        int taskCount = kyTaskInfoService.getTaskCount();
+        //分片距离
+        int waterMark = 1000;
+        //完整的分片
+        int splitNum = taskCount / waterMark;
+        //余数
+        int remainder = taskCount % waterMark;
+        //多开一个线程处理余数
+        if (remainder > 0) splitNum = splitNum + 1;
+
+        for (int i = 0; i < splitNum; i++) {
+            /*项目成本的计算,以科研任务作为维度,以任务号分片加入线程池任务*/
+            executor.execute(new projectCostSummaryRunnable(i, serviceBeenFactory, redisCache));
+        }
+    }
+
+    /*计算项目成本内的装机成本*/
+    public void InstallationCostSummaryTask() throws ExecutionException, InterruptedException {
+
+        /*mes装机信息卡service*/
+        IMesInfoService mesInfoService = serviceBeenFactory.getMesInfoService();
+        /*装机成本计算专用线程池*/
+        ThreadPoolExecutor executor = InstallationCostSummaryThreadPool.getInstance().getExecutor();
+
+        //一次while循环处理的数量
+        long size = 10000;
+
+        // 一个线程一次性处理2000条数据
+        long watermark = 2000;
+
+        while (true) {
+            //获取当前mesInfo表中最大的主键
+            Long MesInfoCount = mesInfoService.getMesInfoMaxKeyId();
+            //获取上次处理的装机信息卡最后一条数据的id
+            Long checkPoint = mesInfoService.selectCheckPoint();
+            //未处理的数量
+            long unprocessedQuantity = MesInfoCount - checkPoint;
+            //未处理的数据为0,结束计算
+            if (unprocessedQuantity == 0) {
+                break;
+            }
+            //未处理的数据量超过一万条,将其中一万条作为一个批次处理
+            if (unprocessedQuantity < 100000) size = unprocessedQuantity;
+
+            //起始id
+            long startId = checkPoint; //0
+            //终点ID
+            long endId;
+            //完整分片
+            long splitNum = size / watermark;
+            //余数
+            long remainder = size % watermark;
+            //有余数,就多开个线程处理
+            if (remainder != 0) splitNum = splitNum + 1;
+
+            ArrayList<Future<Boolean>> futures = new ArrayList<>();
+
+            for (long i = 0; i < splitNum; i++) {
+                startId = startId + (size * i); // 0 2000
+                endId = startId + watermark + 1; //2001 4001
+                Future<Boolean> future = executor.submit(new InstallationCostSummaryCallable(startId, endId, serviceBeenFactory, RedisLockMethodUtil.getInstance(), redisCache));
+                futures.add(future);
+            }
+            boolean success = true;
+            for (Future<Boolean> future : futures) {
+                Boolean aBoolean = future.get();
+                if (!aBoolean) {
+                    success = aBoolean;
+                }
+            }
+            if (!success) {
+                break;
+            }
+            long newCheckPoint = checkPoint + size;
+            int i = mesInfoService.recordCheckPoint(newCheckPoint);
+            if (i == 0) break;
+
+        }
+
+        redisCache.deleteObject(CacheConstants.INSTALLATION_COST);
+    }
+}