zhuo
2025-05-20 61f34419e094f2363276d614a960b379cc456482
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java
@@ -10,24 +10,25 @@
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
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.ruoyi.basic.mapper.IfsInventoryQuantityMapper;
import com.ruoyi.basic.mapper.StandardProductListMapper;
import com.ruoyi.basic.mapper.StructureItemParameterMapper;
import com.ruoyi.basic.pojo.IfsInventoryQuantity;
import com.ruoyi.basic.pojo.StandardProductList;
import com.ruoyi.basic.pojo.StructureItemParameter;
import com.ruoyi.basic.pojo.StructureTestObject;
import com.ruoyi.common.constant.InsOrderTypeConstants;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.numgen.NumberGenerator;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.api.IfsApiUtils;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.inspect.dto.*;
import com.ruoyi.inspect.mapper.*;
@@ -37,11 +38,6 @@
import com.ruoyi.inspect.service.InsProductService;
import com.ruoyi.inspect.service.InsSampleService;
import com.ruoyi.inspect.vo.InsOrderPrintingVo;
import com.ruoyi.inspect.vo.SampleDefectsFatherVo;
import com.ruoyi.performance.pojo.AuxiliaryOutputWorkingHours;
import com.ruoyi.performance.pojo.AuxiliaryOutputWorkingHoursTemporary;
import com.ruoyi.performance.service.AuxiliaryOutputWorkingHoursTemporaryService;
import com.ruoyi.system.mapper.CustomMapper;
import com.ruoyi.system.mapper.UserMapper;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
@@ -87,14 +83,13 @@
    private IfsApiUtils ifsApiUtils;
    private SpotCheckQuarterItemMapper spotCheckQuarterItemMapper;
    private StandardProductListMapper standardProductListMapper;
    private AuxiliaryOutputWorkingHoursTemporaryService auxiliaryOutputWorkingHoursTemporaryService;
    private StructureItemParameterMapper structureItemParameterMapper;
    //获取检验下单数据
    @Override
    public IPage<SampleOrderDto> selectInsOrderParameter(IPage<InsOrder> page, SampleOrderDto sampleOrderDto) {
        //todo: 只看我判断全部,个人,组织的权限
        String laboratory = null;
        // 判断是否是全部
        String isOrderAll = null;
@@ -160,43 +155,9 @@
            spotCheckQuarterItemMapper.updateById(spotCheckQuarterItem);
        }
        // 创建工时暂存
        // 缓存样品id, 编号map
        Map<Integer, String> sampleMap = insSamples.stream().collect(Collectors.toMap(InsSample::getId, InsSample::getSampleCode));
        List<InsProduct> insProductList = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                .in(InsProduct::getInsSampleId, ids)
                .eq(InsProduct::getState, 1));
        List<AuxiliaryOutputWorkingHoursTemporary> outputWorkingHours = insProductList.stream().map(insProduct -> {
            AuxiliaryOutputWorkingHoursTemporary auxiliaryOutputWorkingHours = new AuxiliaryOutputWorkingHoursTemporary();
            auxiliaryOutputWorkingHours.setInspectionItemClass(insProduct.getInspectionItemClass());//检测项分类
            auxiliaryOutputWorkingHours.setInspectionItem(insProduct.getInspectionItem());//检测父项
            auxiliaryOutputWorkingHours.setInspectionItemSubclass(insProduct.getInspectionItemSubclass());//检测子项
            auxiliaryOutputWorkingHours.setSample(sampleMap.get(insProduct.getInsSampleId()));//样品编号
            auxiliaryOutputWorkingHours.setOrderId(order.getId());//订单id
            auxiliaryOutputWorkingHours.setOrderNo(order.getEntrustCode());//非加班委托单号
            auxiliaryOutputWorkingHours.setWorkTime(insProduct.getManHour());//非加班工时
            auxiliaryOutputWorkingHours.setAmount(1);//非加班数量
            auxiliaryOutputWorkingHours.setOutputWorkTime((ObjectUtils.isNotEmpty(auxiliaryOutputWorkingHours.getOvertimeWorkTime()) ? auxiliaryOutputWorkingHours.getOvertimeWorkTime() : BigDecimal.ZERO).add(ObjectUtils.isNotEmpty(auxiliaryOutputWorkingHours.getWorkTime()) ? auxiliaryOutputWorkingHours.getWorkTime() : BigDecimal.ZERO));//产量工时
            auxiliaryOutputWorkingHours.setManHourGroup(insProduct.getManHourGroup());//工时分组
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            DateTimeFormatter formatters = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            auxiliaryOutputWorkingHours.setDateTime(LocalDateTime.now().toLocalDate().atStartOfDay().format(formatters));//日期
            LocalDateTime localDateTime = LocalDateTime.now();
            DateTime parse = DateUtil.parse(localDateTime.format(formatter));
            auxiliaryOutputWorkingHours.setWeekDay(getWeek(localDateTime.format(formatters)));//星期
            auxiliaryOutputWorkingHours.setWeek(String.valueOf(DateUtil.weekOfYear(DateUtil.offsetDay(parse, 1))));//周次
            auxiliaryOutputWorkingHours.setCheck(userId);//检测人
            auxiliaryOutputWorkingHours.setPrice(insProduct.getPrice());//单价
            auxiliaryOutputWorkingHours.setSampleId(insProduct.getInsSampleId());//样品id
            auxiliaryOutputWorkingHours.setInsProductId(insProduct.getId());//检验项id
            return auxiliaryOutputWorkingHours;
        }).collect(Collectors.toList());
        auxiliaryOutputWorkingHoursTemporaryService.saveBatch(outputWorkingHours);
        return 1;
    }
    public static String getWeek(String dayStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -232,6 +193,19 @@
            default:
                return "未知";
        }
    }
    // 如果你使用 Java 8+,也可以用 Stream API 简化代码:
    public List<StandardProductList> findMissingItemsWithStream(List<StandardProductList> standardList,
                                                                List<InsProduct> insList) {
        Set<Integer> insIds = insList.stream()
                .map(InsProduct::getStructureItemParameterId)
                .collect(Collectors.toSet());
        return standardList.stream()
                .filter(product -> !insIds.contains(product.getStructureItemParameterId()))
                .collect(Collectors.toList());
    }
    @Override
