maven
2 天以前 2a9c3934bb093c978a54a1c3e220e6a120855e77
Merge remote-tracking branch 'origin/jtwy' into jtwy
已添加34个文件
已修改62个文件
2737 ■■■■■ 文件已修改
doc/1767778273_add_product_order_id_to_product_work_order.sql 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/create_table_process_route_item.sql 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/SupplierManageFileController.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/mapper/SupplierManageFileMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/Customer.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/SupplierManage.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/SupplierManageFile.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/SupplierManageFileService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/SupplierManageFileServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/controller/DeviceRepairController.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/dto/DeviceAssetInfoDto.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/dto/DeviceRepairDto.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/pojo/DeviceRepair.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/IDeviceLedgerService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementExceptionRecordController.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/InventoryInformationDto.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementExceptionRecordMapper.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementExceptionRecord.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductStructureController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductProcess.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionProductInputService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionProductMainService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/ShipmentApprovalMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/ShipmentApproval.java 352 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/ShipmentApprovalService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShipmentApprovalServiceImpl.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/SupplierManageFileMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/SupplierManageMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/device/DeviceRepairMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementExceptionRecordMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductWorkOrderMapper.xml 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductInputMapper.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductMainMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductOutputMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/ProductRecordMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/quality/QualityInspectMapper.xml 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerMapper.xml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ShipmentApprovalMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/1767778273_add_product_order_id_to_product_work_order.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2 @@
alter table product_work_order
    add product_order_id bigint not null default 0 comment '生产订单id';
doc/create_table_process_route_item.sql
@@ -50,6 +50,10 @@
    create_time      datetime null comment '录入时间',
    update_time      datetime null comment '更新时间',
    work_order_no    varchar(255) not null default '' comment '工单编号',
    plan_start_time  datetime null comment '计划开始时间',
    plan_end_time    datetime null comment '计划结束时间',
    actual_start_time  datetime null comment '实际开始时间',
    actual_end_time    datetime null comment '实际结束时间',
    status           int not null default 0 comment '状态  1 å¾…确认  2 å¾…生产 3生产中 4已生产 ',
    tenant_id        bigint   not null comment '租户id'
);
src/main/java/com/ruoyi/approve/pojo/ApproveProcess.java
@@ -157,7 +157,14 @@
     * åˆ›å»ºæ—¶é—´
     */
    private LocalDateTime createTime;
    /**
     * è®¾å¤‡æŠ¥ä¿®id
     */
    private Long deviceRepairId;
    /**
     * æŠ¥ä¿®é‡‘额
     */
    private BigDecimal maintenancePrice;
    private static final long serialVersionUID = 1L;
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -10,6 +10,8 @@
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
@@ -43,6 +45,9 @@
    @Autowired
    private CommonFileMapper fileMapper;
    @Autowired
    private DeviceRepairMapper deviceRepairMapper;
    public ApproveProcess getApproveById(String id) {
@@ -135,11 +140,21 @@
            approveProcess.setApproveUserCurrentId(approveNode1.getApproveNodeUserId());
            approveProcess.setApproveUserCurrentName(approveNode1.getApproveNodeUser());
        }
        if (approveProcess.getApproveStatus() != 1){
        if(approveProcess.getApproveStatus().equals(2) || approveProcess.getApproveStatus().equals(3) || approveProcess.getApproveStatus().equals(4)){
            approveProcess.setApproveOverTime(new Date());
        }
        approveProcessMapper.updateById(approveProcess);
        DeviceRepair deviceRepair = deviceRepairMapper.selectById(approveProcess.getDeviceRepairId());
        if(deviceRepair == null) throw new RuntimeException("设备报修不存在");
        if(approveProcess.getApproveStatus().equals(2)){
            // åŒæ„
            deviceRepair.setStatus(1);
        }else if(approveProcess.getApproveStatus().equals(3)){
            // æ‹’绝
            deviceRepair.setStatus(2);
        }
        deviceRepairMapper.updateById(deviceRepair);
        // ç»‘定附件
        if(!CollectionUtils.isEmpty(approveNode.getTempFileIds()) && approveNode.getApproveNodeStatus() == 1){
            tempFileService.migrateTempFilesToFormal(approveNode.getId(), approveNode.getTempFileIds(), FileNameType.ApproveNode.getValue());
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -74,16 +74,14 @@
        if(CollectionUtils.isEmpty(sysUsers)) throw new RuntimeException("审核用户不存在");
        if(sysDept == null) throw new RuntimeException("部门不存在");
        if(sysUser == null) throw new RuntimeException("申请人不存在");
//        String today = LocalDate.now().format(DATE_FORMAT);
        String approve_process = OrderUtils.countTodayByCreateTime(approveProcessMapper, "");
//        Long approveId = dailyRedisCounter.incrementAndGetByDb();
//        String formattedCount = String.format("%03d", approveId);
        String today = LocalDate.now().format(DATE_FORMAT);
        Long approveId = dailyRedisCounter.incrementAndGetByDb();
        String formattedCount = String.format("%03d", approveId);
        //流程 ID
//        String approveID = today + formattedCount;
        String approveID = today + formattedCount;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        ApproveProcess approveProcess = new ApproveProcess();
        BeanUtils.copyProperties(approveProcessVO, approveProcess);
        approveProcess.setApproveId(approve_process);
        approveProcess.setApproveId(approveID);
        approveProcess.setApproveUser(approveProcessVO.getApproveUser());
        approveProcess.setApproveUserName(sysUser.getNickName());
        approveProcess.setApproveDeptId(approveProcessVO.getApproveDeptId());
@@ -91,6 +89,8 @@
        approveProcess.setApproveUserNames(sysUsers.stream().map(SysUser::getNickName).collect(Collectors.joining(",")));
        approveProcess.setApproveTime(StringUtils.isEmpty(approveProcessVO.getApproveTime()) ? null : dateFormat.parse(approveProcessVO.getApproveTime()));
        approveProcess.setApproveReason(approveProcessVO.getApproveReason());
        approveProcess.setDeviceRepairId(approveProcessVO.getDeviceRepairId());
        approveProcess.setMaintenancePrice(approveProcessVO.getMaintenancePrice());
        approveProcess.setApproveOverTime(null);
        approveProcess.setApproveStatus(0);
        approveProcess.setApproveDelete(0);
@@ -113,7 +113,7 @@
        }
        save(approveProcess);
        //初始化审批节点
        approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(),approve_process,approveProcessVO.getApproveDeptId());
        approveNodeService.initApproveNodes(approveProcessVO.getApproveUserIds(),approveID,approveProcessVO.getApproveDeptId());
        // é™„件绑定
        tempFileService.migrateTempFilesToFormal(approveProcess.getId(), approveProcessVO.getTempFileIds(), FileNameType.ApproveProcess.getValue());
    }
src/main/java/com/ruoyi/approve/vo/ApproveProcessVO.java
@@ -14,24 +14,37 @@
@Data
public class ApproveProcessVO {
    /**
     * ä¸´æ—¶æ–‡ä»¶id列表
     */
    private List<String> tempFileIds;
    /**
     * å®¡æ‰¹æµç¨‹id
     */
    private Long id;
    private String approveId;
    /**
     * å®¡æ‰¹éƒ¨é—¨id
     */
    private Long approveDeptId;
    private String approveDeptName;
    /**
     * å®¡æ‰¹æ—¶é—´
     */
    private String approveTime;
    /**
     * ç”³è¯·äººid
     */
    // ç”³è¯·äºº
    private Long approveUser;
    /**
     * å®¡æ‰¹äººid列表
     */
    // å®¡æ‰¹äºº
    private String approveUserIds;
    /**
     * å®¡æ‰¹ç†ç”±
     */
    private String approveReason;
    @Excel(name = "开始时间", dateFormat = "yyyy-MM-dd",width = 30)
@@ -54,4 +67,12 @@
     * å®¡æ‰¹ç±»åž‹
     */
    private Integer approveType;
     /**
     * è®¾å¤‡æŠ¥ä¿®id
     */
    private Long deviceRepairId;
     /**
     * æŠ¥ä¿®é‡‘额
     */
    private BigDecimal maintenancePrice;
}
src/main/java/com/ruoyi/basic/controller/SupplierManageFileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.ruoyi.basic.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.pojo.SupplierManageFile;
import com.ruoyi.basic.service.SupplierManageFileService;
import com.ruoyi.framework.web.domain.AjaxResult;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
 * ä¾›åº”商附件
 */
@RestController
@RequestMapping("/basic/supplierManageFile")
public class SupplierManageFileController {
    @Resource
    private SupplierManageFileService supplierManageFileService;
    /**
     * æ–°å¢ž
     * @param supplierManageFile
     * @return
     */
    @PostMapping("/add")
    public AjaxResult add(@RequestBody SupplierManageFile supplierManageFile) {
        return AjaxResult.success(supplierManageFileService.save(supplierManageFile));
    }
    /**
     * åˆ é™¤
     * @param ids
     * @return
     */
    @DeleteMapping("/del")
    public AjaxResult delSupplierManageFile(@RequestBody List<Integer> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return AjaxResult.error("请选择至少一条数据");
        }
        //删除检验附件
        return AjaxResult.success(supplierManageFileService.removeBatchByIds(ids));
    }
    /**
     *分页查询
     * @param page
     * @param supplierManageFile
     * @return
     */
    @GetMapping("/listPage")
    public AjaxResult supplierManageFileListPage(Page page, SupplierManageFile supplierManageFile) {
        return AjaxResult.success(supplierManageFileService.supplierManageFileListPage(page, supplierManageFile));
    }
}
src/main/java/com/ruoyi/basic/mapper/SupplierManageFileMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.basic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.pojo.SupplierManageFile;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface SupplierManageFileMapper extends BaseMapper<SupplierManageFile> {
    IPage<SupplierManageFile> supplierManageFileListPage(Page page, @Param("supplierManageFile") SupplierManageFile supplierManageFile);
}
src/main/java/com/ruoyi/basic/pojo/Customer.java
@@ -31,6 +31,10 @@
     */
    @Excel(name = "客户名称")
    private String customerName;
    /** å®¢æˆ·åˆ†ç±»ï¼šé›¶å”®å®¢æˆ·ï¼Œè¿›é”€å•†å®¢æˆ· */
    @Excel(name = "客户分类")
    private String customerType;
    /**
     * çº³ç¨Žäººè¯†åˆ«å·
src/main/java/com/ruoyi/basic/pojo/SupplierManage.java
@@ -56,6 +56,9 @@
    @JsonFormat(pattern = "yyyy-MM-dd")
//    @Excel(name = "维护时间", width = 30, dateFormat = "yyyy-MM-dd")
    private LocalDate maintainTime;
    @Excel(name = "是否白名单")
    @ApiModelProperty(value = "是否白名单(0是 1否)")
    private Integer isWhite;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
src/main/java/com/ruoyi/basic/pojo/SupplierManageFile.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package com.ruoyi.basic.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * ä¾›åº”商管理--附件
 * supplier_manage_file
 */
@TableName(value = "supplier_manage_file")
@Data
public class SupplierManageFile implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * åºå·
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "文件名称")
    private String name;
    @ApiModelProperty(value = "文件路径")
    private String url;
    @ApiModelProperty(value = "文件大小")
    private int fileSize;
    @ApiModelProperty(value = "供应商ID")
    @NotBlank(message = "供应商id不能为空!")
    private Long supplierId;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/basic/service/SupplierManageFileService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.ruoyi.basic.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.basic.pojo.SupplierManageFile;
public interface SupplierManageFileService extends IService<SupplierManageFile> {
    IPage<SupplierManageFile> supplierManageFileListPage(Page page, SupplierManageFile supplierManageFile);
}
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -74,9 +74,13 @@
        // 2. æž„建查询条件(增强空值安全)
        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
        String customerName = customer.getCustomerName();
        String customerType = customer.getCustomerType();
        if (StringUtils.isNotBlank(customerName)) {
            queryWrapper.like(Customer::getCustomerName, customerName);
        }
        if (StringUtils.isNotBlank(customerType)) {
            queryWrapper.like(Customer::getCustomerType, customerType);
        }
        // 3. æ‰§è¡Œåˆ†é¡µæŸ¥è¯¢ï¼ˆä¿ç•™åˆ†é¡µå…ƒæ•°æ®ï¼‰
        IPage<Customer> customerPage = customerMapper.selectPage(page, queryWrapper);
