Pārlūkot izejas kodu

aps-生产计划跟踪报表

sucheng 11 mēneši atpakaļ
vecāks
revīzija
d81af71889

+ 159 - 0
bs-common/src/main/java/com/rongwei/safecommon/config/MybatisConfig.java

@@ -0,0 +1,159 @@
+package com.rongwei.safecommon.config;
+
+import com.baomidou.mybatisplus.core.parser.ISqlParser;
+import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
+import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
+import com.rongwei.rwcommonconfig.config.interceptor.SaasPaginationInterceptor;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.reflection.MetaObject;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by duyisong on 17/5/28.
+ */
+@EnableTransactionManagement
+@Configuration
+@MapperScan("com.rongwei.*.*.dao")
+public class MybatisConfig {
+
+//    @Autowired
+//    private RedisService redisService;
+
+//    /**
+//     * 自定义查询sql多数据库适配
+//     * @return
+//     */
+//    @Bean
+//    public QuerySqlAdaptationInterceptor querySqlAdaptationInterceptor(){
+//        QuerySqlAdaptationInterceptor sqlAdaptation = new QuerySqlAdaptationInterceptor();
+//        return sqlAdaptation;
+//    }
+
+    /*
+     * 分页插件,自动识别数据库类型
+     * 多租户,请参考官网【插件扩展】
+     */
+    @Bean
+    public SaasPaginationInterceptor paginationInterceptor() {
+        SaasPaginationInterceptor paginationInterceptor = new SaasPaginationInterceptor();
+        /*
+         * 【测试多租户】 SQL 解析处理拦截器<br>
+         * 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )<br>
+         */
+        List<ISqlParser> sqlParserList = new ArrayList<>();
+//        TenantSqlParser tenantSqlParser = new TenantSqlParser();
+//        tenantSqlParser.setTenantHandler(new TenantHandler() {
+//            @Override
+//            public Expression getTenantId() {
+//                String tenantId = null;
+//                String token = ThreadLocalResource.token.get();
+//                SysUserVo currUser = null;
+//                if(StringUtils.isNotEmpty(token)){
+//                    currUser = redisService.getLoginUser(token);
+//                }
+//                if(currUser != null && currUser.getTenantDo() != null){
+//                    tenantId = currUser.getTenantDo().getId();
+//                }
+//
+//                return new StringValue(tenantId);
+//            }
+//
+//            @Override
+//            public String getTenantIdColumn() {
+//                return "TENANTID";
+//            }
+//
+//            @Override
+//            public boolean doTableFilter(String tableName) {
+//                // 这里可以判断是否过滤表,true表示过滤、false不过滤
+//                /*
+//                if ("user".equals(tableName)) {
+//                    return true;
+//                }*/
+//                return true;
+//            }
+//        });
+//        sqlParserList.add(tenantSqlParser);
+        paginationInterceptor.setSqlParserList(sqlParserList);
+        paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
+            @Override
+            public boolean doFilter(MetaObject metaObject) {
+                MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
+                // 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
+                if ("com.rongwei.rwadmincommon.system.dao.getAll".equals(ms.getId())) {
+                    return true;
+                }
+                return false;
+            }
+        });
+        paginationInterceptor.setLimit(2000);
+        return paginationInterceptor;
+    }
+
+//    /**
+//     * 打印 sql
+//     */
+//    @Bean
+//    public PerformanceInterceptor performanceInterceptor() {
+//        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
+//        //格式化sql语句
+//        Properties properties = new Properties();
+//        properties.setProperty("format", "true");
+//        performanceInterceptor.setProperties(properties);
+//        return performanceInterceptor;
+//    }
+
+    /*@Bean
+    public MapperScannerConfigurer mapperScannerConfigurer() {
+        log.info("[config] 注册 tkMtBatis");
+        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
+        mapperScannerConfigurer.setBasePackage("com.rongwei.rwadmin.system.dao");
+        Properties properties = new Properties();
+        properties.setProperty("markerInterface", "com.rongwei.rwadmin.common.mapper.BaseDao");
+        mapperScannerConfigurer.setProperties(properties);
+        return mapperScannerConfigurer;
+    }
+
+    @Bean
+    public PageHelper pageHelper(DataSource dataSource) {
+        log.info("[config] 注册 MyBatis分页插件PageHelper");
+        PageHelper pageHelper = new PageHelper();
+        Properties p = new Properties();
+        p.setProperty("offsetAsPageNum", "true");
+        p.setProperty("rowBoundsWithCount", "true");
+        p.setProperty("reasonable", "true");
+        pageHelper.setProperties(p);
+        return pageHelper;
+    }*/
+
+
+    // 配置sqlSessionFactory
+    /*@Bean(name = "sqlSessionFactory")
+    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource
+            ,QuerySqlAdaptationInterceptor sqlAdaptation,PaginationInterceptor paginationInterceptor) {
+        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
+        bean.setDataSource(dataSource);
+        if(StringUtils.isNotBlank(typeAliasesPackage)){
+            bean.setTypeAliasesPackage(typeAliasesPackage);
+        }
+
+        // 自定义的sql日志拦截器
+        Interceptor sqlLogInterceptor = new SqlLogInterceptor();
+        Interceptor[] plugins =  new Interceptor[]{ sqlLogInterceptor};
+        bean.setPlugins(plugins);
+        try {
+            bean.setMapperLocations(resolver.getResources(xmlLocation));
+            return bean.getObject();
+        } catch (Exception e) {
+
+            throw new RuntimeException(e);
+        }
+    }*/
+
+}

