liyong
6 天以前 f5ee8e7afb178179c1d1d078cf42fe33dc7607f9
Merge remote-tracking branch 'origin/dev_New_pro' into dev_New_pro

# Conflicts:
# src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
已修改14个文件
271 ■■■■ 文件已修改
src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java 79 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInRecordMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockOutRecordMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/销售台账导入模板.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionBomStructureServiceImpl.java
@@ -291,8 +291,15 @@
                                            ProductionOrderBom orderBom,
                                            List<ProductionBomStructure> structureList,
                                            Long rootProductModelId) {
        // é‡æ–°æŸ¥è¯¢BOM结构,按子节点优先排序
        List<ProductionBomStructure> routingStructureList = this.list(
                Wrappers.<ProductionBomStructure>lambdaQuery()
                        .eq(ProductionBomStructure::getProductionOrderBomId, orderBom.getId())
                        .orderByDesc(ProductionBomStructure::getParentId)
                        .orderByAsc(ProductionBomStructure::getId));
        ProductionOrderRouting orderRouting = getOrCreateOrderRoutingSnapshot(productionOrderId, productionOrder, orderBom, rootProductModelId);
        List<ProductionOrderRoutingOperation> desiredOperationList = buildDesiredRoutingOperationList(structureList, rootProductModelId);
        List<ProductionOrderRoutingOperation> desiredOperationList = buildDesiredRoutingOperationList(routingStructureList, rootProductModelId);
        List<ProductionOrderRoutingOperation> existingOperationList = productionOrderRoutingOperationMapper.selectList(
                Wrappers.<ProductionOrderRoutingOperation>lambdaQuery()
                        .eq(ProductionOrderRoutingOperation::getOrderRoutingId, orderRouting.getId())
@@ -310,7 +317,7 @@
            if (matchedOperation == null) {
                matchedOperation = insertRoutingOperationSnapshot(orderRouting.getId(), productionOrderId, desiredOperation);
            } else {
                updateRoutingOperationSnapshotIfNecessary(desiredOperation, orderRouting.getId(), productionOrderId, matchedOperation);
                updateRoutingOperationSnapshotIfNecessary(matchedOperation, orderRouting.getId(), productionOrderId, desiredOperation);
            }
            finalOperationList.add(matchedOperation);
        }
@@ -381,14 +388,14 @@
        Map<Long, ProductionBomStructure> structureById = structureList.stream()
                .filter(item -> item != null && item.getId() != null)
                .collect(Collectors.toMap(ProductionBomStructure::getId, item -> item, (left, right) -> left));
        // æž„建父-子映射关系
        Map<Long, List<ProductionBomStructure>> treeMap = buildParentChildMap(structureList);
        // ä½¿ç”¨åŽåºéåŽ†æž„å»ºæ“ä½œåˆ—è¡¨ï¼ˆå…ˆå­åŽçˆ¶ï¼Œç¡®ä¿å·¥è‰ºè·¯çº¿é¡ºåºæ­£ç¡®ï¼‰
        Map<String, ProductionBomStructure> uniqueOperationMap = new LinkedHashMap<>();
        for (ProductionBomStructure bomStructure : structureList) {
            if (bomStructure == null || bomStructure.getTechnologyOperationId() == null) {
                continue;
            }
            Long outputProductModelId = resolveOutputProductModelId(resolveOperationOutputNode(bomStructure, structureById), rootProductModelId);
            uniqueOperationMap.putIfAbsent(buildBomOperationDedupKey(bomStructure, outputProductModelId), bomStructure);
        }
        buildOperationListPostOrder(null, treeMap, uniqueOperationMap, structureById, rootProductModelId);
        List<ProductionOrderRoutingOperation> desiredOperationList = new ArrayList<>();
        int dragSort = 1;
        for (ProductionBomStructure bomStructure : uniqueOperationMap.values()) {
@@ -405,6 +412,52 @@
            desiredOperationList.add(routingOperation);
        }
        return desiredOperationList;
    }
    private Map<Long, List<ProductionBomStructure>> buildParentChildMap(List<ProductionBomStructure> structureList) {
        Map<Long, List<ProductionBomStructure>> treeMap = new LinkedHashMap<>();
        Map<Long, Integer> childCountMap = new HashMap<>();
        // ç¬¬ä¸€éï¼šç»Ÿè®¡æ¯ä¸ªèŠ‚ç‚¹çš„å­èŠ‚ç‚¹æ•°é‡ï¼ŒåŒæ—¶æž„å»ºåˆå§‹æ˜ å°„
        for (ProductionBomStructure structure : structureList) {
            if (structure == null) continue;
            Long parentId = structure.getParentId();
            childCountMap.merge(parentId, 1, Integer::sum);  // ç»Ÿè®¡æ¯ä¸ªçˆ¶èŠ‚ç‚¹æœ‰å¤šå°‘ä¸ªå­èŠ‚ç‚¹
            treeMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(structure);
        }
        // ç¬¬äºŒéï¼šå¯¹æ¯ä¸ªçˆ¶èŠ‚ç‚¹ä¸‹çš„å­èŠ‚ç‚¹æŒ‰å­èŠ‚ç‚¹æ•°é‡å€’åºæŽ’åºï¼ˆæœ‰å­èŠ‚ç‚¹çš„ä¼˜å…ˆï¼‰
        for (Map.Entry<Long, List<ProductionBomStructure>> entry : treeMap.entrySet()) {
            List<ProductionBomStructure> children = entry.getValue();
            children.sort((a, b) -> {
                int countA = childCountMap.getOrDefault(a.getId(), 0);
                int countB = childCountMap.getOrDefault(b.getId(), 0);
                return Integer.compare(countB, countA);  // å­èŠ‚ç‚¹å¤šçš„æŽ’å‰é¢
            });
        }
        return treeMap;
    }
    private void buildOperationListPostOrder(Long parentId,
                                             Map<Long, List<ProductionBomStructure>> treeMap,
                                             Map<String, ProductionBomStructure> uniqueOperationMap,
                                             Map<Long, ProductionBomStructure> structureById,
                                             Long rootProductModelId) {
        List<ProductionBomStructure> children = treeMap.get(parentId);
        if (children == null || children.isEmpty()) {
            return;
        }
        for (ProductionBomStructure child : children) {
            // å…ˆé€’归处理子节点
            buildOperationListPostOrder(child.getId(), treeMap, uniqueOperationMap, structureById, rootProductModelId);
            // å†å¤„理当前节点
            if (child.getTechnologyOperationId() != null) {
                Long outputProductModelId = resolveOutputProductModelId(resolveOperationOutputNode(child, structureById), rootProductModelId);
                uniqueOperationMap.putIfAbsent(buildBomOperationDedupKey(child, outputProductModelId), child);
            }
        }
    }
    private Map<String, Deque<ProductionOrderRoutingOperation>> buildExistingRoutingOperationBucketMap(List<ProductionOrderRoutingOperation> existingOperationList) {
@@ -482,6 +535,12 @@
        if (!Objects.equals(currentOperation.getIsProduction(), desiredOperation.getIsProduction())) {
            update.setIsProduction(desiredOperation.getIsProduction());
            currentOperation.setIsProduction(desiredOperation.getIsProduction());
            changed = true;
        }
        // æ›´æ–° dragSort å­—段,确保工艺路线顺序正确
        if (!Objects.equals(currentOperation.getDragSort(), desiredOperation.getDragSort())) {
            update.setDragSort(desiredOperation.getDragSort());
            currentOperation.setDragSort(desiredOperation.getDragSort());
            changed = true;
        }
        if (!Objects.equals(currentOperation.getType(), desiredOperation.getType())) {
@@ -744,8 +803,8 @@
            return;
        }
        for (ProductionBomStructureDto node : source) {
            flattenTree(node.getChildren(), result);  // å…ˆé€’归添加子节点
            result.add(node);
            flattenTree(node.getChildren(), result);
        }
    }
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -126,6 +126,7 @@
            String text = inspectParams.stream().map(QualityInspectParam::getParameterItem).collect(Collectors.joining(","));
            qualityUnqualified.setDefectivePhenomena(text + "这些指标中存在不合格");//不合格现象
            qualityUnqualified.setInspectId(qualityInspect.getId());
            qualityUnqualified.setId(null);
            qualityUnqualifiedMapper.insert(qualityUnqualified);
        }