src/main/java/com/ruoyi/basic/service/impl/SupplierManageFileServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.basic.service.impl;
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.ruoyi.basic.mapper.SupplierManageFileMapper;
import com.ruoyi.basic.pojo.SupplierManageFile;
import com.ruoyi.basic.service.SupplierManageFileService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@AllArgsConstructor
@Service
public class SupplierManageFileServiceImpl extends ServiceImpl<SupplierManageFileMapper, SupplierManageFile> implements SupplierManageFileService {
    private SupplierManageFileMapper supplierManageFileMapper;
    @Override
    public IPage<SupplierManageFile> supplierManageFileListPage(Page page, SupplierManageFile supplierManageFile) {
        return supplierManageFileMapper.supplierManageFileListPage(page, supplierManageFile);
    }
}
src/main/java/com/ruoyi/device/controller/DeviceLedgerController.java
@@ -84,7 +84,14 @@
    public void export(HttpServletResponse response, Long[] ids) {
         deviceLedgerService.export(response, ids);
    }
    /**
     *
     */
    @GetMapping("/report/forms")
    @ApiOperation("查询设备台账图表数据")
    public AjaxResult report() {
        return AjaxResult.success(deviceLedgerService.report());
    }
    @PostMapping("import")
    @ApiModelProperty("导入设备台账")
    public AjaxResult importData(MultipartFile file) throws IOException {
src/main/java/com/ruoyi/device/controller/DeviceRepairController.java
@@ -1,21 +1,33 @@
package com.ruoyi.device.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveProcessService;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.dto.DeviceRepairDto;
import com.ruoyi.device.pojo.DeviceLedger;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.device.service.IDeviceLedgerService;
import com.ruoyi.device.service.IDeviceRepairService;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
@Api(tags = "设备报修管理")
@RequestMapping("/device/repair")
@@ -27,6 +39,8 @@
    @Autowired
    private IDeviceLedgerService deviceLedgerService;
    @Autowired
    private IApproveProcessService approveProcessService;
    @ApiModelProperty("设备报修列表")
    @GetMapping("/page")
@@ -35,9 +49,40 @@
    }
    @PostMapping()
    @Transactional(rollbackFor = Exception.class)
    @ApiModelProperty("添加设备报修")
    public AjaxResult add( @RequestBody DeviceRepair deviceRepair) {
        return deviceRepairService.saveDeviceRepair(deviceRepair);
    public AjaxResult add( @RequestBody DeviceRepair deviceRepair) throws Exception {
        deviceRepairService.saveDeviceRepair(deviceRepair);
        ApproveProcessVO approveProcessVO = new ApproveProcessVO();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        // èŽ·å–å½“å‰ç™»å½•å…¬å¸
        Long tenantId = loginUser.getTenantId();
        if(null != tenantId){
            LambdaQueryWrapper<DeviceRepair> QueryWrapper = new LambdaQueryWrapper<>();
            QueryWrapper.eq(DeviceRepair::getDeviceLedgerId,deviceRepair.getDeviceLedgerId())
                    .eq(DeviceRepair::getRemark,deviceRepair.getRemark())
                    .eq(DeviceRepair::getDeviceName,deviceRepair.getDeviceName())
                    .eq(DeviceRepair::getApproverId,deviceRepair.getApproverId())
                    .eq(DeviceRepair::getRepairTime,deviceRepair.getRepairTime());
            DeviceRepair one = deviceRepairService.getOne(QueryWrapper);
            if(ObjectUtils.isEmpty(one)){
                return AjaxResult.error("设备报修不存在");
            }
            //获取当前登录部门id
            approveProcessVO.setApproveDeptId(tenantId);
            //获取当前登录用户id
            approveProcessVO.setApproveUser(loginUser.getUserId());
            //获取当前时间
            approveProcessVO.setApproveTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            approveProcessVO.setApproveType(4);
            approveProcessVO.setApproveUserIds(deviceRepair.getApproverId().toString());
            approveProcessVO.setApproveReason(deviceRepair.getRemark());
            approveProcessVO.setDeviceRepairId(one.getId());
            approveProcessVO.setMaintenancePrice(deviceRepair.getMaintenancePrice());
            approveProcessService.addApprove(approveProcessVO);
        }
        return AjaxResult.success();
    }
    @ApiModelProperty("根据id查询设备报修")
@@ -62,6 +107,17 @@
    @DeleteMapping("/{ids}")
    @ApiModelProperty("删除设备报修")
    public AjaxResult delete(@PathVariable("ids") Long[] ids) {
        LambdaQueryWrapper<ApproveProcess> QueryWrapper = new LambdaQueryWrapper<>();
        QueryWrapper.in(ApproveProcess::getDeviceRepairId,ids);
        List<ApproveProcess> approveProcessList = approveProcessService.list(QueryWrapper);
        if(!approveProcessList.isEmpty()){
            approveProcessList.forEach(approveProcess -> {
                if (approveProcess.getApproveStatus() != 0){
                    //抛出异常
                    throw new RuntimeException("有正在处理中的审批流程,不能删除");
                }
            });
        }
        boolean b = deviceRepairService.removeBatchByIds(Arrays.asList(ids));
        if (!b) {
            return AjaxResult.error("删除失败");
src/main/java/com/ruoyi/device/dto/DeviceAssetInfoDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.device.dto;
import lombok.Data;
import java.math.BigDecimal;
/**
 * è®¾å¤‡èµ„产信息Dto-资产报表
 */
@Data
public class DeviceAssetInfoDto {
    /**
     * è®¾å¤‡æ€»æ•°
     */
    private Integer totalEquipment;
    /**
     * èµ„产原值
     */
    private BigDecimal totalOriginalValue;
    /**
     * ç´¯è®¡æŠ˜æ—§
     */
    private BigDecimal totalDepreciation;
    /**
     * å‡€å€¼
     */
    private BigDecimal totalNetValue;
}
src/main/java/com/ruoyi/device/dto/DeviceRepairDto.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -68,7 +69,7 @@
    @ApiModelProperty("租户id")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty("维修价格")
    private String maintenancePrice;
}
src/main/java/com/ruoyi/device/pojo/DeviceRepair.java
@@ -4,10 +4,9 @@
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.Api;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import nonapi.io.github.classgraph.json.Id;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
@@ -24,9 +23,9 @@
    @ApiModelProperty("设备台账id")
    private Long deviceLedgerId;
    @ApiModelProperty("设备名称")
    private String deviceName;
    @ApiModelProperty("设备型号")
    private String deviceModel;
    @ApiModelProperty("报修时间")
@@ -49,7 +48,7 @@
    @ApiModelProperty("维修结果")
    private String maintenanceResult;
    @ApiModelProperty("状态 0 å¾…ç»´ä¿® 1完结 2 å¤±è´¥")
    @ApiModelProperty("状态:0审核中,1审核通过,2审核失败,3维修中,4维修通过,5维修失败")
    private Integer status;
    @ApiModelProperty("创建时间")
@@ -75,6 +74,8 @@
    @ApiModelProperty("租户id")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty("维修价格")
    private BigDecimal maintenancePrice;
    @ApiModelProperty("审批人id")
    private Integer approverId;
}
src/main/java/com/ruoyi/device/service/IDeviceLedgerService.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.device.dto.DeviceAssetInfoDto;
import com.ruoyi.device.dto.DeviceLedgerDto;
import com.ruoyi.device.pojo.DeviceLedger;
import com.ruoyi.framework.web.domain.AjaxResult;
@@ -22,4 +23,5 @@
    void export(HttpServletResponse response, Long[] ids);
    Boolean importData(MultipartFile file) throws IOException;
    DeviceAssetInfoDto report();
}
src/main/java/com/ruoyi/device/service/impl/DeviceLedgerServiceImpl.java
@@ -8,6 +8,7 @@
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.device.dto.DeviceAssetInfoDto;
import com.ruoyi.device.dto.DeviceLedgerDto;
import com.ruoyi.device.execl.DeviceLedgerExeclDto;
import com.ruoyi.device.mapper.DeviceLedgerMapper;
@@ -24,6 +25,7 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
@@ -119,4 +121,14 @@
        return true;
    }
    @Override
    public DeviceAssetInfoDto report() {
        List<DeviceLedger> list = deviceLedgerMapper.selectList(null);
        DeviceAssetInfoDto deviceAssetInfoDto = new DeviceAssetInfoDto();
        deviceAssetInfoDto.setTotalEquipment(list.stream().map(DeviceLedger::getNumber).reduce(BigDecimal.ZERO, BigDecimal::add).intValue());
        deviceAssetInfoDto.setTotalOriginalValue(list.stream().map(DeviceLedger::getTaxIncludingPriceTotal).reduce(BigDecimal.ZERO, BigDecimal::add));
        deviceAssetInfoDto.setTotalNetValue(list.stream().map(DeviceLedger::getUnTaxIncludingPriceTotal).reduce(BigDecimal.ZERO, BigDecimal::add));
        deviceAssetInfoDto.setTotalDepreciation(deviceAssetInfoDto.getTotalOriginalValue().subtract(deviceAssetInfoDto.getTotalNetValue()));
        return deviceAssetInfoDto;
    }
}
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -425,25 +425,29 @@
//                .ge(SalesLedger::getEntryDate, startDate)
//                .lt(SalesLedger::getEntryDate, endDate)
        );
        BigDecimal receivableMoney = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//        BigDecimal receivableMoney = salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal receivableMoney = sumAmount(salesLedgers, SalesLedger::getContractAmount);
        // åº”付
        List<PurchaseLedger> procurementRecords = purchaseLedgerMapper.selectList(new LambdaQueryWrapper<PurchaseLedger>()
//                .ge(PurchaseLedger::getEntryDate, startDate)
//                .lt(PurchaseLedger::getEntryDate, endDate)
        );
        BigDecimal payableMoney = procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//        BigDecimal payableMoney = procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal payableMoney = sumAmount(procurementRecords, PurchaseLedger::getContractAmount);
        // é¢„æ”¶
        List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>()
//                .ge(ReceiptPayment::getReceiptPaymentDate, startDate)
//                .lt(ReceiptPayment::getReceiptPaymentDate, endDate)
        );
        BigDecimal advanceMoney = receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//        BigDecimal advanceMoney = receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal advanceMoney = sumAmount(receiptPayments, ReceiptPayment::getReceiptPaymentAmount);
        // é¢„付
        List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper.selectList(new LambdaQueryWrapper<PaymentRegistration>()
//                .ge(PaymentRegistration::getPaymentDate, startDate)
//                .lt(PaymentRegistration::getPaymentDate, endDate)
        );
        BigDecimal prepayMoney = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//        BigDecimal prepayMoney = paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal prepayMoney = sumAmount(paymentRegistrations, PaymentRegistration::getCurrentPaymentAmount);
        StatisticsReceivablePayableDto statisticsReceivablePayableDto = new StatisticsReceivablePayableDto();
        statisticsReceivablePayableDto.setPayableMoney(payableMoney.subtract(prepayMoney));
        statisticsReceivablePayableDto.setReceivableMoney(receivableMoney.subtract(advanceMoney));
@@ -452,7 +456,13 @@
        return statisticsReceivablePayableDto;
    }
    public static <T> BigDecimal sumAmount(List<T> list, java.util.function.Function<T, BigDecimal> amountExtractor) {
        return list.stream()
                // æå–金额时,将null替换为BigDecimal.ZERO
                .map(item -> Optional.ofNullable(amountExtractor.apply(item)).orElse(BigDecimal.ZERO))
                // ç´¯åŠ ï¼Œåˆå§‹å€¼ä¸º0,避免空流问题
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    @Autowired
    private DeviceRepairMapper deviceRepairMapper;
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementExceptionRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.procurementrecord.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.dto.*;
import com.ruoyi.procurementrecord.mapper.ProcurementExceptionRecordMapper;
import com.ruoyi.procurementrecord.pojo.ProcurementExceptionRecord;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
 * @author :yys
 * @date : 2025/7/7 14:32
 */
@RestController
@Api(tags = "采购异常记录")
@RequestMapping("/procurementExceptionRecord")
public class ProcurementExceptionRecordController extends BaseController {
    @Autowired
    private ProcurementExceptionRecordMapper procurementExceptionRecordMapper;
    @PostMapping("/add")
    @Transactional
    public AjaxResult add(@RequestBody ProcurementExceptionRecord procurementExceptionRecord) {
        return AjaxResult.success(procurementExceptionRecordMapper.insert(procurementExceptionRecord));
    }
    @PostMapping("/update")
    @Transactional
    public AjaxResult updatePro(@RequestBody ProcurementExceptionRecord procurementExceptionRecord) {
        return AjaxResult.success(procurementExceptionRecordMapper.updateById(procurementExceptionRecord));
    }
}
src/main/java/com/ruoyi/procurementrecord/controller/ProcurementRecordController.java
@@ -119,7 +119,11 @@
        IPage<ProcurementPageDto> result = procurementRecordService.listPage(page, procurementDto);
        return AjaxResult.success(result);
    }
    @GetMapping("/listReport")
    @ApiOperation(value = "查询库存图表数据")
    public AjaxResult listReport() {
        return AjaxResult.success(procurementRecordService.getReportList());
    }
    @GetMapping("/listPageByProduction")
    @Log(title = "生产入库-入库管理-入库查询", businessType = BusinessType.OTHER)
    @ApiOperation(value = "入库查询")
src/main/java/com/ruoyi/procurementrecord/dto/InventoryInformationDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.procurementrecord.dto;
import lombok.Data;
import java.math.BigDecimal;
/**
 * å­˜è´§æ ¸ç®—信息Dto-资产报表
 */