@@ -442,6 +416,9 @@
                if (StringUtils.isBlank(product.getAsk()) || StringUtils.isBlank(product.getTell())) {
                    throw new ErrorException("有检验项的要求值或要求描述为空, 请先去标准库配置要求值或要求描述");
                }
                if (StringUtils.isBlank(product.getSonLaboratory())) {
                    throw new ErrorException("有检验项的的子实验室为绑定, 请先绑定子实验室");
                }
                insProductMapper.insert(product);
            }
        }
@@ -493,7 +470,7 @@
            }
            // 生成编号
            String no = numberGenerator.generateNumberWithPrefix(3,
                    "JCZX/ZB-" + code + LimsDateUtil.resetDate(LocalDateTime.now()),
                    "JCZX/NS-" + code + LimsDateUtil.resetDate(LocalDateTime.now()),
                    InsOrder::getEntrustCode);
            // 判断是否是季度检验, 是季度检验取消原材料季度检验下单
            if (InsOrderTypeConstants.QUARTERLY_TEST.equals(order.getOrderType())) {
@@ -557,112 +534,12 @@
        return productDto2IPage;
    }
    @Override
    public IPage<CostStatisticsDto> costStatistics(IPage<CostStatisticsDto> page, CostStatisticsDto costStatisticsDto) {
        String dates = costStatisticsDto.getDates();
        String[] split = dates.replaceAll("\\[", "").replaceAll("]", "").replaceAll("\"", "").split(",");
        costStatisticsDto.setDates(null);
        //todo:仅看自己
        IPage<CostStatisticsDto> dtoIPage = insOrderMapper.selectCostStatistics(page, QueryWrappers.queryWrappers(costStatisticsDto).ge("create_time", split[0]).le("create_time", split[1] + " 23:59:59"));
        List<CostStatisticsDto> collect = dtoIPage.getRecords().stream().map(dto -> {
            Set<String> uniqueTags = new HashSet<>();
            if (dto.getInspectionItem().contains(",")) {
                for (String s : dto.getInspectionItem().split(",")) {
                    uniqueTags.add(s.split("@")[0]);
                }
            } else {
                uniqueTags.add(dto.getInspectionItem().split("@")[0]);
            }
            dto.setInspectionItem(uniqueTags.toString());
            return dto;
        }).collect(Collectors.toList());
        dtoIPage.setRecords(collect);
        return dtoIPage;
    }
    @Override
    public Map<String, Object> costStatistics2(CostStatisticsDto costStatisticsDto) {
        Map<String, Object> map = new HashMap<>();
        String dates = costStatisticsDto.getDates();
        String[] split = dates.replaceAll("\\[", "").replaceAll("]", "").replaceAll("\"", "").split(",");
        costStatisticsDto.setDates(null);
        List<CostStatisticsDto> costStatisticsDtos = insOrderMapper.selectCostStatistics2(QueryWrappers.queryWrappers(costStatisticsDto).ge("create_time", split[0]).le("create_time", split[1] + " 23:59:59"));
        double totalPrice = costStatisticsDtos.stream()
                .filter(dto -> dto.getPrice() != null) // 过滤掉价格为 null 的对象
                .mapToDouble(value -> value.getPrice().doubleValue() * value.getNum())
                .sum();
        map.put("total", totalPrice);
        return map;
    }
    @Override
    public Map<String, Object> selectSampleDefects(Page page, String inspectionItems, String orderNumber) {
        List<SampleDefectsFatherVo> sampleDefectsFatherVos = insOrderMapper.selectSampleDefects(page, inspectionItems, orderNumber);
        Map<String, Object> map = new HashMap<>();
        map.put("records", sampleDefectsFatherVos);
        Long aLong = insOrderMapper.getCount(inspectionItems, orderNumber);
        map.put("total", aLong);
        return map;
    }
    @Override
    public int updateStatus(Integer id) {
        return insOrderMapper.updateStatus(id);
    }
    @Override
    public void export(CostStatisticsDto costStatisticsDto, HttpServletResponse response) throws IOException {
        //查询导出的费用统计数据
        String dates = costStatisticsDto.getDates();
        String[] split = dates.replaceAll("\\[", "").replaceAll("]", "").replaceAll("\"", "").split(",");
        costStatisticsDto.setDates(null);
        List<CostStatisticsDto> costStatisticsDtos = insOrderMapper.selectCostStatistics2(QueryWrappers.queryWrappers(costStatisticsDto).ge("create_time", split[0]).le("create_time", split[1] + " 23:59:59"));
        costStatisticsDtos = costStatisticsDtos.stream().map(dto -> {
            Set<String> uniqueTags = new HashSet<>();
            if (dto.getInspectionItem().contains(",")) {
                for (String s : dto.getInspectionItem().split(",")) {
                    uniqueTags.add(s.split("@")[0]);
                }
            } else {
                uniqueTags.add(dto.getInspectionItem().split("@")[0]);
            }
            dto.setInspectionItem(uniqueTags.toString());
            return dto;
        }).collect(Collectors.toList());
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("UTF-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("样品费用统计导出", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        Map<String, List<CostStatisticsDto>> groupByCompany =
                costStatisticsDtos.stream().filter(e -> StrUtil.isNotEmpty(e.getCompany()))
                        .collect(Collectors.groupingBy(CostStatisticsDto::getCompany));
        try {
            // 新建ExcelWriter
            // 新建ExcelWriter
            ExcelWriter excelWriter =
                    EasyExcel.write(response.getOutputStream())
                            .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                            .build();
            for (Map.Entry<String, List<CostStatisticsDto>> companyDataEntry : groupByCompany.entrySet()) {
                String sheetName = companyDataEntry.getKey();
                List<CostStatisticsDto> dataList = companyDataEntry.getValue();
                WriteSheet mainSheet = EasyExcel.writerSheet(sheetName)
                        .head(CostStatisticsDto.class)
                        .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                        .build();
                excelWriter.write(dataList, mainSheet);
            }
            // 关闭流
            excelWriter.finish();
        } catch (IOException e) {
            throw new RuntimeException("导出失败");
        }
    }
    /**
     * 获取ifs库存信息
@@ -746,7 +623,7 @@
            ifsInventoryQuantity.setIsSource(1);
            ifsInventoryQuantity.setState(0);
            IfsInventoryQuantity one = ifsInventoryQuantityMapper.selectOne(new LambdaQueryWrapper<IfsInventoryQuantity>()
            Long count = ifsInventoryQuantityMapper.selectCount(new LambdaQueryWrapper<IfsInventoryQuantity>()
                    .eq(IfsInventoryQuantity::getOrderNo, ifsInventoryQuantity.getOrderNo())
                    .eq(IfsInventoryQuantity::getLineNo, ifsInventoryQuantity.getLineNo())
                    .eq(IfsInventoryQuantity::getReleaseNo, ifsInventoryQuantity.getReleaseNo())
@@ -758,8 +635,7 @@
                    .eq(IfsInventoryQuantity::getWaivDevRejNo, ifsInventoryQuantity.getWaivDevRejNo())
                    .eq(IfsInventoryQuantity::getActivitySeq, ifsInventoryQuantity.getActivitySeq())
            );
            if(Objects.isNull(one)) {
            if(count == 0) {
                ifsInventoryQuantity.setIsFirst(0);
                // 查询产业链检测数据
                String industryChainAttrFields = IndustryChainUtils.getIndustryChainAttrFields(ifsInventoryQuantity.getOrderNo(),
@@ -999,6 +875,10 @@
        // 修改检验项
        for (SampleProductDto sampleProductDto : insOrderUpdateDto.getSampleProduct()) {
            insSampleService.update(Wrappers.<InsSample>lambdaUpdate()
                    .eq(InsSample::getId, sampleProductDto.getId())
                    .set(InsSample::getSpecialStandardMethod, sampleProductDto.getSpecialStandardMethod()));
            insProductService.updateBatchById(sampleProductDto.getInsProduct());
        }
@@ -1034,7 +914,8 @@
        // 查询标准树
        List<StandardProductList> standardProductLists = standardProductListMapper.selectList(Wrappers.<StandardProductList>lambdaQuery()
                .eq(StandardProductList::getStandardMethodListId, insProduct.getStandardMethodListId())
                .eq(StandardProductList::getTree, tree));
                .eq(StandardProductList::getTree, tree)
                .orderByAsc(StandardProductList::getSort));
        for (StandardProductList standardProductList : standardProductLists) {
            standardProductList.setId(null);
        }
@@ -1059,6 +940,7 @@
                product.setCreateUser(null);
                product.setUpdateTime(null);
                product.setUpdateUser(null);
                product.setSection(null);
                product.setInsSampleId(omitOrderProductDto.getInsSampleId());
                if (StringUtils.isBlank(product.getCableTag())) {
                    product.setCableTag(null);
@@ -1083,16 +965,21 @@
     */
    @Override
    public void rawAllInsOrderExport(SampleOrderDto sampleOrderDto, HttpServletResponse response) {
        //判断全部,个人,组织的权限
        //todo:仅看我获取当前人所属实验室id
        String laboratory = null;
        // 判断是否是全部
        String isOrderAll = null;
        if (sampleOrderDto.getState() != null && sampleOrderDto.getState() == -2) {
            isOrderAll = "1";
            sampleOrderDto.setState(null);
        List<SampleOrderDto> sampleOrderDtoList = new ArrayList<>();
        if (StringUtils.isNotBlank(sampleOrderDto.getIds())) {
            List<String> orderIds = StrUtil.split(sampleOrderDto.getIds(), ",");
            sampleOrderDtoList = insOrderMapper.getInsOrderExportByIds(orderIds);
        } else {
            String laboratory = null;
            // 判断是否是全部
            String isOrderAll = null;
            if (sampleOrderDto.getState() != null && sampleOrderDto.getState() == -2) {
                isOrderAll = "1";
                sampleOrderDto.setState(null);
            }
            sampleOrderDto.setIds(null);
            sampleOrderDtoList = insOrderMapper.rawAllInsOrderExport(QueryWrappers.queryWrappers(sampleOrderDto), laboratory, isOrderAll);
        }
        List<SampleOrderDto> sampleOrderDtoList = insOrderMapper.rawAllInsOrderExport(QueryWrappers.queryWrappers(sampleOrderDto), laboratory, isOrderAll);
        // 判断是否是不合格, 不合格查询不合格项
        for (SampleOrderDto orderDto : sampleOrderDtoList) {
@@ -1125,6 +1012,140 @@
        }
    }
    /**
     * 修改样品型号
     * @param insSample
     */
    @Override
    public void updateSampleModel(InsSample insSample) {
        // 判断当前订单是否生成了报告, 生成了报告不能修改单号
        Long count = insReportMapper.selectCount(Wrappers.<InsReport>lambdaQuery()
                .eq(InsReport::getInsOrderId, insSample.getInsOrderId()));
        if (count > 0 ) {
            throw new ErrorException("当前订单已经生成了报告不能修改编号");
        }
        insSampleService.update(Wrappers.<InsSample>lambdaUpdate()
                .eq(InsSample::getId, insSample.getId())
                .set(InsSample::getModel, insSample.getModel()));
    }
    /**
     * 查询当前时间是否没有该检测项的抽样计划
     * @param sampleList
     * @param insOrder
     * @return
     */
    @Override
    public Result judgeNotSpotCheckOrder(List<SampleProductDto> sampleList, InsOrder insOrder) {
        // todo: 下单判断抽样计划的唯一性
        if (insOrder.getQuarterItemId() != null) {
            Long quarterItemCount = insOrderMapper.selectCount(Wrappers.<InsOrder>lambdaQuery()
                    .eq(InsOrder::getQuarterItemId, insOrder.getQuarterItemId())
                    .notIn(InsOrder::getState, -1 ,2 ,3));
            if (quarterItemCount > 0) {
                throw new ErrorException("该抽样计划已被绑定过");
            }
        }
        // 判断是否是抽样检测
        if (insOrder.getOrderType().equals(InsOrderTypeConstants.SPOT_CHECK)) {
            Set<String> monthMessageSet = new HashSet<>();
            Set<String> quarterMessageSet = new HashSet<>();
            Set<String> yearMessageSet = new HashSet<>();
            String formatTime = "yyyy-MM-dd HH:mm:ss";
            // 查询当前所有样品的检验项
            for (SampleProductDto sampleProductDto : sampleList) {
                List<StandardProductList> standardProductList = getProductTreeBySampleId(sampleProductDto.getId());
                Set<Integer> insIds = sampleProductDto.getInsProduct().stream()
                        .map(InsProduct::getStructureItemParameterId)
                        .collect(Collectors.toSet());
                List<StandardProductList> productLists = standardProductList.stream()
                        .filter(product -> !insIds.contains(product.getStructureItemParameterId()))
                        .collect(Collectors.toList());
                // 查询检验项基础表, 查询是否有月度, 季度, 年度的检验项
                List<StructureItemParameter> itemParameterList = structureItemParameterMapper.selectList(Wrappers.<StructureItemParameter>lambdaQuery()
                        .in(StructureItemParameter::getId, productLists.stream().map(StandardProductList::getStructureItemParameterId).collect(Collectors.toList())));
                for (StructureItemParameter item : itemParameterList) {
                    if (StringUtils.isNotBlank(item.getSpotCheckType())) {
                        switch (item.getSpotCheckType()) {
                            case "1": // 月度
                                // 查询当月是否有该检测项的抽样计划
                                // 当月开始时间
                                DateTime monthStart = DateUtil.beginOfMonth(DateUtil.date());
                                String monthStartTime = monthStart.toString(formatTime);
                                // 当月结束时间
                                DateTime monthEnd = DateUtil.endOfMonth(DateUtil.date());
                                String monthEndTime = monthEnd.toString(formatTime);
                                Integer count = insOrderMapper.selectNotSpotCheckOrder(item.getId(), monthStartTime, monthEndTime);
                                if (count == 0) {
                                    String monthMessage = item.getInspectionItemClass() +
                                            item.getInspectionItem() +
                                            item.getInspectionItemSubclass();
                                    monthMessageSet.add(monthMessage);
                                }
                                break;
                            case "2": // 季度
                                DateTime quarterStart = DateUtil.beginOfQuarter(DateUtil.date());
                                String quarterStartTime = quarterStart.toString(formatTime);
                                // 当月结束时间
                                DateTime quarterEnd = DateUtil.endOfQuarter(DateUtil.date());
                                String quarterEndTime = quarterEnd.toString(formatTime);
                                Integer quarterCount = insOrderMapper.selectNotSpotCheckOrder(item.getId(), quarterStartTime, quarterEndTime);
                                if (quarterCount == 0) {
                                    String quarterMessage = item.getInspectionItemClass() +
                                            item.getInspectionItem() +
                                            item.getInspectionItemSubclass();
                                    quarterMessageSet.add(quarterMessage);
                                }
                                break;
                            case "3": // 年度
                                DateTime yearStart = DateUtil.beginOfQuarter(DateUtil.date());
                                String yearStartTime = yearStart.toString(formatTime);
                                // 当月结束时间
                                DateTime yearEnd = DateUtil.endOfQuarter(DateUtil.date());
                                String yearEndTime = yearEnd.toString(formatTime);
                                Integer yearCount = insOrderMapper.selectNotSpotCheckOrder(item.getId(), yearStartTime, yearEndTime);
                                if (yearCount == 0) {
                                    String yearMessage = item.getInspectionItemClass() +
                                            item.getInspectionItem() +
                                            item.getInspectionItemSubclass();
                                    yearMessageSet.add(yearMessage);
                                }
                                break;
                        }
                    }
                }
            }
            String message = "";
            if (CollectionUtils.isNotEmpty(monthMessageSet)) {
                message += StrUtil.format("<p>检验项<span style=\"color: red\">{}</span>当月还未进行抽样检测, 请查看是否需要添加当前检验项</p>", CollUtil.join(monthMessageSet, ", "));
            }
            if (CollectionUtils.isNotEmpty(quarterMessageSet)) {
                message += StrUtil.format("<p>检验项<span style=\"color: red\">{}</span>当前季度还未进行抽样检测, 请看是否需要添加当前检验项</p>", CollUtil.join(quarterMessageSet, ", "));
            }
            if (CollectionUtils.isNotEmpty(yearMessageSet)) {
                message += StrUtil.format("<p>检验项<span style=\"color: red\">{}</span>今年还未进行抽样检测, 请看是否需要添加当前检验项</p>", CollUtil.join(yearMessageSet, ", "));
            }
            if (StringUtils.isNotBlank(message)) {
                return Result.success(false, message);
            }
        }
        return Result.success(true);
    }
}