src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java
@@ -43,6 +43,10 @@
    @Excel(name = "签订日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date executionDate;
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "交付日期", width = 30, dateFormat = "yyyy-MM-dd")
    private Date deliveryDate;
    @Schema(description = "付款方式")
    @Excel(name = "付款方式")
    private String paymentMethod;
src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
@@ -73,6 +73,9 @@
    @Excel(name = "是否质检", readConverterExp = "0=否,1=是")
    private Boolean isChecked;
    /**
     * æ˜¯å¦ç”Ÿäº§
     */
    @Excel(name = "是否生产", readConverterExp = "0=否,1=是")
    private Integer isProduction;
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -285,6 +285,9 @@
     * åˆ é™¤ç”Ÿäº§è®¡åˆ’
     */
    public void deleteProductionData(List<Long> productIds) {
        if (CollectionUtils.isEmpty(productIds)) {
            return;
        }
        List<ProductionPlan> productionPlans = productionPlanMapper.selectList(
                new LambdaQueryWrapper<ProductionPlan>()
                        .in(ProductionPlan::getSalesLedgerProductId, productIds.stream().map(Long::intValue).collect(Collectors.toList())));
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -27,8 +28,9 @@
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.mapper.ProductionProductInputMapper;
import com.ruoyi.production.mapper.ProductionProductMainMapper;
import com.ruoyi.production.mapper.ProductionProductOutputMapper;
import com.ruoyi.production.service.ProductionProductMainService;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
@@ -44,7 +46,6 @@
import com.ruoyi.sales.vo.SalesLedgerVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -55,15 +56,10 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
@@ -347,9 +343,17 @@
            if (CollectionUtils.isEmpty(salesLedgerImportDtoList)) return R.fail("销售台账数据为空!");
            List<SalesLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("销售产品数据");
            if (CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return R.fail("销售产品数据为空!");
            // å®¢æˆ·æ•°æ®
            List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName,
                    salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).collect(Collectors.toList())));
            // å®¢æˆ·æ•°æ® - å‚考 listPage æŸ¥è¯¢ç§æµ·å®¢æˆ·ï¼ˆtype = 0)
            // type = 0(私海客户)或者 type = 1(公海客户)且已被分配,并且是自己领用、自己创建或者共享给自己的客户
            Long loginUserId = loginUser.getUser().getUserId();
            List<Customer> customers = customerMapper.selectList(new QueryWrapper<Customer>()
                    .in("customer_name", salesLedgerImportDtoList.stream()
                            .map(SalesLedgerImportDto::getCustomerName).collect(Collectors.toList()))
                    .and(wrapper -> wrapper.eq("type", 0)
                            .or(wrapper2 -> wrapper2.eq("type", 1).eq("is_assigned", 1)))
                    .and(wrapper -> wrapper.eq("usage_user", loginUserId)
                            .or(wrapper2 -> wrapper2.eq("create_user", loginUserId)
                                    .or(wrapper3 -> wrapper3.exists("select 1 from customer_user cu where cu.customer_id = customer.id and cu.user_id = " + loginUserId)))));