@Data
public class InventoryInformationDto {
    /**
     * æ€»åº“存数量
     */
    private Integer totalInventoryCount;
    /**
     * æ€»åº“存金额
     */
    private BigDecimal totalInventoryValue;
    /**
     * åº“存变动数量
     */
    private Integer inventoryChangeCount;
    /**
     * åº“存变动金额
     */
    private BigDecimal inventoryChangeValue;
}
src/main/java/com/ruoyi/procurementrecord/dto/ProcurementAddDto.java
@@ -21,5 +21,6 @@
    private Integer type;
    private String typeName;
    private Integer purchaseLedgerId;
}
src/main/java/com/ruoyi/procurementrecord/mapper/ProcurementExceptionRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
package com.ruoyi.procurementrecord.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.procurementrecord.pojo.ProcurementExceptionRecord;
public interface ProcurementExceptionRecordMapper extends BaseMapper<ProcurementExceptionRecord> {
}
src/main/java/com/ruoyi/procurementrecord/pojo/ProcurementExceptionRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
package com.ruoyi.procurementrecord.pojo;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@TableName("procurement_exception_record")
@Data
@Builder
public class ProcurementExceptionRecord {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * é‡‡è´­å°è´¦id
     */
    private Integer purchaseLedgerId;
    /**
     * å¼‚常描述
     */
    private String exceptionReason;
    /**
     * å¼‚常数量
     */
    private BigDecimal exceptionNum;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹è€…
     */
    private Long updateUser;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    private LocalDateTime updateTime;
    /**
     * ç§Ÿæˆ·ID
     */
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
}
src/main/java/com/ruoyi/procurementrecord/service/ProcurementRecordService.java
@@ -57,4 +57,5 @@
    int updateManagementByCustom(ProcurementManagementUpdateDto procurementDto);
    BigDecimal getProcurementAmount(Long salesProductId);
    InventoryInformationDto getReportList();
}
src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -416,6 +416,68 @@
    }
    @Override
    public InventoryInformationDto getReportList() {
        InventoryInformationDto inventoryInformationDto = new InventoryInformationDto();
        IPage<ProcurementPageDto> procurementPageDtoIPage = this.listPage(new Page<>(1, -1), new ProcurementPageDto());
        if(CollectionUtils.isEmpty(procurementPageDtoIPage.getRecords())){
            return inventoryInformationDto;
        }
        // è®¡ç®—总库存数量
        inventoryInformationDto.setTotalInventoryCount(procurementPageDtoIPage.getRecords().stream()
                .map(ProcurementPageDto::getInboundNum0)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .intValue());
        // è®¡ç®—总库存金额-ProcurementPageDto里每个对象的inboundNum0值和taxInclusiveUnitPrice的乘积,之后相加得到总库存金额
        BigDecimal totalInventoryValue = procurementPageDtoIPage.getRecords().stream()
                // è¿‡æ»¤ç©ºå¯¹è±¡ï¼Œé¿å…NPE
                .filter(Objects::nonNull)
                // å¤„理每个对象的空值:null转为0
                .map(dto -> {
                    // å…¥åº“数量:null â†’ 0
                    BigDecimal inboundNum0 = Optional.ofNullable(dto.getInboundNum0()).orElse(BigDecimal.ZERO);
                    // å«ç¨Žå•价:null â†’ 0
                    BigDecimal taxInclusiveUnitPrice = Optional.ofNullable(dto.getTaxInclusiveUnitPrice()).orElse(BigDecimal.ZERO);
                    // è®¡ç®—单个对象的库存金额:数量 Ã— å«ç¨Žå•ä»·
                    return inboundNum0.multiply(taxInclusiveUnitPrice);
                })
                // æ‰€æœ‰å•个金额求和,初始值为0
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // è®¾ç½®æ€»åº“存金额
        inventoryInformationDto.setTotalInventoryValue(totalInventoryValue);
        // è®¡ç®—库存变动数量-ProcurementPageDto里每个对象的inboundNum值和inboundNum0值的差值,之后相加得到库存变动数量
        inventoryInformationDto.setInventoryChangeCount(procurementPageDtoIPage.getRecords().stream()
                // è¿‡æ»¤ç©ºå¯¹è±¡ï¼Œé¿å…NPE
                .filter(Objects::nonNull)
                // å¤„理每个对象的空值:null转为0
                .map(dto -> {
                    // å…¥åº“数量:null â†’ 0
                    BigDecimal inboundNum = Optional.ofNullable(dto.getInboundNum()).orElse(BigDecimal.ZERO);
                    // å¾…出库数量:null â†’ 0
                    BigDecimal inboundNum0 = Optional.ofNullable(dto.getInboundNum0()).orElse(BigDecimal.ZERO);
                    // è®¡ç®—单个对象的库存变动数量:数量 - å¾…出库数量
                    return inboundNum.subtract(inboundNum0);
                })
                // æ‰€æœ‰å•个变动数量求和,初始值为0
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .intValue());
        // è®¡ç®—库存变动金额ProcurementPageDto里每个对象的taxInclusiveTotalPrice值的和
        BigDecimal inventoryChangeValue = procurementPageDtoIPage.getRecords().stream()
                // è¿‡æ»¤ç©ºå¯¹è±¡ï¼Œé¿å…NPE
                .filter(Objects::nonNull)
                // å¤„理每个对象的空值:null转为0
                .map(dto -> {
                    // å«ç¨Žæ€»ä»·ï¼šnull â†’ 0
                    BigDecimal taxInclusiveTotalPrice = Optional.ofNullable(dto.getTaxInclusiveTotalPrice()).orElse(BigDecimal.ZERO);
                    // è®¡ç®—单个对象的入库库存金额:含税总价
                    return taxInclusiveTotalPrice;
                })
                // æ‰€æœ‰å•个变动金额求和,初始值为0
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // è®¾ç½®åº“存变动金额
        inventoryInformationDto.setInventoryChangeValue(inventoryChangeValue.subtract(totalInventoryValue));
        return inventoryInformationDto;
    }
    @Override
    public IPage<ProcurementPageDto> listPageByProduction(Page page, ProcurementPageDto procurementDto) {
        IPage<ProcurementPageDto> procurementPageDtoIPage = procurementRecordMapper.listPageByProduction(page, procurementDto);
        List<ProcurementPageDto> procurementPageDtos = procurementPageDtoIPage.getRecords();
src/main/java/com/ruoyi/production/controller/ProductProcessRouteItemController.java
@@ -1,23 +1,39 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.dto.ProcessRouteItemDto;
import com.ruoyi.production.dto.ProductProcessRouteItemDto;
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.mapper.ProductWorkOrderMapper;
import com.ruoyi.production.pojo.ProductProcessRouteItem;
import com.ruoyi.production.pojo.ProductWorkOrder;
import com.ruoyi.production.service.ProductProcessRouteItemService;
import com.ruoyi.production.service.ProductWorkOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@RequestMapping("productProcessRoute")
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@RequestMapping("/productProcessRoute")
@RestController
@AllArgsConstructor
@Api(tags = "生产工艺路线")
public class ProductProcessRouteItemController {
    @Autowired
    private ProductProcessRouteItemService productProcessRouteItemService;
    private ProductWorkOrderService productWorkOrderService;
    private ProductWorkOrderMapper productWorkOrderMapper;
    @GetMapping("list")
    @ApiOperation("根据Id查询工艺项目")
@@ -25,10 +41,89 @@
        return R.ok(productProcessRouteItemService.listItem(orderId));
    }
    @PostMapping ()
    @ApiOperation("新增修改")
    @PostMapping("/updateRouteItem")
    @ApiOperation("批量新增修改")
    @Transactional(rollbackFor = Exception.class)
    public R addOrUpdate(@RequestBody ProductProcessRouteItemDto processRouteItemDto) {
        productProcessRouteItemService.remove(new QueryWrapper<ProductProcessRouteItem>().lambda().eq(ProductProcessRouteItem::getRouteId, processRouteItemDto.getRouteId()));
        return R.ok(productProcessRouteItemService.saveBatch(processRouteItemDto.getProcessRouteItem()));
        List<ProductProcessRouteItem> items = processRouteItemDto.getProcessRouteItem();
        if (CollectionUtils.isEmpty(items)) {
            return R.ok();
        }
        Map<Boolean, List<ProductProcessRouteItem>> partitioned = items.stream()
                .collect(Collectors.partitioningBy(
                        item -> item.getId() != null && item.getId() > 0
                ));
        List<ProductProcessRouteItem> toUpdate = partitioned.get(true);
        List<ProductProcessRouteItem> toInsert = partitioned.get(false);
        // æ‰¹é‡å¤„理
        boolean result = true;
        if (!toInsert.isEmpty()) {
            result = productProcessRouteItemService.saveBatch(toInsert);
            if (result) {
                // ç”Ÿæˆå·¥å•号
                String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                // æŸ¥è¯¢ä»Šæ—¥æœ€å¤§å·¥å•号
                QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                queryWrapper.likeRight("work_order_no", datePrefix)
                        .select("MAX(work_order_no) as maxNo");
                List<Map<String, Object>> maxNoList = productWorkOrderMapper.selectMaps(queryWrapper);
                String maxWorkOrderNo = null;
                if (!maxNoList.isEmpty() && maxNoList.get(0) != null && maxNoList.get(0).get("maxNo") != null) {
                    maxWorkOrderNo = maxNoList.get(0).get("maxNo").toString();
                }
                int startSequence = 1;
                if (maxWorkOrderNo != null && maxWorkOrderNo.startsWith(datePrefix)) {
                    try {
                        String seqStr = maxWorkOrderNo.substring(datePrefix.length());
                        startSequence = Integer.parseInt(seqStr) + 1;
                    } catch (NumberFormatException e) {
                        startSequence = 1;
                    }
                }
                // æ‰¹é‡ç”Ÿæˆå·¥å•
                List<ProductWorkOrder> workOrders = new ArrayList<>();
                for (int i = 0; i < toInsert.size(); i++) {
                    ProductProcessRouteItem item = toInsert.get(i);
                    String workOrderNoStr = String.format("%s%03d", datePrefix, startSequence + i);
                    ProductWorkOrder workOrder = new ProductWorkOrder();
                    workOrder.setProductProcessRouteItemId(item.getId());
                    workOrder.setProductOrderId(item.getRouteId());
                    workOrder.setWorkOrderNo(workOrderNoStr);
                    workOrder.setStatus(1);
                    workOrders.add(workOrder);
                }
                result = productWorkOrderService.saveBatch(workOrders);
            }
        }
        if (!toUpdate.isEmpty()) {
            result = productProcessRouteItemService.updateBatchById(toUpdate) && result;
        }
        return R.ok(result);
    }
    @DeleteMapping("/deleteRouteItem")
    @ApiOperation("删除生产工艺路线")
    @Transactional(rollbackFor = Exception.class)
    public R deleteRouteItem(@RequestBody ProductProcessRouteItemDto processRouteItemDto) {
        if (processRouteItemDto == null || processRouteItemDto.getId() == null) {
            return R.fail("参数错误,ID不能为空");
        }
        try {
            // å…ˆåˆ é™¤å…³è”的工单数据
            LambdaQueryWrapper<ProductWorkOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProductWorkOrder::getProductProcessRouteItemId, processRouteItemDto.getId());
            productWorkOrderMapper.delete(wrapper);
            // åˆ é™¤ä¸»è¡¨æ•°æ®
            productProcessRouteItemService.removeById(processRouteItemDto.getId());
            return R.ok();
        } catch (Exception e) {
            throw new RuntimeException("删除失败:" + e.getMessage());
        }
    }
}
src/main/java/com/ruoyi/production/controller/ProductStructureController.java
@@ -22,7 +22,7 @@
    @ApiOperation("根据productId查询")
    @GetMapping("listByproductModelId/{productModelId}")
    @GetMapping("/listByproductModelId/{productModelId}")
    public R listByproductModelId( @PathVariable("productModelId") Long productModelId){
        return R.ok(productStructureService.listByproductModelId( productModelId));
    }
src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.dto.ProductWorkOrderDto;
import com.ruoyi.production.service.ProductWorkOrderService;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@AllArgsConstructor
@RequestMapping("/productWorkOrder")
public class ProductWorkOrderController {
    private ProductWorkOrderService productWorkOrderservice;
    /**
     * äº§å“å·¥å•实体类分页查询
     */
    @ApiOperation("产品工单实体类分页查询")
    @GetMapping("/page")
    public R page(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
        return R.ok(productWorkOrderservice.listPage(page, productWorkOrder));
    }
    /**
     * äº§å“å·¥å•æ›´æ–°
     */
    @ApiOperation("产品工单更新")
    @PostMapping ("/updateProductWorkOrder")
    public R updateProductWorkOrder(@RequestBody ProductWorkOrderDto productWorkOrderDto) {
        return R.ok(productWorkOrderservice.updateProductWorkOrder(productWorkOrderDto));
    }
}
src/main/java/com/ruoyi/production/controller/ProductionProductInputController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.dto.ProductionProductInputDto;
import com.ruoyi.production.service.ProductionProductInputService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("productionProductInput")
@RestController
@Api(value = "生产投入")
public class ProductionProductInputController {
    @Autowired
    private ProductionProductInputService productionProductInputService;
    @GetMapping("listPage")
    public R page(Page<ProductionProductInputDto> page, ProductionProductInputDto productionProductInputDto) {
        return R.ok(productionProductInputService.listPageProductionProductInputDto(page, productionProductInputDto));
    }
}
src/main/java/com/ruoyi/production/controller/ProductionProductMainController.java
@@ -2,14 +2,17 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.dto.ProductProcessRouteItemDto;
import com.ruoyi.production.dto.ProductionProductMainDto;
import com.ruoyi.production.pojo.ProductionProductMain;
import com.ruoyi.production.service.ProductionProductMainService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
@RequestMapping("productionProductMain")
@RestController
@@ -19,8 +22,31 @@
    @Autowired
    private ProductionProductMainService productionProductMainService;
    /**
     * æŠ¥å·¥æŸ¥è¯¢
     * @param page
     * @param productionProductMainDto
     * @return
     */
    @GetMapping("listPage")
    public R page(Page<ProductionProductMainDto> page, ProductionProductMainDto productionProductMainDto) {
        return R.ok(productionProductMainService.listPageProductionProductMainDto(page, productionProductMainDto));
    }
    /**
     * æŠ¥å·¥æ–°å¢žæ›´æ–°
     * @param productionProductMainDto
     * @return
     */
    @PostMapping("addProductMain")
    public R addProductMain(@RequestBody ProductionProductMainDto productionProductMainDto) {
        return R.ok(productionProductMainService.addProductMain(productionProductMainDto));
    }
    @ApiOperation("删除报工")
    @DeleteMapping("/delete")
    @Transactional(rollbackFor = Exception.class)
    public R delete(@RequestBody ProductionProductMainDto productionProductMainDto) {
        return R.ok(productionProductMainService.removeProductMain(productionProductMainDto));
    }
}
src/main/java/com/ruoyi/production/controller/ProductionProductOutputController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.production.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.production.dto.ProductionProductInputDto;
import com.ruoyi.production.dto.ProductionProductOutputDto;
import com.ruoyi.production.service.ProductionProductInputService;
import com.ruoyi.production.service.ProductionProductOutputService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("productionProductOutput")
@RestController
@Api(value = "生产产出")
public class ProductionProductOutputController {
    @Autowired
    private ProductionProductOutputService productionProductOutputService;
    @GetMapping("listPage")
    public R page(Page<ProductionProductOutputDto> page, ProductionProductOutputDto productionProductOutputDto) {
        return R.ok(productionProductOutputService.listPageProductionProductOutputDto(page, productionProductOutputDto));
    }
}
src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.production.dto;
import com.ruoyi.production.pojo.ProductWorkOrder;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class ProductWorkOrderDto extends ProductWorkOrder {
    //产品名称
    @ApiModelProperty(value = "产品名称")
    private String productName;
    //规格
    @ApiModelProperty(value = "规格")
    private String model;
    //工序
    @ApiModelProperty(value = "工序")
    private String processName;
    //单位
    @ApiModelProperty(value = "单位")
    private String unit;
    //生产订单号
    @ApiModelProperty(value = "生产订单号")
    private String productOrderNpsNo;
}
src/main/java/com/ruoyi/production/dto/ProductionProductInputDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package com.ruoyi.production.dto;
import com.ruoyi.production.pojo.ProductionProductInput;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ProductionProductInputDto extends ProductionProductInput {
    @ApiModelProperty(value = "报工单号")
    private String productNo;
    @ApiModelProperty(value = "产品型号")
    private String model;
}
src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -4,6 +4,8 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ProductionProductMainDto extends ProductionProductMain {
    @ApiModelProperty(value = "工单编号")
@@ -14,4 +16,13 @@
    @ApiModelProperty(value = "报工人员昵称")
    private String nickName;
    @ApiModelProperty(value = "报工数量")
    private BigDecimal quantity;
    @ApiModelProperty(value = "是否报工")
    private boolean reportWork;
    @ApiModelProperty(value = "报工id")
    private Long productMainId;
}
src/main/java/com/ruoyi/production/dto/ProductionProductOutputDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.production.dto;
import com.ruoyi.production.pojo.ProductionProductInput;
import com.ruoyi.production.pojo.ProductionProductOutput;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ProductionProductOutputDto extends ProductionProductOutput {
    @ApiModelProperty(value = "报工单号")
    private String productNo;
    @ApiModelProperty(value = "产品型号")
    private String model;
}
src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.production.dto.ProductWorkOrderDto;
import com.ruoyi.production.pojo.ProductWorkOrder;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
@Mapper
public interface ProductWorkOrderMapper extends BaseMapper<ProductWorkOrder> {
    IPage<ProductWorkOrderDto> pageProductWorkOrder(Page<ProductWorkOrderDto> page, @Param("c") ProductWorkOrderDto productWorkOrder);
    int updatePlanQuantity(Map<String, Object> params);
    /**
     * å›žæ»šå·¥å•计划数量:从production_product_output取quantity加回plan_quantity
     * @param productMainId
     * @return
     */
    int rollbackPlanQuantity(@Param("productMainId") Long productMainId);
}
src/main/java/com/ruoyi/production/mapper/ProductionProductInputMapper.java
@@ -1,9 +1,21 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.production.dto.ProductionProductInputDto;
import com.ruoyi.production.pojo.ProductionProductInput;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ProductionProductInputMapper extends BaseMapper<ProductionProductInput> {
    IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, @Param("c") ProductionProductInputDto productionProductInputDto);
    /**
     * æ ¹æ®ç”Ÿäº§ä¸»è¡¨ID批量删除投入表数据
     */
    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
}
src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -3,16 +3,20 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.production.dto.ProductOrderDto;
import com.ruoyi.production.dto.ProductionProductMainDto;
import com.ruoyi.production.pojo.ProductionProductMain;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import javax.annotation.ManagedBean;
import java.util.List;
@Mapper
public interface ProductionProductMainMapper extends BaseMapper<ProductionProductMain> {
    IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, @Param("c") ProductionProductMainDto productionProductMainDto);
    /**
     * æ ¹æ®å·¥å•ID批量删除生产主表数据
     */
    int deleteByWorkOrderIds(@Param("workOrderIds") List<Long> workOrderIds);
}
src/main/java/com/ruoyi/production/mapper/ProductionProductOutputMapper.java
@@ -1,9 +1,21 @@
package com.ruoyi.production.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.production.dto.ProductionProductOutputDto;
import com.ruoyi.production.pojo.ProductionProductOutput;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ProductionProductOutputMapper extends BaseMapper<ProductionProductOutput> {
    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, @Param("c") ProductionProductOutputDto productionProductOutputDto);
    /**
     * æ ¹æ®ç”Ÿäº§ä¸»è¡¨ID批量删除产出表数据
     */
    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
}
src/main/java/com/ruoyi/production/pojo/ProcessRouteItem.java
@@ -1,15 +1,13 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("process_route_item")
public class ProcessRouteItem {
    @TableId(type = IdType.AUTO)
src/main/java/com/ruoyi/production/pojo/ProductProcess.java
@@ -3,12 +3,13 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@TableName("product_process")
@Data
public class ProductProcess {
public class ProductProcess implements Serializable {
    private static final long serialVersionUID = 1L;
src/main/java/com/ruoyi/production/pojo/ProductProcessRouteItem.java
@@ -13,7 +13,7 @@
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "工艺路线id")
    @ApiModelProperty(value = "生产订单id(product_order_id)")
    private Long routeId;
    @ApiModelProperty(value = "工序id")
@@ -32,4 +32,7 @@
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value ="拖动排序")
    private Integer dragSort;
}
src/main/java/com/ruoyi/production/pojo/ProductWorkOrder.java
@@ -5,14 +5,23 @@
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
 * äº§å“å·¥å•实体类
 * å¯¹åº”数据库表:product_work_order
 */