+ 5 - 4
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/dao/ApsBlankOrderDao.java

@@ -1,14 +1,13 @@
 package com.rongwei.bscommon.sys.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.rongwei.bsentity.domain.ApsBlankOrderDo;
 import com.rongwei.bsentity.domain.ApsProcessOperationDo;
 import com.rongwei.bsentity.domain.ApsProcessOperationProcessEquDo;
 import com.rongwei.bsentity.domain.AspCheckItemsDo;
-import com.rongwei.bsentity.vo.ApsBlankOrderVo;
-import com.rongwei.bsentity.vo.BlankIdAndProcessStatusVo;
-import com.rongwei.bsentity.vo.UpdateBlankDeliveryDateVo;
-import com.rongwei.bsentity.vo.WashingMetal;
+import com.rongwei.bsentity.vo.*;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
@@ -119,4 +118,6 @@ public interface ApsBlankOrderDao extends BaseMapper<ApsBlankOrderDo> {
     void updateBatchNumberByBorrow(@Param("batchnumber") String batchnumber, @Param("processoperationequid") String processoperationequid, @Param("joboutputmaterialid") String joboutputmaterialid);
 
     List<UpdateBlankDeliveryDateVo> getBlankDeliveryDate(@Param("blankId") String blankId);
+
+    IPage<ProductPlanReportVo> selectPageReport(Page<ProductPlanReportVo> queryPage, @Param("param") ProductPlanReportParamVo param);
 }

+ 3 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/dao/ApsProductionOrderDao.java

@@ -3,6 +3,7 @@ package com.rongwei.bscommon.sys.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.rongwei.bsentity.domain.ApsProcessOperationDo;
 import com.rongwei.bsentity.domain.ApsProductionOrderDo;
+import com.rongwei.bsentity.vo.BlankIdAndWorkShopVo;
 import com.rongwei.bsentity.vo.ProductDetailIdAndPlanOutPutRollCountAllVo;
 import com.rongwei.bsentity.vo.ProductTypeIdAndPidVo;
 import org.apache.ibatis.annotations.Param;
@@ -75,6 +76,8 @@ public interface ApsProductionOrderDao extends BaseMapper<ApsProductionOrderDo>
 
     @Select("select * from aps_process_operation where DELETED = 0 AND PLANINPUTID = #{joboutputmaterialid} AND LEAVEWAITWORKROLL > 0 ORDER BY PLANSTARTDATE DESC LIMIT 1")
     ApsProcessOperationDo selectNeedBorrowOperation(@Param("joboutputmaterialid") String joboutputmaterialid);
+
+    List<BlankIdAndWorkShopVo> getWorkShopByBlankId(@Param("blankIdList") List<String> blankIdList);
 }
 
 