//            // è§„格型号数据
//            List<ProductModel> productModels = productModelMapper.selectList(new LambdaQueryWrapper<ProductModel>().in(ProductModel::getModel,
//                    salesLedgerProductImportDtoList.stream().map(SalesLedgerImportDto::getSpecificationModel).collect(Collectors.toList())));
@@ -370,17 +374,16 @@
                SalesLedger salesLedger = new SalesLedger();
                BeanUtils.copyProperties(salesLedgerImportDto, salesLedger);
                salesLedger.setExecutionDate(DateUtils.toLocalDate(salesLedgerImportDto.getExecutionDate()));
                salesLedger.setDeliveryDate(DateUtils.toLocalDate(salesLedgerImportDto.getDeliveryDate()));
                // é€šè¿‡å®¢æˆ·åç§°æŸ¥è¯¢å®¢æˆ·ID,客户合同号
                salesLedger.setCustomerId(customers.stream()
                Optional<Customer> customerOptional = customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst()
                        .map(Customer::getId)
                        .orElse(null));
                salesLedger.setCustomerContractNo(customers.stream()
                        .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
                        .findFirst()
                        .map(Customer::getTaxpayerIdentificationNumber)
                        .orElse(null));
                        .findFirst();
                if (customerOptional.isEmpty()) {
                    throw new RuntimeException("客户:" + salesLedger.getCustomerName() + "不存在!或者非私海用户");
                }
                salesLedger.setCustomerId(customerOptional.get().getId());
                salesLedger.setCustomerContractNo(customerOptional.get().getTaxpayerIdentificationNumber());
                Long aLong = sysUsers.stream()
                        .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getEntryPerson()))
                        .findFirst()