@Data
@TableName("product_work_order")
public class ProductWorkOrder implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
@@ -23,16 +32,36 @@
    private Long productProcessRouteItemId;
    /**
     * ç”Ÿäº§è®¢å•id
     */
    @ApiModelProperty(value = "生产订单id")
    private Long productOrderId;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * ä¿®æ”¹æ—¶é—´
     */
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;
    /**
     * å·¥å•编号
     */
    @ApiModelProperty(value = "生产订单号")
    @ApiModelProperty(value = "工单编号")
    private String workOrderNo;
    /**
     * ç”Ÿäº§çŠ¶æ€ 1 å¾…确认  2 å¾…生产 3生产中 4已生产
     * çŠ¶æ€  1 å¾…确认  2 å¾…生产 3生产中 4已生产
     */
    @ApiModelProperty(value = "生产状态 1 å¾…确认  2 å¾…生产 3生产中 4已生产")
    private String status;
    @ApiModelProperty(value = "状态  1 å¾…确认  2 å¾…生产 3生产中 4已生产")
    private Integer status;
    /**
     * ç§Ÿæˆ·id
@@ -41,14 +70,52 @@
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    //创建时间
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * è®¡åˆ’开始时间
     */
    @ApiModelProperty(value = "计划开始时间")
    private LocalDate planStartTime;
    //修改时间
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;
    /**
     * è®¡åˆ’结束时间
     */
    @ApiModelProperty(value = "计划结束时间")
    private LocalDate planEndTime;
}
    /**
     * å®žé™…开始时间
     */
    @ApiModelProperty(value = "实际开始时间")
    private LocalDate actualStartTime;
    /**
     * å®žé™…结束时间
     */
    @ApiModelProperty(value = "实际结束时间")
    private LocalDate actualEndTime;
    /**
     * æ˜¯å¦æŠ¥å·¥
     */
    @ApiModelProperty(value = "是否报工")
    private boolean reportWork;
    /**
     * è®¡åˆ’数量
     */
    @ApiModelProperty(value = "计划数量")
    private BigDecimal planQuantity;
    /**
     * å®žé™…数量
     */
    @ApiModelProperty(value = "数量")
    private BigDecimal quantity;
    /**
     * æŠ¥å·¥id
     */
    @ApiModelProperty(value = "报工id")
    private Long productMainId;
}
src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
@@ -1,8 +1,6 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -10,13 +8,14 @@
import java.time.LocalDateTime;
@Data
@TableName("production_product_input")
public class ProductionProductInput {
    @TableId
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "报工id")
    private Long productionProductId;
    private Long productMainId;
    @ApiModelProperty(value = "产品id")
    private Long productModelId;
src/main/java/com/ruoyi/production/pojo/ProductionProductMain.java
@@ -1,17 +1,16 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("production_product_main")
public class ProductionProductMain {
    @TableId
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "报工单号")
@@ -20,15 +19,26 @@
    @ApiModelProperty(value = "报工人员id")
    private Long userId;
    @ApiModelProperty(value = "报工人员")
    private String userName;
    @ApiModelProperty(value = "生产项目id")
    private Long productProcessRouteItemId;
    @ApiModelProperty(value = "工单id")
    private String workOrderId;
    private Long workOrderId;
    @ApiModelProperty(value = "报工状态")
    private Integer status;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "更新时间")
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -1,8 +1,6 @@
package com.ruoyi.production.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -10,13 +8,14 @@
import java.time.LocalDateTime;
@Data
@TableName("production_product_output")
public class ProductionProductOutput {
    @TableId
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "报工id")
    private Long productionProductId;
    private Long productMainId;
    @ApiModelProperty(value = "产品id")
    private Long productModelId;
src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.production.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.dto.ProductWorkOrderDto;
import com.ruoyi.production.pojo.ProductWorkOrder;
public interface ProductWorkOrderService extends IService<ProductWorkOrder>{
    IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder);
    int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto);
}
src/main/java/com/ruoyi/production/service/ProductionProductInputService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.production.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.dto.ProductionProductInputDto;
import com.ruoyi.production.pojo.ProductionProductInput;
public interface ProductionProductInputService extends IService<ProductionProductInput> {
    IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, ProductionProductInputDto productionProductInputDto);
}
src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
@@ -12,4 +12,8 @@
public interface ProductionProductMainService extends IService<ProductionProductMain> {
    IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto);
    Boolean addProductMain(ProductionProductMainDto productionProductMainDto);
    Boolean removeProductMain(ProductionProductMainDto productionProductMainDto);
}
src/main/java/com/ruoyi/production/service/ProductionProductOutputService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.ruoyi.production.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.production.dto.ProductionProductOutputDto;
import com.ruoyi.production.pojo.ProductionProductOutput;
public interface ProductionProductOutputService extends IService<ProductionProductOutput> {
    IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, ProductionProductOutputDto productionProductOutputDto);
}
src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.production.service.impl;
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.ruoyi.production.dto.ProductWorkOrderDto;
import com.ruoyi.production.mapper.ProductWorkOrderMapper;
import com.ruoyi.production.pojo.ProductWorkOrder;
import com.ruoyi.production.service.ProductWorkOrderService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class ProductWorkOrderServiceImpl extends ServiceImpl<ProductWorkOrderMapper, ProductWorkOrder> implements ProductWorkOrderService {
    private ProductWorkOrderMapper productWorkOrdermapper;
    @Override
    public IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
        return productWorkOrdermapper.pageProductWorkOrder(page, productWorkOrder);
    }
    @Override
    public int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto) {
        return productWorkOrdermapper.updateById(productWorkOrderDto);
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductionProductInputServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.production.service.impl;
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.ruoyi.production.dto.ProductionProductInputDto;
import com.ruoyi.production.mapper.ProductionProductInputMapper;
import com.ruoyi.production.pojo.ProductionProductInput;
import com.ruoyi.production.service.ProductionProductInputService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@AllArgsConstructor
public class ProductionProductInputServiceImpl extends ServiceImpl<ProductionProductInputMapper, ProductionProductInput> implements ProductionProductInputService {
    @Autowired
    private ProductionProductInputMapper productionProductInputMapper;
    @Override
    public IPage<ProductionProductInputDto> listPageProductionProductInputDto(Page page, ProductionProductInputDto productionProductInputDto) {
        return productionProductInputMapper.listPageProductionProductInputDto(page, productionProductInputDto);
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -1,29 +1,258 @@
package com.ruoyi.production.service.impl;
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.ruoyi.production.dto.ProcessRouteItemDto;
import com.ruoyi.production.dto.ProductOrderDto;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.production.controller.ProductWorkOrderController;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.dto.ProductionProductMainDto;
import com.ruoyi.production.mapper.ProcessRouteItemMapper;
import com.ruoyi.production.mapper.ProductionProductMainMapper;
import com.ruoyi.production.pojo.ProductionProductMain;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.ProductionProductMainService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.mapper.QualityInspectParamMapper;
import com.ruoyi.quality.mapper.QualityTestStandardMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectParam;
import com.ruoyi.quality.pojo.QualityTestStandard;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.production.mapper.ProductionProductMainMapper;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@AllArgsConstructor
public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
    @Autowired
    private ProductionProductMainMapper productionProductMainMapper;
    private ProductWorkOrderController productWorkOrderController;
    private ProductWorkOrderMapper productWorkOrderMapper;
    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
    private ProductionProductOutputMapper productionProductOutputMapper;
    private ProcessRouteItemMapper processRouteItemMapper;
    private ProductModelMapper productModelMapper;
    private QualityInspectMapper qualityInspectMapper;
    private ProductProcessMapper productProcessMapper;
    private ProductMapper productMapper;
    private QualityTestStandardMapper qualityTestStandardMapper;
    private QualityInspectParamMapper qualityInspectParamMapper;
    private ProductStructureMapper productStructureMapper;
    private ProductionProductInputMapper productionProductInputMapper;
    private ProductOrderMapper productOrderMapper;
    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    @Override
    public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) {
        return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addProductMain(ProductionProductMainDto dto) {
        if (dto == null) {
            throw new RuntimeException("参数不能为空");
        }
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // æ–°å¢žé€»è¾‘
        ProductionProductMain productionProductMain = new ProductionProductMain();
        ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId());
        if (productProcessRouteItem == null) {
            throw new RuntimeException("工艺路线项不存在");
        }
        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        QueryWrapper<ProductionProductMain> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("MAX(product_no) as maxNo")
                .likeRight("product_no", datePrefix);
        List<Map<String, Object>> resultList = productionProductMainMapper.selectMaps(queryWrapper);
        int sequenceNumber = 1;
        if (resultList != null && !resultList.isEmpty()) {
            Map<String, Object> result = resultList.get(0);
            if (result != null) {
                Object maxNoObj = result.get("maxNo");
                if (maxNoObj != null) {
                    String lastNo = maxNoObj.toString();
                    System.out.println("lastNo: " + lastNo);
                    if (lastNo.startsWith(datePrefix)) {
                        try {
                            String seqStr = lastNo.substring(datePrefix.length());
                            sequenceNumber = Integer.parseInt(seqStr) + 1;
                        } catch (NumberFormatException e) {
                            sequenceNumber = 1;
                        }
                    }
                }
            }
        }
        String productNo = String.format("%s%03d", datePrefix, sequenceNumber);
        productionProductMain.setProductNo(productNo);
        productionProductMain.setUserId(user.getUserId());
        productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId());
        productionProductMain.setWorkOrderId(dto.getWorkOrderId());
        productionProductMain.setStatus(0);
        // æ·»åŠ æŠ¥å·¥ä¸»è¡¨
        int insert = productionProductMainMapper.insert(productionProductMain);
        //更新工单
        if (insert > 0) {
            Map<String, Object> params = new HashMap<>();
            params.put("quantity", dto.getQuantity());
            params.put("productMainId", productionProductMain.getId());
            params.put("workOrderId", dto.getWorkOrderId());
            params.put("deductQuantity", dto.getQuantity());
            productWorkOrderMapper.updatePlanQuantity(params);
        }
        ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId());
        ProductModel productModel = productProcessRouteItem.getProductModelId() != null ?
                productModelMapper.selectById(productProcessRouteItem.getProductModelId()) : null;
        if (productModel != null) {
            Product product = productMapper.selectById(productModel.getProductId());
            int inspectType = "组装".equals(productProcess.getName()) ? 2 : 1;
            QualityInspect qualityInspect = new QualityInspect();
            qualityInspect.setProductId(product.getId());
            qualityInspect.setProductName(product.getProductName());
            qualityInspect.setModel(productModel.getModel());
            qualityInspect.setUnit(productModel.getUnit());
            qualityInspect.setQuantity(dto.getQuantity());
            qualityInspect.setProcess(productProcess.getName());
            qualityInspect.setInspectState(0);
            qualityInspect.setInspectType(inspectType);
            qualityInspect.setProductMainId(productionProductMain.getId());
            qualityInspectMapper.insert(qualityInspect);
            qualityTestStandardMapper.selectList(
                    new LambdaQueryWrapper<QualityTestStandard>()
                            .eq(QualityTestStandard::getProductId, product.getId())
            ).forEach(standard -> {
                QualityInspectParam param = new QualityInspectParam();
                BeanUtils.copyProperties(standard, param);
                param.setId(null);
                param.setInspectId(qualityInspect.getId());
                qualityInspectParamMapper.insert(param);
            });
        }
        // æ·»åŠ æŠ•å…¥
        if (productModel != null) {
            List<ProductStructureDto> productStructureDtos = productStructureMapper.listByproductModelId(productModel.getId());
            for (ProductStructureDto productStructureDto : productStructureDtos) {
                ProductionProductInput productionProductInput = new ProductionProductInput();
                productionProductInput.setProductModelId(productStructureDto.getProductModelId());
                productionProductInput.setQuantity(productStructureDto.getUnitQuantity());
                productionProductInput.setProductMainId(productionProductMain.getId());
                productionProductInputMapper.insert(productionProductInput);
            }
        }
        // æ·»åŠ äº§å‡º
        ProductionProductOutput productionProductOutput = new ProductionProductOutput();
        productionProductOutput.setProductMainId(productionProductMain.getId());
        productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId());
        productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO);
        productionProductOutputMapper.insert(productionProductOutput);
        // èŽ·å–ç”Ÿäº§è®¢å•
        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
        ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
        if (productOrder == null) {
            throw new RuntimeException("生产订单不存在");
        }
        // æ·»åŠ ç”Ÿäº§æ ¸ç®—
        SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
                .salesLedgerWorkId(productionProductMain.getId())
                .salesLedgerSchedulingId(0L)
                .salesLedgerId(productOrder.getSalesLedgerId())
                .salesLedgerProductId(productOrder.getProductModelId())
                .schedulingUserId(user.getUserId())
                .schedulingUserName(user.getNickName())
                .finishedNum(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO)
                .workHours(productProcess.getSalaryQuota())
                .process(productProcess.getName())
                .schedulingDate(LocalDate.now())
                .tenantId(dto.getTenantId())
                .build();
        salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting);
        return true;
    }
    @Override
    @Transactional
    public Boolean removeProductMain(ProductionProductMainDto dto) {
        Long id = dto.getId();
        // æ›´æ–°å·¥å•
        productWorkOrderMapper.rollbackPlanQuantity(id);
        // åˆ é™¤è´¨æ£€å‚数和质检记录
        qualityInspectMapper.selectList(
                new LambdaQueryWrapper<QualityInspect>()
                        .eq(QualityInspect::getProductMainId, id)
        ).forEach(q -> {
            qualityInspectParamMapper.delete(
                    new LambdaQueryWrapper<QualityInspectParam>()
                            .eq(QualityInspectParam::getInspectId, q.getId()));
            qualityInspectMapper.deleteById(q.getId());
        });
        // åˆ é™¤äº§å‡ºè®°å½•
        productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
                .eq(ProductionProductOutput::getProductMainId, id)
        );
        // åˆ é™¤å…³è”的核算数据
        salesLedgerProductionAccountingMapper.delete(
                new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
                        .eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, id)
        );
        // åˆ é™¤ä¸»è¡¨
        return productionProductMainMapper.deleteById(id) > 0;
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductionProductOutputServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.production.service.impl;
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.ruoyi.production.dto.ProductionProductOutputDto;
import com.ruoyi.production.mapper.ProductionProductOutputMapper;
import com.ruoyi.production.pojo.ProductionProductOutput;
import com.ruoyi.production.service.ProductionProductOutputService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@AllArgsConstructor
public class ProductionProductOutputServiceImpl extends ServiceImpl<ProductionProductOutputMapper, ProductionProductOutput> implements ProductionProductOutputService {
    @Autowired
    private ProductionProductOutputMapper productionProductOutputMapper;
    @Override
    public IPage<ProductionProductOutputDto> listPageProductionProductOutputDto(Page page, ProductionProductOutputDto productionProductOutputDto) {
        return productionProductOutputMapper.listPageProductionProductOutputDto(page, productionProductOutputDto);
    }
}
src/main/java/com/ruoyi/purchase/controller/PurchaseLedgerController.java
@@ -1,5 +1,6 @@
package com.ruoyi.purchase.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -11,7 +12,10 @@
import com.ruoyi.purchase.dto.PurchaseLedgerDto;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.purchase.service.IPurchaseLedgerService;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
@@ -19,6 +23,7 @@
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
/**
 * é‡‡è´­å°è´¦Controller
@@ -29,10 +34,12 @@
@RestController
@RequestMapping("/purchase/ledger")
@AllArgsConstructor
@Api(tags = "111")
public class PurchaseLedgerController extends BaseController {
    private IPurchaseLedgerService purchaseLedgerService;
    private ISalesLedgerService salesLedgerService;
    private ISalesLedgerProductService salesLedgerProductService;
    /**
     * æŸ¥è¯¢é‡‡è´­å°è´¦åˆ—表
@@ -77,7 +84,42 @@
    public AjaxResult addOrEditPurchase(@RequestBody PurchaseLedgerDto purchaseLedgerDto) throws IOException {
        return toAjax(purchaseLedgerService.addOrEditPurchase(purchaseLedgerDto));
    }
    /**
     * æ–°å¢žé‡‡è´­æ¨¡æ¿
     */
    @PostMapping("/addPurchaseTemplate")
    public AjaxResult addPurchaseTemplate(@RequestBody PurchaseLedgerDto purchaseLedgerDto) throws IOException {
        return toAjax(purchaseLedgerService.addPurchaseTemplate(purchaseLedgerDto));
    }
    /**
     * æŸ¥è¯¢é‡‡è´­æ¨¡æ¿
     */
    @ApiOperation("/2222")
    @GetMapping("/getPurchaseTemplateList")
    public AjaxResult getPurchaseTemplateList() {
        PurchaseLedgerDto purchaseLedgerDto = new PurchaseLedgerDto();
        purchaseLedgerDto.setApprovalStatus(3);
        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerService.selectPurchaseLedgerListPage(new Page(1, -1), purchaseLedgerDto);
        List<PurchaseLedgerDto> purchaseLedgers = purchaseLedgerDtoIPage.getRecords();
        purchaseLedgers.forEach(purchaseLedgerDto1 -> {
            LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedgerDto1.getId())
                    .eq(SalesLedgerProduct::getType, 2);
            List<SalesLedgerProduct> list = salesLedgerProductService.list(queryWrapper);
            if (!list.isEmpty()) {
                purchaseLedgerDto1.setProductData(list);
            }
        });
        return AjaxResult.success(purchaseLedgers);
    }
    /**
     * ä¿®æ”¹é‡‡è´­å°è´¦å®¡æ‰¹çŠ¶æ€
     */
    @PostMapping("/updateApprovalStatus")
    public AjaxResult addOrEditPurchase(@RequestBody PurchaseLedger purchaseLedger){
        return toAjax(purchaseLedgerService.updateById(purchaseLedger));
    }
    /**
     * æŸ¥è¯¢é‡‡è´­å°è´¦å’Œäº§å“çˆ¶å­åˆ—表
     */