+ 3 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/ApsBlankOrderService.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.rongwei.bsentity.domain.ApsProductionTechnicalRequirementDo;
 import com.rongwei.bsentity.vo.*;
 import com.rongwei.rwcommon.base.R;
+import com.rongwei.rwcommon.vo.CriteriaQuery;
+
 import java.util.List;
 import java.util.Map;
 
@@ -53,4 +55,5 @@ public interface ApsBlankOrderService extends IService<ApsBlankOrderDo> {
 
     R checkSchedule(CheckScheduleReq req);
 
+    R productPlanReport(CriteriaQuery req);
 }

+ 196 - 0
cx-aps/cx-aps-common/src/main/java/com/rongwei/bscommon/sys/service/impl/ApsBlankOrderServiceImpl.java

@@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.rongwei.bscommon.sys.dao.*;
 import com.rongwei.bscommon.sys.service.*;
@@ -22,6 +24,10 @@ import com.rongwei.rwcommon.base.R;
 import com.rongwei.rwcommon.base.exception.CustomException;
 import com.rongwei.rwcommon.utils.SecurityUtil;
 import com.rongwei.rwcommon.utils.StringUtils;
+import com.rongwei.rwcommon.vo.ColumnQueryType;
+import com.rongwei.rwcommon.vo.CriteriaQuery;
+import com.rongwei.rwcommon.vo.SearchColumnVo;
+import com.rongwei.rwcommon.vo.SearchOrderVo;
 import com.rongwei.safecommon.utils.CXCommonUtils;
 import com.rongwei.safecommon.utils.SaveConstans;
 import org.slf4j.Logger;
@@ -2668,4 +2674,194 @@ public class ApsBlankOrderServiceImpl extends ServiceImpl<ApsBlankOrderDao, ApsB
         calendar.add(Calendar.HOUR_OF_DAY, hour);
         return calendar.getTime();
     }