@@ -410,13 +413,16 @@
                    salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP));
                    salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
                    salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice());
                    list.stream()
                            .filter(map -> map.get("productName").equals(salesLedgerProduct.getProductCategory()) && map.get("model").equals(salesLedgerProduct.getSpecificationModel()))
                            .findFirst()
                            .ifPresent(map -> {
                                salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString()));
                                salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString()));
                            });
                    // æ ¡éªŒäº§å“è§„格是否存在
                    Optional<Map<String, Object>> productModelOptional = list.stream()
                            .filter(map -> Objects.equals(map.get("productName"), salesLedgerProduct.getProductCategory()) && Objects.equals(map.get("model"), salesLedgerProduct.getSpecificationModel()))
                            .findFirst();
                    if (productModelOptional.isEmpty()) {
                        throw new RuntimeException("产品大类:" + salesLedgerProduct.getProductCategory() + ",规格型号:" + salesLedgerProduct.getSpecificationModel() + "不存在!");
                    }
                    Map<String, Object> productModelMap = productModelOptional.get();
                    salesLedgerProduct.setProductModelId(Long.parseLong(productModelMap.get("modelId").toString()));
                    salesLedgerProduct.setProductId(Long.parseLong(productModelMap.get("id").toString()));
//                    salesLedgerProduct.setProductId(productList.stream()
//                            .filter(product -> product.getProductName().equals(salesLedgerProduct.getProductCategory()))
//                            .findFirst()
@@ -431,6 +437,7 @@
                    salesLedgerProduct.setRegisterDate(LocalDateTime.now());
                    salesLedgerProduct.setApproveStatus(0);
                    salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice());
                    salesLedgerProduct.setIsProduction(salesLedgerProductImportDto.getIsProduction() == 1);
                    salesLedgerProductMapper.insert(salesLedgerProduct);
                    // æ·»åŠ ç”Ÿäº§æ•°æ®
                    salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
@@ -440,6 +447,7 @@
            return R.ok(null, "导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("导入失败:" + e.getMessage());
        }
        return R.ok(null, "导入失败");
    }