@@ -149,7 +191,10 @@
     */
    @GetMapping("/listPage")
    public AjaxResult listPage(Page page, PurchaseLedgerDto purchaseLedger) {
         return AjaxResult.success(purchaseLedgerService.selectPurchaseLedgerListPage(page ,purchaseLedger));
        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerService.selectPurchaseLedgerListPage(page ,purchaseLedger);
        //过滤掉approvalStatus=3的记录
        purchaseLedgerDtoIPage.getRecords().removeIf(purchaseLedgerDto -> purchaseLedgerDto.getApprovalStatus() == 3);
         return AjaxResult.success(purchaseLedgerDtoIPage);
    }
    @ApiOperation("生成采购序列号")
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -40,6 +40,11 @@
     */
    @Excel(name = "供应商名称")
    private String supplierName;
     /**
     * æ˜¯å¦ç™½åå•
     */
    @Excel(name = "是否白名单")
    private Integer isWhite;
    /**
     * å½•入人姓名id
@@ -180,5 +185,10 @@
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @ApiModelProperty("审批状态")
    private Integer approvalStatus;
    @ApiModelProperty(value = "模板名称")
    private String templateName;
    @ApiModelProperty(value = "审批人id")
    private Integer approverId;
}
src/main/java/com/ruoyi/purchase/pojo/PurchaseLedger.java
@@ -148,10 +148,14 @@
    @TableField(exist = false)
    private Integer type;
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @ApiModelProperty("审批状态")
    private Integer approvalStatus;
    @ApiModelProperty(value = "模板名称")
    private String templateName;
    @ApiModelProperty(value = "审批人id")
    private Integer approverId;
}
src/main/java/com/ruoyi/purchase/service/IPurchaseLedgerService.java
@@ -39,4 +39,6 @@
    List<InvoiceRegistrationProduct> getProductBySalesNo(Long id);
    String getPurchaseNo();
    int addPurchaseTemplate(PurchaseLedgerDto purchaseLedgerDto) throws IOException;
}
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -122,7 +122,49 @@
        }
        return purchaseLedgerMapper.selectList(queryWrapper);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addPurchaseTemplate(PurchaseLedgerDto purchaseLedgerDto)throws IOException {
        //录入人
        SysUser sysUser = userMapper.selectUserById(purchaseLedgerDto.getRecorderId());
        SupplierManage supplierManage = supplierManageMapper.selectById(purchaseLedgerDto.getSupplierId());
        PurchaseLedger purchaseLedger = new PurchaseLedger();
//        BeanUtils.copyProperties(purchaseLedger,purchaseLedgerDto);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if(ObjectUtils.isNotEmpty(loginUser) && null != loginUser.getTenantId()) {
            purchaseLedger.setTenantId(loginUser.getTenantId());
        }
        purchaseLedger.setPaymentMethod(purchaseLedgerDto.getPaymentMethod());
        purchaseLedger.setRecorderId(purchaseLedgerDto.getRecorderId());
        purchaseLedger.setSupplierId(purchaseLedgerDto.getSupplierId());
        purchaseLedger.setTemplateName(purchaseLedgerDto.getTemplateName());
//        purchaseLedger.setSalesLedgerPId(purchaseLedgerDto.getSalesLedgerId());
        purchaseLedger.setApprovalStatus(3);
        purchaseLedger.setSupplierName(supplierManage.getSupplierName());
        purchaseLedger.setRecorderName(sysUser.getNickName());
        purchaseLedger.setPhoneNumber(sysUser.getPhonenumber());
        purchaseLedger.setPurchaseContractNumber(UUID.randomUUID().toString().replaceAll("-", ""));
        purchaseLedger.setEntryDate(Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()));
        int insert = purchaseLedgerMapper.insert(purchaseLedger);
        LambdaQueryWrapper<PurchaseLedger> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PurchaseLedger::getSupplierName, purchaseLedger.getSupplierName())
                .eq(PurchaseLedger::getPurchaseContractNumber, purchaseLedger.getPurchaseContractNumber())
                .eq(PurchaseLedger::getApprovalStatus,3);
        PurchaseLedger purchaseLedger1 = purchaseLedgerMapper.selectOne(queryWrapper);
        if(ObjectUtils.isNotEmpty(purchaseLedgerDto.getProductData())) {
            // 4. å¤„理子表数据
            List<SalesLedgerProduct> salesLedgerProductList = purchaseLedgerDto.getProductData();
            salesLedgerProductList.forEach(salesLedgerProduct -> {
                salesLedgerProduct.setSalesLedgerId(purchaseLedger1.getId());
                salesLedgerProduct.setType(2);
            });
            salesLedgerProductList.forEach(salesLedgerProductMapper::insert);
        }
        return insert;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrEditPurchase(PurchaseLedgerDto purchaseLedgerDto) throws IOException {
@@ -169,7 +211,7 @@
            PurchaseLedger purchaseLedgerDB = purchaseLedgerMapper.selectById(purchaseLedger.getId());
            List<AccountExpense> accountExpenseDBs = accountExpenseService.getByInvoiceNumberList(purchaseLedger.getPurchaseContractNumber());
            if (!CollectionUtils.isEmpty(accountExpenseDBs)) {
                accountExpenseDBs.forEach(accountExpenseDB -> {
                accountExpenseDBs.forEach(accountExpenseDB ->{
                    accountExpenseDB.setExpenseDate(purchaseLedgerDB.getEntryDate());
                    accountExpenseDB.setExpenseType("0");
                    accountExpenseDB.setSupplierName(purchaseLedgerDB.getSupplierName());
@@ -383,7 +425,7 @@
    @Override
    public int deletePurchaseLedgerByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new BaseException("请选中至少一条数据");
           throw new BaseException("请选中至少一条数据");
        }
        // æ‰¹é‡åˆ é™¤å…³è”的采购台账产品
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
@@ -392,11 +434,11 @@
        salesLedgerProductMapper.delete(queryWrapper);
        // æ‰¹é‡åˆ é™¤å…³è”的采购台账的来票登记
        LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getPurchaseLedgerId, ids);
        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getSalesLedgerId,ids);
        ticketRegistrationMapper.delete(ticketRegistrationLambdaQueryWrapper);
        // æ‰¹é‡åˆ é™¤å…³è”的采购台账的来票登记记录
        LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productRecordLambdaQueryWrapper.in(ProductRecord::getPurchaseLedgerId, ids);
        productRecordLambdaQueryWrapper.in(ProductRecord::getPurchaseLedgerId,ids);
        productRecordMapper.delete(productRecordLambdaQueryWrapper);
        // æ‰¹é‡åˆ é™¤ä»˜æ¬¾ç™»è®°
        LambdaQueryWrapper<PaymentRegistration> paymentRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -410,9 +452,12 @@
                .map(QualityInspect::getId)
                .collect(Collectors.toList());
        LambdaQueryWrapper<QualityInspectParam> qualityStandardLambdaQueryWrapper = new LambdaQueryWrapper<>();
        qualityStandardLambdaQueryWrapper.in(QualityInspectParam::getInspectId, inspectIds);
        qualityInspectParamMapper.delete(qualityStandardLambdaQueryWrapper);
        if (inspectIds.size() > 0) {
            LambdaQueryWrapper<QualityInspectParam> qualityStandardLambdaQueryWrapper = new LambdaQueryWrapper<>();
            qualityStandardLambdaQueryWrapper.in(QualityInspectParam::getInspectId, inspectIds);
            qualityInspectParamMapper.delete(qualityStandardLambdaQueryWrapper);
        }
        //批量删除原材料检验数据
        qualityInspectMapper.delete(materialInspectLambdaQueryWrapper);
        // æ‰¹é‡åˆ é™¤é‡‡è´­å°è´¦
@@ -436,7 +481,7 @@
        // 3.查询上传文件
        LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>();
        salesLedgerFileWrapper.eq(CommonFile::getCommonId, purchaseLedger.getId())
                .eq(CommonFile::getType, FileNameType.PURCHASE.getValue());
                .eq(CommonFile::getType,FileNameType.PURCHASE.getValue());
        List<CommonFile> salesLedgerFiles = commonFileMapper.selectList(salesLedgerFileWrapper);
        // 4. è½¬æ¢ DTO
src/main/java/com/ruoyi/quality/mapper/QualityInspectMapper.java
@@ -17,4 +17,9 @@
    IPage<QualityInspect> qualityInspectListPage(Page page, @Param("qualityInspect") QualityInspect qualityInspect);
    List<QualityInspect> qualityInspectExport(@Param("qualityInspect") QualityInspect qualityInspect);
    /**
     * æ ¹æ®ç”Ÿäº§ä¸»è¡¨ID批量删除过程检验
     */
    int deleteByProductMainIds(@Param("productMainIds") List<Long> productMainIds);
}
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -140,5 +140,10 @@
    private Long purchaseLedgerId;
    /**
     * æŠ¥å·¥id
     */
    private Long productMainId;
}
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.mapper.ShipmentApprovalMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShipmentApproval;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ShipmentApprovalService;
import com.ruoyi.sales.service.ShippingInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@RestController
@RequestMapping("/shipmentApproval")
@Api(tags = "发货审批管理")
public class ShipmentApprovalController extends BaseController {
    @Autowired
    private ShipmentApprovalService shipmentApprovalService;
    @Autowired
    private ShipmentApprovalMapper shipmentApprovalMapper;
    @Autowired
    private ISalesLedgerProductService salesLedgerProductService;
    @GetMapping("/listPage")
    @ApiOperation("发货审批列表")
    public AjaxResult listPage(Page page, ShipmentApproval req) {
        IPage<ShipmentApproval> listPage = shipmentApprovalService.listPage(page,req);
        return AjaxResult.success(listPage);
    }
    @PostMapping("/update")
    @ApiOperation("发货审批,更新发货审批状态")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody ShipmentApproval req) {
        ShipmentApproval shipmentApproval = shipmentApprovalMapper.selectById(req.getId());
        if (shipmentApproval == null) {
            return AjaxResult.error("发货审批不存在");
        }
        shipmentApproval.setApproveStatus(req.getApproveStatus());
        boolean update = shipmentApprovalService.updateById(shipmentApproval);
        if(update){
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductService.getById(shipmentApproval.getSalesLedgerProductId());
            salesLedgerProduct.setApproveStatus(req.getApproveStatus());
            salesLedgerProductService.updateById(salesLedgerProduct);
        }
        return update ? AjaxResult.success() : AjaxResult.error();
    }
    /**
     * å¯¼å‡ºå‘货信息管理
     */
    @PostMapping("/export")
    @ApiOperation("导出发货审批")
    public void export(HttpServletResponse response) {
        List<ShipmentApproval> list = shipmentApprovalService.list(null);
        ExcelUtil<ShipmentApproval> util = new ExcelUtil<ShipmentApproval>(ShipmentApproval.class);
        util.exportExcel(response, list, "发货审批");
    }
}
src/main/java/com/ruoyi/sales/controller/ShippingInfoController.java
@@ -1,5 +1,6 @@
package com.ruoyi.sales.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -7,13 +8,20 @@
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.mapper.ShipmentApprovalMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShipmentApproval;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import com.ruoyi.sales.service.ShippingInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
@@ -30,6 +38,10 @@
    @Autowired
    private ShippingInfoService shippingInfoService;
    @Autowired
    private ShipmentApprovalMapper shipmentApprovalMapper;
    @Autowired
    private ISalesLedgerProductService salesLedgerProductService;
    @GetMapping("/listPage")