+
+
+    @Override
+    public R productPlanReport(CriteriaQuery req) {
+        //解析入参
+        //每页数量
+        Integer size = req.getSize();
+        //页数
+        Integer current = req.getCurrent();
+        //查询条件
+        /**
+         * 客户名称:模糊查询;
+         * 客户订单号:模糊查询;
+         * 承诺交货日期:日历选择日期范围
+         * 坯料计划编号:模糊查询;
+         */
+        //页签查询:订单产品生产状态
+
+        ProductPlanReportParamVo param = new ProductPlanReportParamVo();
+
+        List<ColumnQueryType> columnQueryTypes = req.getColumnQueryTypes();
+        for (ColumnQueryType columnQueryType : columnQueryTypes) {
+            for (SearchColumnVo column : columnQueryType.getColumns()) {
+                if (column.getField().equals("customname")) {
+                    param.setCustomName(column.getValue());
+                }
+                if (column.getField().equals("customorderno")) {
+                    param.setCustomOrderNo(column.getValue());
+                }
+                if (column.getField().equals("promiseDateStart")) {
+                    param.setStartDate(column.getStartDate());
+                    param.setEndDate(column.getEndDate());
+                }
+                if (column.getField().equals("blankNumber")) {
+                    param.setBlankNumber(column.getValue());
+                }
+                if (column.getField().equals("productionOrderStatus")) {
+                    param.setProductionOrderStatus(column.getValue());
+                }
+            }
+        }
+
+        //排序规则
+        String order = "";
+        List<SearchOrderVo> orders = req.getOrders();
+        if (ObjectUtil.isNotEmpty(orders)) {
+            for (SearchOrderVo searchOrderVo : orders) {
+                if (searchOrderVo.getOrderName().equals("auditdate")) {
+                    order = "a.auditdate " + searchOrderVo.getOrderType() + ",";
+                }
+                if (searchOrderVo.getOrderName().equals("customname")) {
+                    order = "a.customname " + searchOrderVo.getOrderType() + ",";
+                }
+            }
+        }
+        param.setOrders(order);
+
+        Page<ProductPlanReportVo> queryPage = new Page<>(current, size);
+
+
+        IPage<ProductPlanReportVo> res = this.baseMapper.selectPageReport(queryPage, param);
+
+        //分页查询结束,拼接结果字段信息
+        List<ProductPlanReportVo> records = res.getRecords();
+        //当前页面的坯料计划的ID集合
+        List<String> blankIdList = records.stream().map(ProductPlanReportVo::getBlankId).distinct().collect(Collectors.toList());
+        List<BlankIdAndWorkShopVo> blankIdAndWorkShopList = new LinkedList<>();
+        if (ObjectUtil.isNotEmpty(blankIdList)) {
+            //查询坯料计划对应的 坯料 加工车间
+            blankIdAndWorkShopList = apsProcessOperationDao.getWorkShopByBlankId(blankIdList);
+        }
+
+        //查询坯料计划对应的工序作业信息
+        List<ApsProcessOperationDo> processOperationDoList = apsProcessOperationService.list(new QueryWrapper<ApsProcessOperationDo>().lambda().in(ApsProcessOperationDo::getBlankid, blankIdList));
+
+        //构造生产进度
+        //获取所有的最终工序ID集合
+        List<String> lastProcessIdList = records.stream().filter(item -> ObjectUtil.isNotEmpty(item.getLastProcessId())).map(ProductPlanReportVo::getLastProcessId).distinct().collect(Collectors.toList());
+        //组装map《最终工序ID,生产进度》
+        Map<String, String> processLoadingMap = new HashMap<>();
+        doSetMapLoading(processLoadingMap, lastProcessIdList, processOperationDoList);
+
+        for (ProductPlanReportVo record : records) {
+            //加工车间
+            if (ObjectUtil.isNotEmpty(blankIdAndWorkShopList)) {
+                BlankIdAndWorkShopVo blankIdAndWorkShopVo = blankIdAndWorkShopList.stream().filter(item -> item.getBlankId().equals(record.getBlankId())).findFirst().orElse(null);
+                if (ObjectUtil.isNotEmpty(blankIdAndWorkShopVo)) {
+                    record.setProcessWorkShop(blankIdAndWorkShopVo.getPrcessWorkShop());
+                }
+            }
+
+            //计划转料日期
+            //实际转料日期
+            //已投料数量
+            List<ApsProcessOperationDo> operationDoList = processOperationDoList.stream().filter(item -> item.getBlankid().equals(record.getBlankId()) && item.getIfblankprocess().equals("否")).collect(Collectors.toList());
+            if (ObjectUtil.isNotEmpty(operationDoList)) {
+                ApsProcessOperationDo processOperationDo1 = operationDoList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getPlanstartdate())).min(Comparator.comparing(ApsProcessOperationDo::getPlanstartdate)).orElse(null);
+                if (ObjectUtil.isNotEmpty(processOperationDo1)) {
+                    record.setPlanChangeBlankDate(processOperationDo1.getPlanstartdate());
+                    record.setHadStartRoll(processOperationDo1.getStartingroll());
+                }
+                ApsProcessOperationDo processOperationDo2 = operationDoList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getActualstartdate())).min(Comparator.comparing(ApsProcessOperationDo::getActualstartdate)).orElse(null);
+                if (ObjectUtil.isNotEmpty(processOperationDo2)) {
+                    record.setActualChangeBlankDate(processOperationDo2.getActualstartdate());
+                }
+            }
+
+
+            //生产进度
+            if (ObjectUtil.isNotEmpty(record.getLastProcessId()) && processLoadingMap.containsKey(record.getLastProcessId())) {
+                record.setProductLoading(processLoadingMap.get(record.getLastProcessId()));
+            }
+
+            //计划开工时间
+            //计划完工时间
+            //实际开工时间
+            //实际完工时间
+            List<ApsProcessOperationDo> operationDoList2 = processOperationDoList.stream().filter(item -> item.getBlankid().equals(record.getBlankId())).collect(Collectors.toList());
+            if (ObjectUtil.isNotEmpty(operationDoList2)) {
+                ApsProcessOperationDo processOperationDo1 = operationDoList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getPlanstartdate())).min(Comparator.comparing(ApsProcessOperationDo::getPlanstartdate)).orElse(null);
+                if (ObjectUtil.isNotEmpty(processOperationDo1)) {
+                    record.setPlanStartDate(processOperationDo1.getPlanstartdate());
+                }
+
+                ApsProcessOperationDo processOperationDo2 = operationDoList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getPlanenddate())).max(Comparator.comparing(ApsProcessOperationDo::getPlanenddate)).orElse(null);
+                if (ObjectUtil.isNotEmpty(processOperationDo2)) {
+                    record.setPlanEndDate(processOperationDo2.getPlanstartdate());
+                }
+
+                ApsProcessOperationDo processOperationDo3 = operationDoList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getActualstartdate())).min(Comparator.comparing(ApsProcessOperationDo::getActualstartdate)).orElse(null);
+                if (ObjectUtil.isNotEmpty(processOperationDo3)) {
+                    record.setActualStartDate(processOperationDo3.getActualstartdate());
+                }
+
+                ApsProcessOperationDo processOperationDo4 = operationDoList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getActualfinishdate())).max(Comparator.comparing(ApsProcessOperationDo::getActualfinishdate)).orElse(null);
+                if (ObjectUtil.isNotEmpty(processOperationDo4)) {
+                    record.setActualEndDate(processOperationDo4.getActualfinishdate());
+                }
+
+            }
+
+        }
+
+
+        return R.ok(res);
+    }
+
+    private void doSetMapLoading(Map<String, String> processLoadingMap, List<String> lastProcessIdList, List<ApsProcessOperationDo> processOperationDoList) {
+        for (String s : lastProcessIdList) {
+
+            LinkedList<String> stack = new LinkedList<>();
+            //迭代处理
+            setStack(processLoadingMap, processOperationDoList, s, stack, s);
+        }
+    }
+
+    //迭代处理,组装生产进度,赋值stack
+    private void setStack(Map<String, String> processLoadingMap, List<ApsProcessOperationDo> processOperationDoList, String s, LinkedList<String> stack, String lastProcessId) {
+        //获取该工序详情
+        ApsProcessOperationDo processOperationDo = processOperationDoList.stream().filter(item -> item.getId().equals(s)).findFirst().orElse(null);
+
+        if (ObjectUtil.isEmpty(processOperationDo)) {
+            setMap(s, processLoadingMap, stack, lastProcessId);
+        }
+
+        //组装赋值,先进后出
+        String processname = processOperationDo.getProcessname();
+        Integer reportroll = processOperationDo.getReportroll();
+        Integer planprocessrall = processOperationDo.getPlanprocessrall();
+        stack.push(processname + "(" + reportroll + "/" + planprocessrall + ")");
+
+        //如果前道工序为空,表示结束
+        if (ObjectUtil.isEmpty(processOperationDo.getPreviousprocessid())) {
+            setMap(s, processLoadingMap, stack, lastProcessId);
+        } else {//不为空,继续迭代
+            setStack(processLoadingMap, processOperationDoList, processOperationDo.getPreviousprocessid(), stack, lastProcessId);
+        }
+    }
+
+
+    //赋值map
+    private void setMap(String s, Map<String, String> processLoadingMap, LinkedList<String> stack, String lastProcessId) {
+        //判断栈中 是否为空,如果为空,则赋值空字符串
+        if (stack.size() <= 0) {
+            processLoadingMap.put(s, "");
+        } else {//否则,顺序取出并拼接字符串
+            String processLoading = String.join("-", stack);
+            processLoadingMap.put(lastProcessId, processLoading);
+        }
+    }
 }