src/main/java/com/ruoyi/staff/service/impl/StaffOnJobServiceImpl.java
@@ -1,12 +1,13 @@
package com.ruoyi.staff.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.common.exception.base.BaseException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.dto.WordDateDto;
import com.ruoyi.project.system.domain.SysDept;
@@ -64,7 +65,6 @@
    private final StaffEmergencyContactMapper staffEmergencyContactMapper;
    private final StaffEmergencyContactServiceImpl staffEmergencyContactServiceImpl;
    //在职员工台账分页查询
    @Override
    public IPage<StaffOnJobDto> staffOnJobListPage(Page page, StaffOnJob staffOnJob) {
@@ -77,7 +77,8 @@
    public int add(StaffOnJobDto staffOnJobPrams) {
        String[] ignoreProperties = {"id"};//排除id属性
        // åˆ¤æ–­ç¼–号是否存在
        List<StaffOnJob> staffOnJobs = staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery().eq(StaffOnJob::getStaffNo, staffOnJobPrams.getStaffNo()));
        List<StaffOnJob> staffOnJobs = staffOnJobMapper.selectList(
                Wrappers.<StaffOnJob>lambdaQuery().eq(StaffOnJob::getStaffNo, staffOnJobPrams.getStaffNo()));
        if (staffOnJobs != null && !staffOnJobs.isEmpty()){
            throw new BaseException("编号为"+staffOnJobPrams.getStaffNo()+"的员工已经存在,无法新增!!!");
        }
@@ -147,6 +148,7 @@
    /**
     * ç»‘定员工子表数据
     *
     * @param staffOnJobPrams
     * @param id
     */
@@ -174,9 +176,9 @@
        }
    }
    /**
     * é€šè¿‡å‘˜å·¥id删除教育经历,工作经历,紧急联系人
     *
     * @param ids
     * @return
     */
@@ -184,16 +186,19 @@
        // åˆ é™¤æ•™è‚²ç»åކ
        staffEducationService.remove(Wrappers.<StaffEducation>lambdaQuery().in(StaffEducation::getStaffOnJobId,ids));
        // åˆ é™¤å·¥ä½œç»åކ
        staffWorkExperienceServiceImpl.remove(Wrappers.<StaffWorkExperience>lambdaQuery().in(StaffWorkExperience::getStaffOnJobId,ids));
        staffWorkExperienceServiceImpl
                .remove(Wrappers.<StaffWorkExperience>lambdaQuery().in(StaffWorkExperience::getStaffOnJobId, ids));
        // åˆ é™¤ç´§æ€¥è”系人
        staffEmergencyContactServiceImpl.remove(Wrappers.<StaffEmergencyContact>lambdaQuery().in(StaffEmergencyContact::getStaffOnJobId,ids));
        staffEmergencyContactServiceImpl
                .remove(Wrappers.<StaffEmergencyContact>lambdaQuery().in(StaffEmergencyContact::getStaffOnJobId, ids));
    }
    //删除入职
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delStaffOnJobs(List<Integer> ids) {
        List<StaffOnJob> staffOnJobs = staffOnJobMapper.selectList(Wrappers.<StaffOnJob>lambdaQuery().in(StaffOnJob::getId, ids));
        List<StaffOnJob> staffOnJobs = staffOnJobMapper
                .selectList(Wrappers.<StaffOnJob>lambdaQuery().in(StaffOnJob::getId, ids));
        if(CollectionUtils.isEmpty(staffOnJobs)){
            throw new BaseException("该员工不存在,无法删除!!!");
        }
@@ -202,10 +207,12 @@
        // åˆ é™¤ç¦»èŒæ•°æ®
        staffLeaveMapper.delete(Wrappers.<StaffLeave>lambdaQuery().in(StaffLeave::getStaffOnJobId, ids));
        // åˆ é™¤æ‰“卡记录
        personalAttendanceRecordsMapper.delete(Wrappers.<PersonalAttendanceRecords>lambdaQuery().in(PersonalAttendanceRecords::getStaffOnJobId, ids));
        personalAttendanceRecordsMapper.delete(
                Wrappers.<PersonalAttendanceRecords>lambdaQuery().in(PersonalAttendanceRecords::getStaffOnJobId, ids));
        // åˆ é™¤ç”¨æˆ·æ•°æ®
        List<SysUser> sysUsers = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
                .in(SysUser::getUserName, staffOnJobs.stream().map(StaffOnJob::getStaffNo).collect(Collectors.toList())));
                .in(SysUser::getUserName,
                        staffOnJobs.stream().map(StaffOnJob::getStaffNo).collect(Collectors.toList())));
        if(CollectionUtils.isNotEmpty(sysUsers)){
            Long[] longs = sysUsers.stream().map(SysUser::getUserId).toArray(Long[]::new);
            sysUserService.deleteUserByIds(longs);
@@ -214,7 +221,8 @@
        delStaffOnJobExtra(ids.stream().map(Integer::longValue).collect(Collectors.toList()));
        // åˆ é™¤åˆåŒæ•°æ®
        return staffContractMapper.delete(Wrappers.<StaffContract>lambdaQuery().in(StaffContract::getStaffOnJobId, ids));
        return staffContractMapper
                .delete(Wrappers.<StaffContract>lambdaQuery().in(StaffContract::getStaffOnJobId, ids));
    }
    // ç»­ç­¾åˆåŒ