@@ -41,8 +53,33 @@
    @PostMapping("/add")
    @ApiOperation("添加发货信息")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody ShippingInfo req) {
        LambdaQueryWrapper<ShippingInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShippingInfo::getSalesLedgerId, req.getSalesLedgerId());
        wrapper.eq(ShippingInfo::getSalesLedgerProductId, req.getSalesLedgerProductId());
        List<ShippingInfo> list = shippingInfoService.list(wrapper);
        if(!CollectionUtils.isEmpty(list)){
            return AjaxResult.error("发货信息已存在");
        }
        boolean save = shippingInfoService.save(req);
        if(save){
            ShippingInfo shippingInfo = shippingInfoService.getOne(wrapper);
            ShipmentApproval shipmentApproval = new ShipmentApproval();
            shipmentApproval.setSalesLedgerId(req.getSalesLedgerId());
            shipmentApproval.setSalesLedgerProductId(req.getSalesLedgerProductId());
            shipmentApproval.setApproveUserId(req.getApproverId());
            shipmentApproval.setApproveStatus(2);
            shipmentApproval.setShippingInfoId(shippingInfo.getId());
            shipmentApprovalMapper.insert(shipmentApproval);
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductService.getById(req.getSalesLedgerProductId());
            if(salesLedgerProduct != null){
                salesLedgerProduct.setApproveStatus(2);
                salesLedgerProductService.updateById(salesLedgerProduct);
            }
        }
        return save ? AjaxResult.success() : AjaxResult.error();
    }
src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -2,6 +2,9 @@
import com.ruoyi.common.config.MyBaseMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * äº§å“ä¿¡æ¯Mapper接口
@@ -10,4 +13,5 @@
 * @date 2025-05-08
 */
public interface SalesLedgerProductMapper extends MyBaseMapper<SalesLedgerProduct> {
    List<SalesLedgerProduct> selectSalesLedgerProductList(@Param("salesLedgerProduct") SalesLedgerProduct salesLedgerProduct);
}
src/main/java/com/ruoyi/sales/mapper/ShipmentApprovalMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.ruoyi.sales.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.sales.pojo.ShipmentApproval;
import com.ruoyi.sales.pojo.ShippingInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ShipmentApprovalMapper extends BaseMapper<ShipmentApproval> {
    IPage<ShipmentApproval> listPage(Page page,@Param("req") ShipmentApproval req);
}
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -140,5 +140,9 @@
    @ApiModelProperty(value = "付款方式")
    private String paymentMethod;
    @TableField(exist = false)
    @ApiModelProperty(value = "生产状态")
    private String productionStatus = "未开始";
}
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -9,8 +9,10 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * äº§å“ä¿¡æ¯å¯¹è±¡ sales_ledger_product
@@ -20,7 +22,7 @@
 */
@TableName("sales_ledger_product")
@Data
public class SalesLedgerProduct {
public class SalesLedgerProduct implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
@@ -183,4 +185,28 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "登记日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime registerDate;
    /**
     * å‘货车牌号
     */
    @Excel(name = "发货车牌号")
    @TableField(exist = false)
    private String shippingCarNumber;
    /**
     * å‘货日期
     */
    @Excel(name = "发货日期", width = 30, dateFormat = "yyyy-MM-dd")
    @TableField(exist = false)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date shippingDate;
    @TableField(exist = false)
    @ApiModelProperty(value = "生产状态")
    private String productionStatus = "未开始";
    /**
     * å‘货审批状态
     */
//    @TableField(exist = false)
    @ApiModelProperty(value = "审批状态")
    private Integer approveStatus;
}
src/main/java/com/ruoyi/sales/pojo/ShipmentApproval.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,352 @@
package com.ruoyi.sales.pojo;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
@Data
@TableName("shipment_approval")
public class ShipmentApproval {
    @TableId(type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "发货信息id")
    private Long shippingInfoId;
    @ApiModelProperty(value = "销售台账id")
    private Long salesLedgerId;
    @ApiModelProperty(value = "销售报价产品表id")
    private Long salesLedgerProductId;
     @ApiModelProperty(value = "申请部门id")
    private Long approveDeptId;
    @ApiModelProperty(value = "申请部门名称")
    @Excel(name = "申请部门")
    private String approveDeptName;
     @ApiModelProperty(value = "审批用户id")
    private Integer approveUserId;
    @ApiModelProperty(value = "审批用户名称")
    @Excel(name = "审批用户")
    private String approveUserNames;
    /**
     * å®¡æ‰¹çŠ¶æ€
     */
    @ApiModelProperty(value = "审批状态:0未出库,1已出库,2待审核,3审核完成,4审核失败")
    @Excel(name = "审批状态", readConverterExp = "0=未出库,1=已出库,2=待审核,3=审核完成,4=审核失败")
    private Integer approveStatus;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @ApiModelProperty(value = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Integer createUser;
    @ApiModelProperty(value = "修改用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "发货日期", width = 30, dateFormat = "yyyy-MM-dd")
    @TableField(exist = false)
    private Date shippingDate;
    @Excel(name = "发货车牌号")
    @TableField(exist = false)
    private String shippingCarNumber;
    /**
     * é¢„警数量
     */
    @TableField(exist = false)
    private BigDecimal warnNum;
    /**
     * äº§å“å¤§ç±»
     */
    @Excel(name = "产品大类")
    @TableField(exist = false)
    private String productCategory;
    /**
     * è§„格型号
     */
    @Excel(name = "规格型号")
    @TableField(exist = false)
    private String specificationModel;
    /**
     * å•位
     */
    @Excel(name = "单位")
    @TableField(exist = false)
    private String unit;
    /**
     * æ•°é‡
     */
    @Excel(name = "数量")
    @TableField(exist = false)
    private BigDecimal quantity;
    @Excel(name = "最低库存数量")
    @TableField(exist = false)
    private BigDecimal minStock;
    /**
     * ç¨Žçއ
     */
    @Excel(name = "税率")
    @TableField(exist = false)
    private BigDecimal taxRate;
    /**
     * å«ç¨Žå•ä»·
     */
    @Excel(name = "含税单价")
    @TableField(exist = false)
    private BigDecimal taxInclusiveUnitPrice;
    /**
     * å«ç¨Žæ€»ä»·
     */
    @Excel(name = "含税总价")
    @TableField(exist = false)
    private BigDecimal taxInclusiveTotalPrice;
    /**
     * ä¸å«ç¨Žæ€»ä»·
     */
    @Excel(name = "不含税总价")
    @TableField(exist = false)
    private BigDecimal taxExclusiveTotalPrice;
    /**
     * å‘票类型
     */
    @TableField(exist = false)
    private String invoiceType;
    /**
     * å°è´¦ç±»åž‹ 1.销售 2,采购
     */
    @TableField(exist = false)
    private Integer type;
    /**
     * æœ¬æ¬¡æ¥ç¥¨æ•°
     */
    @TableField(exist = false)
    private BigDecimal ticketsNum;
    /**
     * æœ¬æ¬¡æ¥ç¥¨é‡‘额(元)
     */
    @TableField(exist = false)
    private BigDecimal ticketsAmount;
    /**
     * æœªæ¥ç¥¨æ•°
     */
    @TableField(exist = false)
    private BigDecimal futureTickets;
    /**
     * æœªæ¥ç¥¨é‡‘额(元)
     */
    @TableField(exist = false)
    private BigDecimal futureTicketsAmount;
    @ApiModelProperty(value = "开票数")
    @TableField(exist = false)
    private BigDecimal invoiceNum;
    @ApiModelProperty(value = "未开票数")
    @TableField(exist = false)
    private BigDecimal noInvoiceNum;
    @ApiModelProperty(value = "开票金额")
    @TableField(exist = false)
    private BigDecimal invoiceAmount;
    @ApiModelProperty(value = "未开票金额")
    @TableField(exist = false)
    private BigDecimal noInvoiceAmount;
    @ApiModelProperty(value = "本次开票数")
    @TableField(exist = false)
    private BigDecimal currentInvoiceNum;
    @TableField(exist = false)
    @ApiModelProperty(value = "本次开票金额")
    private BigDecimal currentInvoiceAmount;
    /**
     *  äº§å“id
     */
    @TableField(exist = false)
    private Long productId;
    /**
     * äº§å“è§„æ ¼id
     */
    @TableField(exist = false)
    private Long productModelId;
    @ApiModelProperty(value = "初始未开票数")
    @TableField(exist = false)
    private BigDecimal originalNoInvoiceNum;
    @ApiModelProperty(value = "临时未开票数")
    @TableField(exist = false)
    private BigDecimal tempNoInvoiceNum;
    @ApiModelProperty(value = "临时未开票金额")
    @TableField(exist = false)
    private BigDecimal tempnoInvoiceAmount;
    @ApiModelProperty(value = "临时未来票数")
    @TableField(exist = false)
    private BigDecimal tempFutureTickets;
    @ApiModelProperty(value = "临时未来票金额")
    @TableField(exist = false)
    private BigDecimal tempFutureTicketsAmount;
    @ApiModelProperty("登记人")
    @TableField(exist = false)
    private String register;
    @ApiModelProperty("登记日期")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "登记日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
    @TableField(exist = false)
    private LocalDateTime registerDate;
    /**
     * é”€å”®åˆåŒå·
     */
    @Excel(name = "销售合同号")
    @TableField(exist = false)
    private String salesContractNo;
    /**
     * å®¢æˆ·åˆåŒå·
     */
    @Excel(name = "客户合同号")
    @TableField(exist = false)
    private String customerContractNo;
    /**
     * é¡¹ç›®åç§°
     */
    @Excel(name = "项目名称")
    @TableField(exist = false)
    private String projectName;
    /**
     * å½•入日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @TableField(exist = false)
    private Date entryDate;
    /**
     * ä¸šåŠ¡å‘˜
     */
    @Excel(name = "业务员")
    @TableField(exist = false)
    private String salesman;
    @TableField(exist = false)
    private Long customerId;
    /**
     * å®¢æˆ·åç§°
     */
    @Excel(name = "客户名称")
    @TableField(exist = false)
    private String customerName;
    /**
     * å½•入人
     */
    @TableField(exist = false)
    private String entryPerson;
    @TableField(exist = false)
    @ApiModelProperty(value = "录入人")
    @Excel(name = "录入人")
    private String entryPersonName;
    /**
     * å¤‡æ³¨
     */
    @Excel(name = "备注")
    @TableField(exist = false)
    private String remarks;
    /**
     * é™„件材料,存储文件名等相关信息
     */
    @TableField(exist = false)
    private String attachmentMaterials;
    /**
     * åˆåŒé‡‘额(产品含税总价)
     */
    @Excel(name = "合同金额")
    @TableField(exist = false)
    private BigDecimal contractAmount;
    @TableField(exist = false)
    @ApiModelProperty(value = "未开票金额(元)")
    @Excel(name = "未开票金额")
    private BigDecimal noInvoiceAmountTotal = BigDecimal.ZERO;
    @ApiModelProperty(value = "签订日期")
    @TableField(exist = false)
    private LocalDate executionDate;
    @TableField(exist = false)
    @ApiModelProperty(value = "已开票金额(元)")
    @Excel(name = "已开票金额")
    private BigDecimal invoiceTotal = BigDecimal.ZERO;
    @TableField(exist = false)
    @ApiModelProperty(value = "回款金额")
    private BigDecimal receiptPaymentAmountTotal = BigDecimal.ZERO;
    @TableField(exist = false)
    @ApiModelProperty(value = "待回款金额")
    private BigDecimal noReceiptAmount = BigDecimal.ZERO;
    @ApiModelProperty(value = "付款方式")
    @TableField(exist = false)
    private String paymentMethod;
    @TableField(exist = false)
    @ApiModelProperty(value = "生产状态")
    private String productionStatus = "未开始";
}
src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
@@ -23,7 +23,8 @@
    @ApiModelProperty(value = "销售台账id")
    private Long salesLedgerId;
    @ApiModelProperty(value = "销售报价产品表id")
    private Long salesLedgerProductId;
    @TableField(exist = false)
    @ApiModelProperty(value = "销售合同号")
    @Excel(name = "销售合同号")
@@ -64,5 +65,8 @@
    @ApiModelProperty(value = "租户ID")
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    @ApiModelProperty(value = "审批人id")
    @TableField(exist = false)
    private Integer approverId;
}
src/main/java/com/ruoyi/sales/service/ShipmentApprovalService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.ruoyi.sales.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.sales.pojo.ShipmentApproval;
import com.ruoyi.sales.pojo.ShippingInfo;
public interface ShipmentApprovalService extends IService<ShipmentApproval>{
    IPage<ShipmentApproval> listPage(Page page, ShipmentApproval req);
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -4,14 +4,8 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.production.mapper.ProcessRouteItemMapper;
import com.ruoyi.production.mapper.ProcessRouteMapper;
import com.ruoyi.production.mapper.ProductOrderMapper;
import com.ruoyi.production.mapper.ProductProcessRouteItemMapper;
import com.ruoyi.production.pojo.ProcessRoute;
import com.ruoyi.production.pojo.ProcessRouteItem;
import com.ruoyi.production.pojo.ProductOrder;
import com.ruoyi.production.pojo.ProductProcessRouteItem;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.sales.dto.InvoiceRegistrationProductDto;
@@ -30,6 +24,8 @@
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -53,11 +49,14 @@
    private ProductOrderMapper productOrderMapper;
    private ProcessRouteItemMapper processRouteItemMapper;
    private ProductProcessRouteItemMapper productProcessRouteItemMapper;
    @Autowired
    private InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
    @Autowired
    private ProcessRouteMapper processRouteMapper;
    private ProductWorkOrderMapper productWorkOrderMapper;
    @Override
    public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -66,11 +65,11 @@
    @Override
    public List<SalesLedgerProduct> selectSalesLedgerProductList(SalesLedgerProduct salesLedgerProduct) {
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerProduct.getSalesLedgerId())
                .eq(SalesLedgerProduct::getType, salesLedgerProduct.getType());
        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(salesLedgerProducts)) {
//        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerProduct.getSalesLedgerId())
//                .eq(SalesLedgerProduct::getType, salesLedgerProduct.getType());
        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectSalesLedgerProductList(salesLedgerProduct);
        if(!CollectionUtils.isEmpty(salesLedgerProducts)){
            InvoiceRegistrationProductDto invoiceRegistrationProductDto = new InvoiceRegistrationProductDto();
            invoiceRegistrationProductDto.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId().intValue());
            List<InvoiceRegistrationProductDto> invoiceRegistrationProductDtoList = invoiceRegistrationProductMapper.invoiceRegistrationProductList(invoiceRegistrationProductDto);
@@ -80,8 +79,8 @@
                    BigDecimal invoiceNum = BigDecimal.ZERO;
                    BigDecimal invoiceAmount = BigDecimal.ZERO;
                    for (InvoiceRegistrationProductDto registrationProductDto : invoiceRegistrationProductDtoList) {
                        if (ledgerProduct.getId().intValue() == registrationProductDto.getSalesLedgerProductId()) {
                            invoiceNum = invoiceNum.add(registrationProductDto.getInvoiceNum());
                        if(ledgerProduct.getId().intValue() == registrationProductDto.getSalesLedgerProductId()){
                            invoiceNum =  invoiceNum.add(registrationProductDto.getInvoiceNum());
                            invoiceAmount = invoiceAmount.add(registrationProductDto.getInvoiceAmount());
                        }
                    }
@@ -107,7 +106,7 @@
            return 0; // æ²¡æœ‰å¯åˆ é™¤çš„æ•°æ®
        }
        // å¯èƒ½å±žäºŽå¤šä¸ªä¸»è¡¨ï¼ˆä½†é€šå¸¸ä¸€ä¸ªæŽ¥å£åªå¤„理一个主表)
        // å¯èƒ½å±žäºŽå¤šä¸ªä¸»è¡¨
        Set<Long> mainIds = deletedProducts.stream()
                .map(SalesLedgerProduct::getSalesLedgerId)
                .filter(Objects::nonNull)
@@ -116,12 +115,40 @@
        // 2. æ‰§è¡Œåˆ é™¤æ“ä½œ
        int result = salesLedgerProductMapper.deleteBatchIds(Arrays.asList(ids));
        //删除对应的生产订单
        for (Long id : ids) {
            ProductOrder productOrder = productOrderMapper.selectOne(new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getProductModelId, id));
            if (productOrder != null) {
                productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>().eq(ProductProcessRouteItem::getRouteId, productOrder.getId()));
                productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getProductModelId, id));
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
                        .in(ProductOrder::getProductModelId, ids)
        );
        if (!CollectionUtils.isEmpty(productOrders)) {
            List<Long> orderIds = productOrders.stream()
                    .map(ProductOrder::getId)
                    .collect(Collectors.toList());
            // æ‰¹é‡æŸ¥è¯¢processRouteItems
            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                    new LambdaQueryWrapper<ProductProcessRouteItem>()
                            .in(ProductProcessRouteItem::getRouteId, orderIds)
            );
            if (!CollectionUtils.isEmpty(allRouteItems)) {
                List<Long> routeItemIds = allRouteItems.stream()
                        .map(ProductProcessRouteItem::getId)
                        .collect(Collectors.toList());
                // æ‰¹é‡åˆ é™¤workOrder
                productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
                                .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
            }
            // æ‰¹é‡åˆ é™¤processRouteItem
            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
                            .in(ProductProcessRouteItem::getRouteId, orderIds));
            // æ‰¹é‡åˆ é™¤productOrder
            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
                    .in(ProductOrder::getProductModelId, ids));
        }
        // 3. å¯¹æ¯ä¸ªä¸»è¡¨ID进行金额更新