+ 61 - 0
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsBlankOrderDao.xml

@@ -221,4 +221,65 @@
             ) a
         where a.rn_asc=1 or a.rn_desc=1 order by a.PLANENDDATE
     </select>
+    <select id="selectPageReport" resultType="com.rongwei.bsentity.vo.ProductPlanReportVo">
+        SELECT a.* from (SELECT
+            apo.*,
+            abo.PROMISEDATESTART AS 'promiseDateStart',
+            abo.PROMISEDATEEND AS 'promiseDateEnd',
+            abo.BLANKNUMBER AS 'blankNumber',
+            apop.OUTPUTRESULT AS 'outPutResult',
+            CONCAT(abo.INPUTREPORTDESCRIBE,' ',CAST(abo.SINGLEROLLWEIGHT AS CHAR) + 0,'吨*',abo.ROLLNUM,'卷') AS 'planBlank',
+            '' AS 'processWorkShop',
+            null AS 'planChangeBlankDate',
+            null AS 'actualChangeBlankDate',
+            '' AS 'hadStartRoll',
+            b.ID AS 'lastProcessId',
+            '' AS 'productLoading',
+            IF(abo.PRODUCTSTATUS = '30','待开工',IF(b.PROCESSSTATUS = '50','已完工','加工中')) AS 'productionOrderStatus',
+            b.PRODOUTROLL AS 'prodOutRoll',
+            null AS 'planStartDate',
+            null AS 'planEndDate',
+            null AS 'actualStartDate',
+            null AS 'actualEndDate',
+            abo.REMARK AS 'blankRemark',
+            abo.ID AS 'blankId'
+            
+        FROM
+            aps_production_order apo
+            LEFT JOIN aps_blank_order abo ON abo.DELETED = 0 
+            AND apo.ID = abo.PRODUCTIONORDERID
+            LEFT JOIN aps_process_output_product apop ON apop.DELETED = 0 
+            AND abo.ID = apop.BLANKID
+            LEFT JOIN (select apo1.ID,apo1.BLANKID,apo1.PROCESSSTATUS,apoom.OUTPUTFINISHPRODUCT,apoom.PRODOUTROLL from aps_process_operation apo1 LEFT JOIN aps_process_operation_out_mater apoom ON apoom.DELETED = 0 AND apoom.OUTPUTFINISHPRODUCT != '' AND apoom.OUTPUTFINISHPRODUCT is not null AND apo1.ID = apoom.MAINID WHERE apo1.DELETED = 0 AND apoom.OUTPUTFINISHPRODUCT != '' AND apoom.OUTPUTFINISHPRODUCT is not null) b 
+            ON b.OUTPUTFINISHPRODUCT = apop.OUTPUTRESULT AND b.BLANKID = apop.BLANKID
+        WHERE 
+            apo.DELETED = 0
+            AND apop.ID is not null
+            AND abo.PRODUCTSTATUS > 20
+            <if test="param.customName != ''">
+                AND apo.CUSTOMNAME like concat('%',#{param.customName},'%')
+            </if>
+            <if test="param.customOrderNo != ''">
+                AND apo.CUSTOMORDERNO like concat('%',#{param.customOrderNo},'%')
+            </if>
+            <if test="param.startDate != '' and param.endDate != ''">
+                AND abo.PROMISEDATESTART >= #{param.startDate} AND abo.PROMISEDATESTART &lt;= #{param.endDate}
+            </if>
+            <if test="param.blankNumber != ''">
+                AND abo.BLANKNUMBER like concat('%',#{param.blankNumber},'%')
+            </if>
+
+            )a
+        <where>
+            <if test="param.productionOrderStatus != ''">
+                AND a.productionOrderStatus = #{param.productionOrderStatus}
+            </if>
+        </where>
+
+        ORDER BY
+            <if test="param.orders != ''">
+                ${param.orders}
+            </if>
+            a.promiseDateStart, a.CUSTOMORDERNO, a.outPutResult
+    </select>
 </mapper>

+ 18 - 0
cx-aps/cx-aps-common/src/main/resources/mybatis/ApsProductionOrderDao.xml

@@ -223,4 +223,22 @@
         )
         and SCHEDULEDELIVERYDATE>PROMISEDELIVERYDATE
     </select>
+    <select id="getWorkShopByBlankId" resultType="com.rongwei.bsentity.vo.BlankIdAndWorkShopVo">
+        SELECT
+            apo.BLANKID AS 'blankId',
+            GROUP_CONCAT( apope.PROCESSWORKSHOP ) AS 'prcessWorkShop'
+        FROM
+            aps_process_operation apo
+            LEFT JOIN aps_process_operation_process_equ apope ON apope.DELETED = 0
+            AND apo.ID = apope.PROCESSID
+        WHERE
+            apo.DELETED = 0
+            AND apo.IFBLANKPROCESS = '是'
+            AND apo.BLANKID IN
+            <foreach collection="blankIdList" item="item" open="(" close=")" separator=",">
+                #{item}
+            </foreach>
+        GROUP BY
+            apo.BLANKID
+    </select>
 </mapper>

+ 14 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/BlankIdAndWorkShopVo.java

@@ -0,0 +1,14 @@
+package com.rongwei.bsentity.vo;
+
+import lombok.Data;
+
+/**
+ * @author :sc
+ * @since :2024/8/27
+ */
+@Data
+public class BlankIdAndWorkShopVo {
+    private String blankId;
+
+    private String prcessWorkShop;
+}

+ 20 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/ProductPlanReportParamVo.java

@@ -0,0 +1,20 @@
+package com.rongwei.bsentity.vo;
+
+import lombok.Data;
+
+/**
+ * @author :sc
+ * @since :2024/8/27
+ */
+@Data
+public class ProductPlanReportParamVo {
+    private String customName = "";
+    private String customOrderNo = "";
+    private String startDate = "";
+    private String endDate = "";
+    private String blankNumber = "";
+
+    private String productionOrderStatus = "";
+
+    private String orders = "";
+}

+ 72 - 0
cx-aps/cx-aps-entity/src/main/java/com/rongwei/bsentity/vo/ProductPlanReportVo.java

@@ -0,0 +1,72 @@
+package com.rongwei.bsentity.vo;
+
+import com.rongwei.bsentity.domain.ApsProductionOrderDo;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author :sc
+ * @since :2024/8/27
+ */
+@Data
+public class ProductPlanReportVo extends ApsProductionOrderDo {
+
+    //期望交货日期-起
+    private String promiseDateStart;
+
+    //期望交货日期-止
+    private String promiseDateEnd;
+
+    //坯料计划编号
+    private String blankNumber;
+
+    //输出订单产品
+    private String outPutResult;
+
+    //计划坯料
+    private String planBlank;
+
+    //计划坯料加工车间
+    private String processWorkShop;
+
+    //计划转料日期
+    private Date planChangeBlankDate = null;
+
+    //实际转料日期
+    private Date actualChangeBlankDate = null;
+
+    //已投料数量
+    private Integer hadStartRoll;
+
+    //输出成品对应最后一个工序作业的ID
+    private String lastProcessId;
+
+    //生产进度
+    private String productLoading;
+
+    //订单产品生产状态
+    private String productionOrderStatus;
+
+    //已完成数量
+    private String prodOutRoll;
+
+    //计划开工时间
+    private Date planStartDate = null;
+
+    //计划完工时间
+    private Date planEndDate = null;
+
+    //实际开工时间
+    private Date actualStartDate = null;
+
+    //实际完工时间
+    private Date actualEndDate = null;
+
+    //备注
+    private String blankRemark;
+
+
+    //坯料计划ID
+    private String blankId;
+}

+ 10 - 0
cx-aps/cx-aps-server/src/main/java/com/rongwei/bsserver/controller/ApsBlankOrderController.java

@@ -7,6 +7,7 @@ import com.rongwei.bsentity.domain.ApsBlankOrderDo;
 import com.rongwei.bsentity.domain.ApsProductionTechnicalRequirementDo;
 import com.rongwei.bsentity.vo.*;
 import com.rongwei.rwcommon.base.R;
+import com.rongwei.rwcommon.vo.CriteriaQuery;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -190,5 +191,14 @@ public class ApsBlankOrderController {
         log.info("checkSchedule 检查排程相关提醒,入参为:{}", req);
         return apsBlankOrderService.checkSchedule(req);
     }
+
+    /**
+     * 生产计划跟踪报表
+     */
+    @PostMapping("/productPlanReport")
+    public R productPlanReport(@RequestBody CriteriaQuery req){
+        log.info("生产计划跟踪报表,入参为:{}", req);
+        return apsBlankOrderService.productPlanReport(req);
+    }
 }