@@ -272,9 +280,11 @@
        // èŽ·å–å­è¡¨æ•°æ®
        staffOnJobDto.setStaffEducationList(staffEducationMapper.selectList(Wrappers.<StaffEducation>lambdaQuery()
                .eq(StaffEducation::getStaffOnJobId, staffOnJob.getId())));
        staffOnJobDto.setStaffWorkExperienceList(staffWorkExperienceMapper.selectList(Wrappers.<StaffWorkExperience>lambdaQuery()
        staffOnJobDto.setStaffWorkExperienceList(
                staffWorkExperienceMapper.selectList(Wrappers.<StaffWorkExperience>lambdaQuery()
                .eq(StaffWorkExperience::getStaffOnJobId, staffOnJob.getId())));
        staffOnJobDto.setStaffEmergencyContactList(staffEmergencyContactMapper.selectList(Wrappers.<StaffEmergencyContact>lambdaQuery()
        staffOnJobDto.setStaffEmergencyContactList(
                staffEmergencyContactMapper.selectList(Wrappers.<StaffEmergencyContact>lambdaQuery()
                .eq(StaffEmergencyContact::getStaffOnJobId, staffOnJob.getId())));
        return staffOnJobDto;
    }
@@ -302,35 +312,58 @@
                return false;
            }
            // èŽ·å–æ‰€æœ‰éƒ¨é—¨æ•°æ®
            List<SysDept> sysDepts = sysDeptMapper.selectList(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getDelFlag, 0));
            List<SysDept> sysDepts = sysDeptMapper
                    .selectList(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getDelFlag, 0));
            // èŽ·å–æ‰€æœ‰è§’è‰²æ•°æ®
            List<SysRole> sysRoles = sysRoleMapper.selectRoleAll();
            staffOnJobs.forEach(staffOnJob -> {
                // å¤„理合同期限数据格式
                if (staffOnJob.getContractTerm() != null && !staffOnJob.getContractTerm().trim().isEmpty()) {
                    String term = staffOnJob.getContractTerm().trim();
                    try {
                        Integer.parseInt(term);
                    } catch (NumberFormatException e) {
                        throw new ServiceException("员工[" + staffOnJob.getStaffName() + "]的合同期限["
                                + staffOnJob.getContractTerm() + "]格式不正确,必须为纯数字(如: 1, 2, 3)");
                    }
                }
                StaffOnJobDto staffOnJobDto = new StaffOnJobDto();
                BeanUtils.copyProperties(staffOnJob, staffOnJobDto);
                // é€šè¿‡åç§°èŽ·å–éƒ¨é—¨id
                staffOnJobDto.setSysDeptId(// ... existing code ...
                        sysDepts.stream()
                            .filter(dept -> dept.getDeptName() != null && dept.getDeptName().equals(staffOnJob.getSysDeptName()))
                Long deptId = sysDepts.stream()
                        .filter(dept -> dept.getDeptName() != null
                                && dept.getDeptName().equals(staffOnJob.getSysDeptName()))
                            .findFirst()
                            .map(SysDept::getDeptId)
                            .orElse(null)
                        );
                        .orElse(null);
                if (deptId == null) {
                    throw new ServiceException(
                            "员工[" + staffOnJob.getStaffName() + "]的部门[" + staffOnJob.getSysDeptName() + "]不存在,请检查数据");
                }
                staffOnJobDto.setSysDeptId(deptId);
                // é€šè¿‡åç§°èŽ·å–è§’è‰²id
                staffOnJobDto.setRoleId(sysRoles.stream()
                        .filter(role -> role.getRoleName() != null && role.getRoleName().equals(staffOnJob.getRoleName()))
                Long roleId = sysRoles.stream()
                        .filter(role -> role.getRoleName() != null
                                && role.getRoleName().equals(staffOnJob.getRoleName()))
                        .findFirst()
                        .map(SysRole::getRoleId)
                        .orElse( null));
                add(staffOnJobDto);
                        .orElse(null);
                if (roleId == null) {
                    throw new ServiceException(
                            "员工[" + staffOnJob.getStaffName() + "]的角色[" + staffOnJob.getRoleName() + "]不存在,请检查数据");
                }
                staffOnJobDto.setRoleId(roleId);
                SpringUtils.getAopProxy(this).add(staffOnJobDto);
            });
            return true;
        } catch (ServiceException | BaseException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
            log.error("员工台账导入失败 : " + e.getMessage());
            throw new ServiceException("导入失败: " + e.getMessage());
        }
    }
    @Override
    public String exportCopy(HttpServletResponse response, StaffOnJob staffOnJob) throws Exception {
@@ -410,7 +443,5 @@
        }
        return url;
    }
}
src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java
@@ -18,6 +18,11 @@
     */
    private String model;
    /**
     * æ‰¹æ¬¡å·
     */
    private String batchNo;
    /**
     * äº§å“å•位
     */
    private String unit;