@@ -161,12 +188,47 @@
            ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
            if (processRoute != null) {
                List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
                // ç”Ÿæˆå½“前日期的前缀:年月日
                String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                for (ProcessRouteItem processRouteItem : processRouteItems) {
                    ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                    productProcessRouteItem.setProductModelId(productOrder.getProductModelId());
                    productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                    productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                    productProcessRouteItem.setRouteId(productOrder.getId());
                    productProcessRouteItemMapper.insert(productProcessRouteItem);
                    int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                    if (insert > 0) {
                        // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
                        QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                        queryWrapper.likeRight("work_order_no", datePrefix)
                                .orderByDesc("work_order_no")
                                .last("LIMIT 1");
                        ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                        int sequenceNumber = 1; // é»˜è®¤åºå·
                        if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                            String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                            if (lastNo.startsWith(datePrefix)) {
                                String seqStr = lastNo.substring(datePrefix.length());
                                try {
                                    sequenceNumber = Integer.parseInt(seqStr) + 1;
                                } catch (NumberFormatException e) {
                                    sequenceNumber = 1;
                                }
                            }
                        }
                        // ç”Ÿæˆå®Œæ•´çš„工单号
                        String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                        ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                        productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                        productWorkOrder.setProductOrderId(productOrder.getId());
                        productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
                        productWorkOrder.setWorkOrderNo(workOrderNoStr);
                        productWorkOrder.setStatus(1);
                        productWorkOrderMapper.insert(productWorkOrder);
                    }
                }
                productOrder.setRouteId(processRoute.getId());
                productOrderMapper.updateById(productOrder);
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -9,7 +9,6 @@
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.account.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.basic.mapper.CustomerMapper;
@@ -24,6 +23,7 @@
import com.ruoyi.production.pojo.*;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.sales.dto.MonthlyAmountDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.mapper.*;
@@ -99,6 +99,16 @@
    private final ProcessRouteItemMapper processRouteItemMapper;
    private final ProductProcessRouteItemMapper productProcessRouteItemMapper;
    private final ProductWorkOrderMapper productWorkOrderMapper;
    private final ProductionProductMainMapper productionProductMainMapper;
    private final ProductionProductOutputMapper productionProductOutputMapper;
    private final ProductionProductInputMapper productionProductInputMapper;
    private final QualityInspectMapper qualityInspectMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
@@ -366,10 +376,85 @@
            return 0;
        }
        // åˆ é™¤é”€å”®ç®¡ç†æ•°æ®
        // 1. å…ˆåˆ é™¤å­è¡¨æ•°æ®
        LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList);
        salesLedgerProductMapper.delete(productWrapper);
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList)
                .select(SalesLedgerProduct::getId);
        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(queryWrapper);
        List<Long> productIds = products.stream()
                .map(SalesLedgerProduct::getId)
                .collect(Collectors.toList());
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
                        .in(ProductOrder::getProductModelId, productIds)
        );
        if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) {
            List<Long> orderIds = productOrders.stream()
                    .map(ProductOrder::getId)
                    .collect(Collectors.toList());
            // æ‰¹é‡æŸ¥è¯¢processRouteItems
            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                    new LambdaQueryWrapper<ProductProcessRouteItem>()
                            .in(ProductProcessRouteItem::getRouteId, orderIds)
            );
            if (!CollectionUtils.isEmpty(allRouteItems)) {
                // èŽ·å–è¦åˆ é™¤çš„å·¥åºé¡¹ID
                List<Long> routeItemIds = allRouteItems.stream()
                        .map(ProductProcessRouteItem::getId)
                        .collect(Collectors.toList());
                // æŸ¥è¯¢å…³è”的工单ID
                List<ProductWorkOrder> workOrders = productWorkOrderMapper.selectList(
                        new LambdaQueryWrapper<ProductWorkOrder>()
                                .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds)
                );
                if (!CollectionUtils.isEmpty(workOrders)) {
                    List<Long> workOrderIds = workOrders.stream()
                            .map(ProductWorkOrder::getId)
                            .collect(Collectors.toList());
                    // æŸ¥è¯¢å…³è”的生产主表ID
                    List<ProductionProductMain> productMains = productionProductMainMapper.selectList(
                            new LambdaQueryWrapper<ProductionProductMain>()
                                    .in(ProductionProductMain::getWorkOrderId, workOrderIds)
                    );
                    List<Long> productMainIds = productMains.stream()
                            .map(ProductionProductMain::getId)
                            .collect(Collectors.toList());
                    // åˆ é™¤äº§å‡ºè¡¨ã€æŠ•入表数据
                    if (!CollectionUtils.isEmpty(productMainIds)) {
                        productionProductOutputMapper.deleteByProductMainIds(productMainIds);
                        productionProductInputMapper.deleteByProductMainIds(productMainIds);
                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
                    }
                    // åˆ é™¤ç”Ÿäº§ä¸»è¡¨æ•°æ®
                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
                    // åˆ é™¤å·¥å•数据
                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
                }
            }
            // æ‰¹é‡åˆ é™¤processRouteItem
            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
                    .in(ProductProcessRouteItem::getRouteId, orderIds));
            // æ‰¹é‡åˆ é™¤productOrder
            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
                    .in(ProductOrder::getProductModelId, productIds));
        }
        // æ‰¹é‡åˆ é™¤äº§å“å­è¡¨
        if (!productIds.isEmpty()) {
            salesLedgerProductMapper.deleteBatchIds(productIds);
        }
        LambdaQueryWrapper<InvoiceRegistrationProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(InvoiceRegistrationProduct::getSalesLedgerId, idList);
@@ -394,7 +479,6 @@
            wrapperTree.in(ReceiptPayment::getInvoiceLedgerId, invoiceLedgerIds);
            receiptPaymentMapper.delete(wrapperTree);
        }
        // åˆ é™¤ç”Ÿäº§ç®¡æŽ§æ•°æ®
        // åˆ é™¤ç”Ÿäº§è®¢å•数据
@@ -596,12 +680,48 @@
                ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
                if (processRoute != null) {
                    List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
                    // ç”Ÿæˆå½“前日期的前缀:年月日
                    String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                    int dragSort = 1;
                    for (ProcessRouteItem processRouteItem : processRouteItems) {
                        ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                        productProcessRouteItem.setProductModelId(productOrder.getProductModelId());
                        productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                        productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                        productProcessRouteItem.setRouteId(productOrder.getId());
                        productProcessRouteItemMapper.insert(productProcessRouteItem);
                        productProcessRouteItem.setDragSort(dragSort);
                        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                        if (insert > 0) {
                            // æŸ¥è¯¢ä»Šæ—¥å·²å­˜åœ¨çš„æœ€å¤§å·¥å•号
                            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                            queryWrapper.likeRight("work_order_no", datePrefix)
                                    .orderByDesc("work_order_no")
                                    .last("LIMIT 1");
                            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                            int sequenceNumber = 1; // é»˜è®¤åºå·
                            if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                                String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                                if (lastNo.startsWith(datePrefix)) {
                                    String seqStr = lastNo.substring(datePrefix.length());
                                    try {
                                        sequenceNumber = Integer.parseInt(seqStr) + 1;
                                    } catch (NumberFormatException e) {
                                        sequenceNumber = 1;
                                    }
                                }
                            }
                            // ç”Ÿæˆå®Œæ•´çš„工单号
                            String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                            ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                            productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                            productWorkOrder.setProductOrderId(productOrder.getId());
                            productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
                            productWorkOrder.setWorkOrderNo(workOrderNoStr);
                            productWorkOrder.setStatus(1);
                            productWorkOrderMapper.insert(productWorkOrder);
                        }
                        dragSort++;
                    }
                    productOrder.setRouteId(processRoute.getId());
                    productOrderMapper.updateById(productOrder);
@@ -659,12 +779,12 @@
            return datePart + String.format("%03d", nextSequence);
        } finally {
            // 3. é‡Šæ”¾é”ï¼ˆä½¿ç”¨Lua脚本保证原子性,避免误删其他线程的锁)
            // 3. é‡Šæ”¾é”
            String luaScript = "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end";
            redisTemplate.execute(
                    new DefaultRedisScript<>(luaScript, Long.class),
                    Collections.singletonList(lockKey),
                    lockValue // åªæœ‰æŒæœ‰ç›¸åŒå€¼çš„线程才能删除锁
                    lockValue
            );
        }
    }
@@ -673,7 +793,7 @@
        if (sequences.isEmpty()) {
            return 1;
        }
        // æŽ’序后查找第一个缺失的正整数(与原逻辑一致)
        // æŽ’序后查找第一个缺失的正整数
        sequences.sort(Integer::compareTo);
        int next = 1;
        for (int seq : sequences) {
@@ -703,14 +823,13 @@
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // æž„造主表更新对象(支持任意主表类型)
        // æž„造主表更新对象
        try {
            S entity = mainEntityClass.getDeclaredConstructor().newInstance();
            Field idField = mainEntityClass.getDeclaredField("id");
            idField.setAccessible(true);
            idField.set(entity, mainId);
            // è®¾ç½® contractAmount å­—段,注意这里假设字段名为 "contractAmount"
            Field amountField = mainEntityClass.getDeclaredField("contractAmount");
            amountField.setAccessible(true);
            amountField.set(entity, totalAmount);
src/main/java/com/ruoyi/sales/service/impl/ShipmentApprovalServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.sales.service.impl;
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.ruoyi.sales.mapper.ShipmentApprovalMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.ShipmentApproval;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ShipmentApprovalService;
import com.ruoyi.sales.service.ShippingInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author :yys
 * @date : 2025/10/22 9:33
 */
@Service
@Slf4j
public class ShipmentApprovalServiceImpl extends ServiceImpl<ShipmentApprovalMapper, ShipmentApproval> implements ShipmentApprovalService {
    @Autowired
    private ShipmentApprovalMapper shipmentApprovalMapper;
    @Override
    public IPage<ShipmentApproval> listPage(Page page, ShipmentApproval req) {
        IPage<ShipmentApproval> listPage = shipmentApprovalMapper.listPage(page, req);
        return listPage;
    }
}
src/main/resources/mapper/basic/SupplierManageFileMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ruoyi.basic.mapper.SupplierManageFileMapper">
    <select id="supplierManageFileListPage" resultType="com.ruoyi.basic.pojo.SupplierManageFile">
        select *
        from supplier_manage_file
        where supplier_id = #{supplierManageFile.supplierId}
    </select>
</mapper>
src/main/resources/mapper/basic/SupplierManageMapper.xml
@@ -22,12 +22,16 @@
        T1.update_time,
        T1.update_user,
        T1.tenant_id,
        T1.is_white,
        T2.nick_name AS maintainUserName
        FROM supplier_manage T1
        LEFT JOIN sys_user T2 ON T1.maintain_user_id = T2.user_id
        <where>
            <if test="supplierManageDto.supplierName != null and supplierManageDto.supplierName != '' ">
                AND T1.supplier_name LIKE CONCAT('%',#{supplierManageDto.supplierName},'%')
            </if>
            <if test="supplierManageDto.isWhite != null">
                AND T1.is_white = #{supplierManageDto.isWhite}
            </if>
        </where>
    </select>
@@ -50,6 +54,7 @@
        T1.update_time,
        T1.update_user,
        T1.tenant_id,
        T1.is_white,
        T2.nick_name AS maintainUserName
        FROM supplier_manage T1
        LEFT JOIN sys_user T2 ON T1.maintain_user_id = T2.user_id
@@ -57,6 +62,9 @@
            <if test="supplierManageDto.supplierName != null and supplierManageDto.supplierName != '' ">
                AND T1.supplier_name LIKE CONCAT('%',#{supplierManageDto.supplierName},'%')
            </if>
            <if test="supplierManageDto.isWhite != null">
                AND T1.is_white = #{supplierManageDto.isWhite}
            </if>
        </where>
    </select>
src/main/resources/mapper/device/DeviceRepairMapper.xml
@@ -14,6 +14,7 @@
                dr.maintenance_name,
                dr.maintenance_time,
                dr.maintenance_result,
                dr.maintenance_price,
                dr.status,
                dr.create_time,
                dr.update_time,
@@ -59,6 +60,7 @@
               dr.maintenance_name,
               dr.maintenance_time,
               dr.maintenance_result,
               dr.maintenance_price,
               dr.status,
               dr.create_time,
               dr.update_time,
src/main/resources/mapper/measuringinstrumentledger/SparePartsMapper.xml
@@ -2,11 +2,12 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.measuringinstrumentledger.mapper.SparePartsMapper">
    <select id="listPage" resultType="com.ruoyi.measuringinstrumentledger.dto.SparePartsDto">
        select sp.*,sp1.name as parentName from spare_parts sp
        select sp.*,sp1.name as parentName
        from spare_parts sp
        left join spare_parts sp1 on sp1.id = sp.parent_id
        <where>
            <if test="spareParts.name != null">
                and name like concat('%',#{spareParts.name},'%')
            <if test="spareParts.name != null and spareParts.name != ''">
                and sp.name like concat('%',#{spareParts.name},'%')
            </if>
        </where>
    </select>
src/main/resources/mapper/procurementrecord/ProcurementExceptionRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.procurementrecord.mapper.ProcurementExceptionRecordMapper">
</mapper>
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -137,6 +137,7 @@
        sum(t1.total_price) as totalPrice,
        sum(t1.inbound_num) as inboundNum,
        sum(t1.inbound_num) as inboundNum0,
        t1.inbound_num as totalInboundNum,
        t1.create_time,
        t1.update_time,
        t1.create_by,
@@ -171,7 +172,7 @@
                and t1.create_time &lt;= #{req.endDate}
            </if>
        </where>
        group by t2.product_category,t2.specification_model,t1.unit_price
        group by t3.supplier_name,t2.product_category,t2.specification_model,t1.unit_price
        order by t1.create_time desc
    </select>
    <select id="listCopy" resultType="com.ruoyi.procurementrecord.dto.ProcurementPageDtoCopy">
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -14,7 +14,7 @@
        <result property="updateTime" column="update_time"/>
    </resultMap>
    <select id="pageProductOrder" resultType="com.ruoyi.production.dto.ProductOrderDto">
        select po.*,sl.sales_contract_no,sl.project_name,sl.customer_name,slp.product_category,slp.specification_model
        select po.*,sl.sales_contract_no,sl.customer_name,slp.product_category,slp.specification_model
        from product_order po
        left join sales_ledger sl on po.sales_ledger_id = sl.id
        left join sales_ledger_product slp on po.product_model_id = slp.id
@@ -25,9 +25,6 @@
            </if>
            <if test="c.salesContractNo != null and c.salesContractNo != ''">
                and sl.sales_contract_no like concat('%',#{c.salesContractNo},'%')
            </if>
            <if test="c.projectName != null and c.projectName != ''">
                and sl.project_name like concat('%',#{c.projectName},'%')
            </if>
            <if test="c.customerName != null and c.customerName != ''">
                and sl.customer_name like concat('%',#{c.customerName},'%')
src/main/resources/mapper/production/ProductProcessRouteItemMapper.xml
@@ -21,7 +21,7 @@
                 left join product p on pm.product_id = p.id
                 left join product_process pp on pp.id = ppri.process_id
        where ppri.route_id = #{orderId}
        order by ppri.id
        order by ppri.drag_sort
    </select>
src/main/resources/mapper/production/ProductWorkOrderMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.production.mapper.ProductWorkOrderMapper">
    <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductWorkOrder">
        <result column="id" property="id"/>
        <result column="product_process_route_item_id" property="productProcessRouteItemId"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
        <result column="work_order_no" property="workOrderNo"/>
        <result column="status" property="status"/>
        <result column="tenant_id" property="tenantId"/>
        <result column="actual_end_time" property="planStartTime"/>
        <result column="plan_end_time" property="planEndTime"/>
        <result column="actual_start_time" property="actualStartTime"/>
        <result column="actualEndTime" property="actualEndTime"/>
    </resultMap>
    <select id="pageProductWorkOrder" resultType="com.ruoyi.production.dto.ProductWorkOrderDto">
        SELECT
        pwo.*,
        pp.NAME as processName,
        pm.model,
        pm.unit,
        p.product_name AS productName,
        po.nps_no AS productOrderNpsNo
        FROM
        `product_work_order` pwo
        LEFT JOIN product_process_route_item ppri ON ppri.id = pwo.product_process_route_item_id
        LEFT JOIN product_order po ON po.id = pwo.product_order_id
        LEFT JOIN product_process pp ON pp.id = ppri.process_id
        LEFT JOIN product_model pm ON pm.id = ppri.product_model_id
        LEFT JOIN product p ON p.id = pm.product_id
        <where>
            <if test="c.workOrderNo != null and c.workOrderNo != ''">
                pwo.work_order_no like concat('%',#{c.workOrderNo},'%')
            </if>
        </where>
    </select>
    <update id="updatePlanQuantity" parameterType="java.util.Map">
        UPDATE product_work_order
        SET
            report_work = #{reportWork},
            quantity = #{quantity},
            plan_quantity = plan_quantity - #{deductQuantity},
            product_main_id = #{productMainId}
        WHERE id = #{workOrderId}
    </update>
    <update id="rollbackPlanQuantity" parameterType="java.lang.Long">
        UPDATE product_work_order pwo
        INNER JOIN production_product_main ppm
        ON pwo.id = ppm.work_order_id
        AND ppm.id = #{productMainId}
        INNER JOIN production_product_output ppo
        ON ppo.product_main_id = ppm.id
        SET
        pwo.plan_quantity = pwo.plan_quantity + ppo.quantity,
        pwo.report_work = 0,
        pwo.quantity = 0
        WHERE pwo.id = ppm.work_order_id
    </update>
</mapper>
src/main/resources/mapper/production/ProductionProductInputMapper.xml
@@ -2,5 +2,35 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.production.mapper.ProductionProductInputMapper">
    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductInput">
        <id property="id" column="id"/>
        <result property="productMainId" column="product_main_id"/>
        <result property="productModelId" column="product_model_id"/>
        <result property="quantity" column="quantity"/>
        <result property="tenantId" column="tenant_id"/>
        <result property="createTime" column="create_time"/>
    </resultMap>
    <select id="listPageProductionProductInputDto" resultType="com.ruoyi.production.dto.ProductionProductInputDto">
        select ppi.*,
        pm.model as model,
        ppm.product_no as productNo
        from
        production_product_input ppi
        left join production_product_main ppm on ppm.id = ppi.product_main_id
        left join product_model pm on pm.id = ppi.product_model_id
        <where>
            <if test="c.productMainId != null and c.productMainId > 0">
                and ppm.id = #{c.productMainId}
            </if>
        </where>
        order by ppi.id
    </select>
    <delete id="deleteByProductMainIds" parameterType="java.util.List">
        DELETE FROM production_product_input
        WHERE product_main_id IN
        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -37,4 +37,12 @@
        </where>
        order by ppm.id
    </select>
    <delete id="deleteByWorkOrderIds" parameterType="java.util.List">
        DELETE FROM production_product_main
        WHERE work_order_id IN
        <foreach collection="workOrderIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
src/main/resources/mapper/production/ProductionProductOutputMapper.xml
@@ -2,5 +2,36 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.production.mapper.ProductionProductOutputMapper">
    <resultMap id="basicMap" type="com.ruoyi.production.pojo.ProductionProductOutput">
        <id property="id" column="id"/>
        <result property="productMainId" column="product_main_id"/>
        <result property="productModelId" column="product_model_id"/>
        <result property="quantity" column="quantity"/>
        <result property="tenantId" column="tenant_id"/>
        <result property="createTime" column="create_time"/>
    </resultMap>
    <select id="listPageProductionProductOutputDto" resultType="com.ruoyi.production.dto.ProductionProductOutputDto">
        select ppo.*,
        pm.model as model,
        ppm.product_no as productNo
        from
        production_product_output ppo
        left join production_product_main ppm on ppm.id = ppo.product_main_id
        left join product_model pm on pm.id = ppo.product_model_id
        <where>
            <if test="c.productMainId != null and c.productMainId > 0">
                and ppm.id = #{c.productMainId}
            </if>
        </where>
        order by ppo.id
    </select>
    <delete id="deleteByProductMainIds" parameterType="java.util.List">
        DELETE FROM production_product_output
        WHERE product_main_id IN
        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
src/main/resources/mapper/purchase/ProductRecordMapper.xml
@@ -28,10 +28,10 @@
        left join product_model pm on pm.id = pr.product_model_id
        WHERE type = 2
        <if test="c.salesContractNo != null and c.salesContractNo != ''">
            and sl.sales_contract_no = #{c.salesContractNo}
            and sl.sales_contract_no like concat('%',#{c.salesContractNo},'%')
        </if>
        <if test="c.supplierName != null and c.supplierName != ''">
            and pl.supplier_name = #{c.supplierName}
            and pl.supplier_name like concat('%',#{c.supplierName},'%')
        </if>
        <if test="c.createdAtStart != null and c.createdAtStart != ''">
            and pr.created_at &gt;= date_format(#{c.createdAtStart},'%Y-%m-%d hh:mm:ss')
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -14,21 +14,30 @@
        pl.id,
        pl.purchase_contract_number ,
        pl.sales_contract_no,
        pl.supplier_id,
        pl.supplier_name,
        pl.project_name,
        pl.contract_amount,
        sum(pr.tickets_amount)as receipt_payment_amount,
        pl.contract_amount-sum(pr.tickets_amount) AS unReceipt_payment_amount,
        pl.entry_date,
        pl.execution_date,
        pl.recorder_id,
        pl.recorder_name,
        pl.template_name,
        pl.approver_id,
        sm.is_white,
        pl.approval_status,
        pl.payment_method
        from purchase_ledger pl
        left join product_record pr on pl.id = pr.purchase_ledger_id
        left join supplier_manage sm on pl.supplier_id = sm.id
        <where>
            1 = 1
            <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''">
               and pl.purchase_contract_number like concat('%',#{c.purchaseContractNumber},'%')
            </if>
            <if test="c.approvalStatus != null and c.approvalStatus != ''">
                and pl.approval_status = #{c.approvalStatus}
            </if>
            <if test="c.supplierName != null and c.supplierName != ''">
                and pl.supplier_name like concat('%',#{c.supplierName},'%')
@@ -51,6 +60,7 @@
        pl.recorder_name,
        pl.contract_amount
        order by pl.entry_date desc
    </select>
    <select id="getPaymentRegistrationDtoById" resultType="com.ruoyi.purchase.dto.PaymentRegistrationDto">
        SELECT
src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -8,16 +8,16 @@
        where
        inspect_type=#{qualityInspect.inspectType}
        <if test="qualityInspect.supplier != null and qualityInspect.supplier != '' ">
            AND supplier = #{qualityInspect.supplier}
            AND supplier like concat('%',#{qualityInspect.supplier},'%')
        </if>
        <if test="qualityInspect.customer != null and qualityInspect.customer != '' ">
            AND customer = #{qualityInspect.customer}
            AND customer like concat('%',#{qualityInspect.customer},'%')
        </if>
        <if test="qualityInspect.process != null and qualityInspect.process != '' ">
            AND process = #{qualityInspect.process}
            AND process like concat('%',#{qualityInspect.process},'%')
        </if>
        <if test="qualityInspect.productName != null and qualityInspect.productName != '' ">
            AND product_name = #{qualityInspect.productName}
            AND product_name like concat('%',#{qualityInspect.productName},'%')
        </if>
        <if test="qualityInspect.entryDateStart != null and qualityInspect.entryDateStart != '' ">
            AND check_time &gt;= DATE_FORMAT(#{qualityInspect.entryDateStart},'%Y-%m-%d')
@@ -46,4 +46,13 @@
            AND product_name = #{qualityInspect.productName}
        </if>
    </select>
    <delete id="deleteByProductMainIds">
        DELETE FROM quality_inspect
        WHERE product_main_id IN
        <foreach collection="productMainIds" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>
src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -58,13 +58,10 @@
        T1.contract_amount,
        T1.execution_date,
        T2.nick_name AS entry_person_name,
        T1.payment_method,
        t3.shipping_car_number,
        t3.shipping_date
        T1.payment_method
        FROM
        sales_ledger T1
        LEFT JOIN sys_user T2 ON T1.entry_person = T2.user_id
        left join shipping_info t3 on T1.id = t3.sales_ledger_id
        <where>
            <if test="salesLedgerDto.customerName != null and salesLedgerDto.customerName != '' ">
                AND  T1.customer_name LIKE CONCAT('%',#{salesLedgerDto.customerName},'%')
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.SalesLedgerProductMapper">
    <select id="selectSalesLedgerProductList" resultType="com.ruoyi.sales.pojo.SalesLedgerProduct">
        SELECT
        T1.*,
        t3.shipping_car_number,
        t3.shipping_date
        FROM
        sales_ledger_product T1
        left join shipping_info t3 on T1.id = t3.sales_ledger_id
        <where>
            1=1
            <if test="salesLedgerProduct.salesLedgerId != null and salesLedgerProduct.salesLedgerId != '' ">
                AND  T1.sales_ledger_id = #{salesLedgerProduct.salesLedgerId}
            </if>
            <if test="salesLedgerProduct.type != null and salesLedgerProduct.type != '' ">
                AND  T1.type = #{salesLedgerProduct.type}
            </if>
        </where>
    </select>
</mapper>
src/main/resources/mapper/sales/ShipmentApprovalMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.ShipmentApprovalMapper">
    <select id="listPage" resultType="com.ruoyi.sales.pojo.ShipmentApproval">
        SELECT *,
        si.shipping_car_number,
        T2.nick_name AS entry_person_name
        FROM shipment_approval sa
                 LEFT JOIN shipping_info si ON sa.shipping_info_id = si.id
                 LEFT JOIN sales_ledger sl ON sa.sales_ledger_id = sl.id
                 LEFT JOIN sales_ledger_product slp ON sa.sales_ledger_product_id = slp.id
                 LEFT JOIN sys_user T2 ON sl.entry_person = T2.user_id
        <where>
            1=1
            <if test="req.approveStatus != null and req.approveStatus != '' ">
                AND  sa.approve_status = #{req.approveStatus}
            </if>
            <if test="req.salesContractNo != null and req.salesContractNo != '' ">
                AND  sl.sales_contract_no LIKE CONCAT('%',#{req.salesContractNo},'%')
            </if>
        </where>
    </select>
</mapper>