src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
@@ -79,4 +79,7 @@
    @Schema(description = "产品id")
    private Long productId;
    @Schema(description = "批次号")
    private String batchNo;
}
src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java
@@ -21,6 +21,10 @@
     */
    private String model;
    /**
     * æ‰¹æ¬¡å·
     */
    private String batchNo;
    /**
     * äº§å“å•位
     */
    private String unit;
src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -31,6 +31,12 @@
            <if test="params.productName != null and params.productName != ''">
                and p.product_name like concat('%',#{params.productName},'%')
            </if>
            <if test="params.model != null and params.model != ''">
                and pm.model like concat('%',#{params.model},'%')
            </if>
            <if test="params.batchNo != null and params.batchNo != ''">
                and sir.batch_no like concat('%',#{params.batchNo},'%')
            </if>
            <if test="params.type != null and params.type != ''">
                and sir.type = #{params.type}
            </if>
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -209,6 +209,12 @@
            <if test="ew.topParentProductId != null and ew.topParentProductId > 0">
                and combined.product_id in (select id from product_tree)
            </if>
            <if test="ew.model != null and ew.model !=''">
                and combined.model like concat('%',#{ew.model},'%')
            </if>
            <if test="ew.batchNo != null and ew.batchNo !=''">
                and combined.batch_no like concat('%',#{ew.batchNo},'%')
            </if>
        </where>
        group by
        product_model_id,
src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -46,6 +46,12 @@
            <if test="params.productName != null and params.productName != ''">
                and p.product_name like concat('%',#{params.productName},'%')
            </if>
            <if test="params.model != null and params.model != ''">
                and pm.model like concat('%',#{params.model},'%')
            </if>
            <if test="params.batchNo != null and params.batchNo != ''">
                and sor.batch_no like concat('%',#{params.batchNo},'%')
            </if>
            <if test="params.type != null and params.type != ''">
                and sor.type = #{params.type}
            </if>
src/main/resources/static/ÏúÊŲ̂Õ˵¼ÈëÄ£°å.xlsx
Binary files differ