liyong
9 天以前 69bb4a6479653f2e27cb67ce0ab817bd40e9c791
Merge remote-tracking branch 'refs/remotes/origin/dev_New' into jtwy
已添加4个文件
已重命名1个文件
已修改40个文件
已删除1个文件
1665 ■■■■■ 文件已修改
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/EnumController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockOutUnQualifiedRecordTypeEnum.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/controller/HomeController.java 192 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductOrderController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/SalesLedgerWorkController.java 185 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/SalesLedgerProductionAccounting.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductOrderService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductionProductMainService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/SalesLedgerWorkServiceImpl.java 367 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/controller/StockInventoryController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-zxsq.yml 245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductOrderMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductWorkOrderMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductMainMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PaymentRegistrationMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/quality/QualityInspectMapper.xml 39 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -11,9 +11,9 @@
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceRepair;
@@ -31,7 +31,6 @@
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -206,7 +205,7 @@
                            purchaseLedgerServiceImpl.addQualityInspect(purchaseLedger, salesLedgerProduct);
                        }else {
                            //直接入库
                            stockUtils.addStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode(), purchaseLedger.getId());
                            stockUtils.addStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockInQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode(), purchaseLedger.getId());
                        }
                    }
                } else if (status.equals(3)) {
src/main/java/com/ruoyi/basic/controller/EnumController.java
@@ -1,7 +1,7 @@
package com.ruoyi.basic.controller;
import com.ruoyi.basic.utils.EnumUtils;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Anonymous;
import com.ruoyi.framework.web.domain.R;
@@ -24,13 +24,13 @@
    @GetMapping("/stockRecordType")
    @Anonymous
    public R  getStockRecordTypeEnum(){
        List<Map<String, Object>> list = EnumUtil.toList(StockQualifiedRecordTypeEnum.class);
        List<Map<String, Object>> list = EnumUtil.toList(StockOutQualifiedRecordTypeEnum.class);
        return R.ok(list);
    }
    @GetMapping("/{className}")
    @Anonymous
    public R test(@PathVariable String className){
    public R stockRecordTypeByClassName(@PathVariable("className") String className){
        return R.ok(EnumUtils.getOptions("com.ruoyi.common.enums." + className));
    }
}
src/main/java/com/ruoyi/collaborativeApproval/service/impl/MeetingServiceImpl.java
@@ -25,6 +25,7 @@
import com.ruoyi.collaborativeApproval.vo.SearchMeetingDraftVo;
import com.ruoyi.collaborativeApproval.vo.SearchMeetingRoomVo;
import com.ruoyi.collaborativeApproval.vo.SearchMeetingUseVo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.project.system.domain.SysUser;
@@ -34,7 +35,9 @@
import com.ruoyi.staff.pojo.StaffOnJob;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -83,7 +86,22 @@
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMeetingRoom(Long id) {
        if (id == null){
            throw new ServiceException("删除会议室失败,会议室ID不能为空");
        }
        LocalDateTime now = LocalDateTime.now();
        List<MeetApplication> meetApplicationList = meetApplicationMapper.selectList(Wrappers.<MeetApplication>lambdaQuery()
                .eq(MeetApplication::getRoomId, id)
                .gt(MeetApplication::getEndTime, now)
                .in(MeetApplication::getStatus, Arrays.asList(0, 1)));
        if (!meetApplicationList.isEmpty()){
            throw new ServiceException("删除会议室失败,该会议室尚有未开始或进行中的有效会议预约");
        }
        meetingRoomMapper.deleteById(id);
    }
src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.ruoyi.common.enums;
import lombok.Getter;
@Getter
public enum StockInQualifiedRecordTypeEnum implements BaseEnum<String> {
    CUSTOMIZATION_STOCK_IN("0", "合格自定义入库"),
    PRODUCTION_REPORT_STOCK_IN("2", "生产报工-入库"),
    PURCHASE_STOCK_IN("7", "采购-入库"),
    QUALITYINSPECT_STOCK_IN("11", "质检-合格入库"),
    DEFECTIVE_PASS("11", "不合格-让步放行");
    private final String code;
    private final String value;
    StockInQualifiedRecordTypeEnum(String code, String value) {
        this.code = code;
        this.value = value;
    }
}
src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java
ÎļþÃû´Ó src/main/java/com/ruoyi/common/enums/StockUnQualifiedRecordTypeEnum.java ÐÞ¸Ä
@@ -4,20 +4,19 @@
@Getter
public enum StockUnQualifiedRecordTypeEnum implements BaseEnum<String> {
public enum StockInUnQualifiedRecordTypeEnum implements BaseEnum<String> {
    PRODUCTION_SCRAP("4", "生产报工-报废"),
    DEFECTIVE_SCRAP("5", "不合格处理-报废"),
    PRODUCTION_SCRAP("5", "生产报工-报废"),
    CUSTOMIZATION_UNSTOCK_IN("9", "不合格自定义入库"),
    CUSTOMIZATION_UNSTOCK_OUT("10", "不合格自定义出库"),
    QUALITYINSPECT_UNSTOCK_IN("12", "质检-不合格入库");
    private final String code;
    private final String value;
    StockUnQualifiedRecordTypeEnum(String code, String value) {
    StockInUnQualifiedRecordTypeEnum(String code, String value) {
        this.code = code;
        this.value = value;
    }
src/main/java/com/ruoyi/common/enums/StockOutQualifiedRecordTypeEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.common.enums;
import lombok.Getter;
@Getter
public enum StockOutQualifiedRecordTypeEnum implements BaseEnum<String> {
    CUSTOMIZATION_STOCK_OUT("1", "合格自定义出库"),
    PRODUCTION_REPORT_STOCK_OUT("3", "生产报工-出库"),
    SALE_STOCK_OUT("8", "销售-出库"),
    SALE_SHIP_STOCK_OUT("13", "销售-发货出库");
    private final String code;
    private final String value;
    StockOutQualifiedRecordTypeEnum(String code, String value) {
        this.code = code;
        this.value = value;
    }
    }
src/main/java/com/ruoyi/common/enums/StockOutUnQualifiedRecordTypeEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.common.enums;
import lombok.Getter;
@Getter
public enum StockOutUnQualifiedRecordTypeEnum implements BaseEnum<String> {
    CUSTOMIZATION_UNSTOCK_OUT("10", "不合格自定义出库");
    private final String code;
    private final String value;
    StockOutUnQualifiedRecordTypeEnum(String code, String value) {
        this.code = code;
        this.value = value;
    }
}
src/main/java/com/ruoyi/common/enums/StockQualifiedRecordTypeEnum.java
ÎļþÒÑɾ³ý
src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -69,6 +69,7 @@
        return AjaxResult.success(homeSummaryDto);
    }
    /********************************************************营销采购类**************************************************/
    @GetMapping("/supplierPurchaseRanking")
    @ApiOperation("供应商采购排名")
    public AjaxResult supplierPurchaseRanking(@RequestParam(value = "type", defaultValue = "1") Integer type) {
@@ -80,13 +81,6 @@
    @ApiOperation("客户营收贡献数值分析")
    public AjaxResult customerRevenueAnalysis(@RequestParam("customerId") Long customerId, @RequestParam(value = "type", defaultValue = "1") Integer type) {
        CustomerRevenueAnalysisDto dto = homeService.customerRevenueAnalysis(customerId, type);
        return AjaxResult.success(dto);
    }
    @GetMapping("/productCategoryDistribution")
    @ApiOperation("产品大类分布")
    public AjaxResult productCategoryDistribution() {
        ProductCategoryDistributionDto dto = homeService.productCategoryDistribution();
        return AjaxResult.success(dto);
    }
@@ -111,63 +105,23 @@
        return AjaxResult.success(list);
    }
    @GetMapping("/salesPurchaseStorageProductCount")
    @ApiOperation("销售-采购-储存产品数")
    public AjaxResult salesPurchaseStorageProductCount(){
        List<MapDto> list = homeService.salesPurchaseStorageProductCount();
        return AjaxResult.success(list);
    @GetMapping("/business")
    @Log(title = "销售-采购-库存数据", businessType = BusinessType.OTHER)
    @ApiOperation("销售-采购-库存数据")
    public AjaxResult business(HomeBusinessDto req) {
        HomeBusinessDto homeBusinessDto = homeService.business();
        return AjaxResult.success(homeBusinessDto);
    }
    @GetMapping("/productInOutAnalysis")
    @ApiOperation("产品出入库分析")
    public AjaxResult productInOutAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){
        List<Map<String, Object>> result = homeService.productInOutAnalysis(type);
        return AjaxResult.success(result);
    @GetMapping("/analysisCustomerContractAmounts")
    @Log(title = "客户合同金额分析", businessType = BusinessType.OTHER)
    @ApiOperation("客户合同金额分析")
    public AjaxResult analysisCustomerContractAmounts(AnalysisCustomerContractAmountsDto req) {
        AnalysisCustomerContractAmountsDto analysisCustomerContractAmounts = homeService.analysisCustomerContractAmounts();
        return AjaxResult.success(analysisCustomerContractAmounts);
    }
    @GetMapping("/productTurnoverDays")
    @ApiOperation("产品周转天数")
    public AjaxResult productTurnoverDays(){
        List<MapDto> list = homeService.productTurnoverDays();
        return AjaxResult.success(list);
    }
    @GetMapping("/incomeExpenseAnalysis")
    @ApiOperation("支收对比分析")
    public AjaxResult incomeExpenseAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type) {
        List<Map<String, Object>> result = homeService.incomeExpenseAnalysis(type);
        return AjaxResult.success(result);
    }
    @GetMapping("/profitTrendAnalysis")
    @ApiOperation("利润趋势分析")
    public AjaxResult profitTrendAnalysis(){
        List<MapDto> list = homeService.profitTrendAnalysis();
        return AjaxResult.success(list);
    }
    @GetMapping("/expenseCompositionAnalysis")
    @ApiOperation("构成分析")
    public AjaxResult expenseCompositionAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type) {
        List<MapDto> list = homeService.expenseCompositionAnalysis(type);
        return AjaxResult.success(list);
    }
    @GetMapping("/monthlyIncome")
    @ApiOperation("月度收入")
    public AjaxResult monthlyIncome(){
        MonthlyIncomeDto dto = homeService.monthlyIncome();
        return AjaxResult.success(dto);
    }
   @GetMapping("/monthlyExpenditure")
   @ApiOperation("月度支出")
   public AjaxResult monthlyExpenditure(){
        MonthlyExpenditureDto dto = homeService.monthlyExpenditure();
        return AjaxResult.success(dto);
   }
    /********************************************************生产类*****************************************************/
    @GetMapping("/inputOutputAnalysis")
    @ApiOperation("投入产出分析")
    public AjaxResult inputOutputAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){
@@ -202,6 +156,21 @@
        return AjaxResult.success(homeService.orderCount());
    }
    @GetMapping("/progressStatistics")
    @ApiOperation("各生产订单的完成进度统计")
    public AjaxResult progressStatistics(){
        ProductionProgressDto productionProgressDto = homeService.productionProgress();
        return AjaxResult.success(productionProgressDto);
    }
    @GetMapping("/workInProcessTurnover")
    @ApiOperation("在制品周转情况")
    public AjaxResult workInProcessTurnover(){
        ProductionTurnoverDto productionTurnoverDto = homeService.workInProcessTurnover();
        return AjaxResult.success(productionTurnoverDto);
    }
    /********************************************************质量类*****************************************************/
    @GetMapping("/rawMaterialDetection")
    @ApiOperation("原材料检测")
    public AjaxResult rawMaterialDetection(@RequestParam(value = "type", defaultValue = "1") Integer type){
@@ -255,42 +224,6 @@
        return AjaxResult.success(list);
    }
    /********************************************************营销采购类**************************************************/
    @GetMapping("/business")
    @Log(title = "销售-采购-库存数据", businessType = BusinessType.OTHER)
    @ApiOperation("销售-采购-库存数据")
    public AjaxResult business(HomeBusinessDto req) {
        HomeBusinessDto homeBusinessDto = homeService.business();
        return AjaxResult.success(homeBusinessDto);
    }
    @GetMapping("/analysisCustomerContractAmounts")
    @Log(title = "客户合同金额分析", businessType = BusinessType.OTHER)
    @ApiOperation("客户合同金额分析")
    public AjaxResult analysisCustomerContractAmounts(AnalysisCustomerContractAmountsDto req) {
        AnalysisCustomerContractAmountsDto analysisCustomerContractAmounts = homeService.analysisCustomerContractAmounts();
        return AjaxResult.success(analysisCustomerContractAmounts);
    }
    /********************************************************生产类*****************************************************/
    @GetMapping("/progressStatistics")
    @ApiOperation("各生产订单的完成进度统计")
    public AjaxResult progressStatistics(){
        ProductionProgressDto productionProgressDto = homeService.productionProgress();
        return AjaxResult.success(productionProgressDto);
    }
    @GetMapping("/workInProcessTurnover")
    @ApiOperation("在制品周转情况")
    public AjaxResult workInProcessTurnover(){
        ProductionTurnoverDto productionTurnoverDto = homeService.workInProcessTurnover();
        return AjaxResult.success(productionTurnoverDto);
    }
    /********************************************************质量类*****************************************************/
    @GetMapping("/qualityStatistics")
    @Log(title = "质量分析", businessType = BusinessType.OTHER)
    @ApiOperation("质量分析")
@@ -299,8 +232,42 @@
        return AjaxResult.success(qualityStatisticsDto);
    }
    /********************************************************财务类*****************************************************/
    @GetMapping("/incomeExpenseAnalysis")
    @ApiOperation("支收对比分析")
    public AjaxResult incomeExpenseAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type) {
        List<Map<String, Object>> result = homeService.incomeExpenseAnalysis(type);
        return AjaxResult.success(result);
    }
    @GetMapping("/profitTrendAnalysis")
    @ApiOperation("利润趋势分析")
    public AjaxResult profitTrendAnalysis(){
        List<MapDto> list = homeService.profitTrendAnalysis();
        return AjaxResult.success(list);
    }
    @GetMapping("/expenseCompositionAnalysis")
    @ApiOperation("构成分析")
    public AjaxResult expenseCompositionAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type) {
        List<MapDto> list = homeService.expenseCompositionAnalysis(type);
        return AjaxResult.success(list);
    }
    @GetMapping("/monthlyIncome")
    @ApiOperation("月度收入")
    public AjaxResult monthlyIncome(){
        MonthlyIncomeDto dto = homeService.monthlyIncome();
        return AjaxResult.success(dto);
    }
    @GetMapping("/monthlyExpenditure")
    @ApiOperation("月度支出")
    public AjaxResult monthlyExpenditure(){
        MonthlyExpenditureDto dto = homeService.monthlyExpenditure();
        return AjaxResult.success(dto);
    }
    @GetMapping("/statisticsReceivablePayable")
    @Log(title = "应收应付统计", businessType = BusinessType.OTHER)
    @ApiOperation("应收应付统计")
@@ -309,17 +276,34 @@
        return AjaxResult.success(statisticsReceivablePayable);
    }
    /********************************************************仓储类*****************************************************/
    @GetMapping("/productCategoryDistribution")
    @ApiOperation("产品大类分布")
    public AjaxResult productCategoryDistribution() {
        ProductCategoryDistributionDto dto = homeService.productCategoryDistribution();
        return AjaxResult.success(dto);
    }
    @GetMapping("/salesPurchaseStorageProductCount")
    @ApiOperation("销售-采购-储存产品数")
    public AjaxResult salesPurchaseStorageProductCount(){
        List<MapDto> list = homeService.salesPurchaseStorageProductCount();
        return AjaxResult.success(list);
    }
    @GetMapping("/productInOutAnalysis")
    @ApiOperation("产品出入库分析")
    public AjaxResult productInOutAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){
        List<Map<String, Object>> result = homeService.productInOutAnalysis(type);
        return AjaxResult.success(result);
    }
    @GetMapping("/productTurnoverDays")
    @ApiOperation("产品周转天数")
    public AjaxResult productTurnoverDays(){
        List<MapDto> list = homeService.productTurnoverDays();
        return AjaxResult.success(list);
    }
}
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -1729,8 +1729,7 @@
                    BigDecimal finishQty = item.getQuantity() != null ? item.getQuantity() : BigDecimal.ZERO;
                    BigDecimal scrapQty = item.getScrapQty() != null ? item.getScrapQty() : BigDecimal.ZERO;
                    dto.setFinishQuantity(
                            dto.getFinishQuantity() != null ? dto.getFinishQuantity().add(finishQty) : finishQty);
                    dto.setFinishQuantity(dto.getFinishQuantity() != null ? dto.getFinishQuantity().add(finishQty) : finishQty);
                }
            }
@@ -1746,9 +1745,11 @@
                    .filter(i -> i.getCreateTime() != null)
                    .collect(Collectors.groupingBy(
                            i -> i.getCreateTime().toLocalDate().toString(),
                            Collectors.reducing(BigDecimal.ZERO,
                                    i -> i.getQuantity() != null ? i.getQuantity() : BigDecimal.ZERO,
                                    BigDecimal::add)));
                            Collectors.reducing(BigDecimal.ZERO, i -> {
                                BigDecimal qty = (i.getQuantity() != null) ? i.getQuantity() : BigDecimal.ZERO;
                                BigDecimal scrap = (i.getScrapQty() != null) ? i.getScrapQty() : BigDecimal.ZERO;
                                return qty.subtract(scrap);
                            }, BigDecimal::add)));
            finishMap.forEach((date, qty) -> {
                WorkOrderEfficiencyDto dto = dateMap.getOrDefault(date, new WorkOrderEfficiencyDto());
src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -87,4 +87,15 @@
    }
    @ApiOperation("新增生产订单")
    @PostMapping("addProductOrder")
    public R addProductOrder(@RequestBody ProductOrder productOrder) {
        return R.ok(productOrderService.addProductOrder(productOrder));
    }
    @ApiOperation("删除生产订单")
    @DeleteMapping("/{ids}")
    public R delete(@PathVariable("ids") Long[] ids) {
        return R.ok(productOrderService.delete(ids));
    }
}
src/main/java/com/ruoyi/production/controller/SalesLedgerWorkController.java
@@ -1,93 +1,92 @@
package com.ruoyi.production.controller;
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.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.production.dto.ProcessSchedulingDto;
import com.ruoyi.production.dto.ProductionReportDto;
import com.ruoyi.production.dto.SalesLedgerSchedulingProcessDto;
import com.ruoyi.production.dto.SalesLedgerWorkDto;
import com.ruoyi.production.pojo.SalesLedgerWork;
import com.ruoyi.production.service.SalesLedgerWorkService;
import com.ruoyi.production.service.impl.SalesLedgerWorkServiceImpl;
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/21 14:43
 */
@RestController
@Api(tags = "生产报工(排产记录)")
@RequestMapping("/salesLedger/work")
@Deprecated // æ ‡è®°è¯¥ç±»å·²å¼ƒç”¨
public class SalesLedgerWorkController extends BaseController {
    @Autowired
    private SalesLedgerWorkServiceImpl salesLedgerWorkService;
    @GetMapping("/listPage")
    @Log(title = "生产报工-分页查询", businessType = BusinessType.OTHER)
    @ApiOperation("生产报工-分页查询")
    public AjaxResult listPage(Page page, SalesLedgerWorkDto salesLedgerWorkDto) {
        IPage<SalesLedgerWorkDto> listPage = salesLedgerWorkService.listPage(page, salesLedgerWorkDto);
        return AjaxResult.success(listPage);
    }
    /**
     * å¯¼å‡º
     * @param response
     */
    @PostMapping("/export")
    @ApiOperation("生产管理-生产报工-导出")
    public void export(HttpServletResponse response) {
        Page page = new Page(-1,-1);
        SalesLedgerWorkDto salesLedgerSchedulingDto = new SalesLedgerWorkDto();
        IPage<SalesLedgerWorkDto> result = salesLedgerWorkService.listPage(page,salesLedgerSchedulingDto);
        result.getRecords().forEach(item -> {
            item.setDaiNum(item.getFinishedNum().subtract(item.getSchedulingNum()));
            item.setStatusName(item.getStatus().toString());
        });
        ExcelUtil<SalesLedgerWorkDto> util = new ExcelUtil<>(SalesLedgerWorkDto.class);
        util.exportExcel(response, result.getRecords(), "工序排产");
    }
    @GetMapping("/list")
    @Log(title = "生产报工-查询", businessType = BusinessType.OTHER)
    @ApiOperation("生产报工-查询")
    public AjaxResult list(@RequestParam("id") Long id) {
        List<ProductionReportDto> list = salesLedgerWorkService.getList(id);
        return AjaxResult.success(list);
    }
    @PostMapping("/productionReport")
    @Log(title = "生产管理-生产报工", businessType = BusinessType.INSERT)
    @ApiOperation("生产管理-生产报工")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult productionReport(@RequestBody ProductionReportDto productionReportDto) {
        int result = salesLedgerWorkService.productionReport(productionReportDto);
        return AjaxResult.success(result);
    }
    @PostMapping("/productionReportUpdate")
    @Log(title = "生产管理-生产报工-修改", businessType = BusinessType.UPDATE)
    @ApiOperation("生产管理-生产报工-修改")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult productionReportUpdate(@RequestBody ProductionReportDto productionReportDto) {
        int result = salesLedgerWorkService.productionReportUpdate(productionReportDto);
        return AjaxResult.success(result);
    }
}
//package com.ruoyi.production.controller;
//
//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.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.production.dto.ProcessSchedulingDto;
//import com.ruoyi.production.dto.ProductionReportDto;
//import com.ruoyi.production.dto.SalesLedgerSchedulingProcessDto;
//import com.ruoyi.production.dto.SalesLedgerWorkDto;
//import com.ruoyi.production.pojo.SalesLedgerWork;
//import com.ruoyi.production.service.SalesLedgerWorkService;
//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/21 14:43
// */
//@RestController
//@Api(tags = "生产报工(排产记录)")
//@RequestMapping("/salesLedger/work")
//@Deprecated // æ ‡è®°è¯¥ç±»å·²å¼ƒç”¨
//public class SalesLedgerWorkController extends BaseController {
//
//
//    @Autowired
//    private SalesLedgerWorkServiceImpl salesLedgerWorkService;
//
//    @GetMapping("/listPage")
//    @Log(title = "生产报工-分页查询", businessType = BusinessType.OTHER)
//    @ApiOperation("生产报工-分页查询")
//    public AjaxResult listPage(Page page, SalesLedgerWorkDto salesLedgerWorkDto) {
//        IPage<SalesLedgerWorkDto> listPage = salesLedgerWorkService.listPage(page, salesLedgerWorkDto);
//        return AjaxResult.success(listPage);
//    }
//
//    /**
//     * å¯¼å‡º
//     * @param response
//     */
//    @PostMapping("/export")
//    @ApiOperation("生产管理-生产报工-导出")
//    public void export(HttpServletResponse response) {
//        Page page = new Page(-1,-1);
//        SalesLedgerWorkDto salesLedgerSchedulingDto = new SalesLedgerWorkDto();
//        IPage<SalesLedgerWorkDto> result = salesLedgerWorkService.listPage(page,salesLedgerSchedulingDto);
//        result.getRecords().forEach(item -> {
//            item.setDaiNum(item.getFinishedNum().subtract(item.getSchedulingNum()));
//            item.setStatusName(item.getStatus().toString());
//        });
//        ExcelUtil<SalesLedgerWorkDto> util = new ExcelUtil<>(SalesLedgerWorkDto.class);
//        util.exportExcel(response, result.getRecords(), "工序排产");
//    }
//
//    @GetMapping("/list")
//    @Log(title = "生产报工-查询", businessType = BusinessType.OTHER)
//    @ApiOperation("生产报工-查询")
//    public AjaxResult list(@RequestParam("id") Long id) {
//        List<ProductionReportDto> list = salesLedgerWorkService.getList(id);
//        return AjaxResult.success(list);
//    }
//
//    @PostMapping("/productionReport")
//    @Log(title = "生产管理-生产报工", businessType = BusinessType.INSERT)
//    @ApiOperation("生产管理-生产报工")
//    @Transactional(rollbackFor = Exception.class)
//    public AjaxResult productionReport(@RequestBody ProductionReportDto productionReportDto) {
//        int result = salesLedgerWorkService.productionReport(productionReportDto);
//        return AjaxResult.success(result);
//    }
//
//
//    @PostMapping("/productionReportUpdate")
//    @Log(title = "生产管理-生产报工-修改", businessType = BusinessType.UPDATE)
//    @ApiOperation("生产管理-生产报工-修改")
//    @Transactional(rollbackFor = Exception.class)
//    public AjaxResult productionReportUpdate(@RequestBody ProductionReportDto productionReportDto) {
//        int result = salesLedgerWorkService.productionReportUpdate(productionReportDto);
//        return AjaxResult.success(result);
//    }
//
//}
src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -20,4 +20,6 @@
    ProductWorkOrderDto getProductWorkOrderFlowCard(@Param("id") Long id);
    List<ProductWorkOrderDto> selectWorkOrderStartStats(@Param("startDate") String startDate, @Param("endDate") String endDate);
    ProductWorkOrder selectMax(@Param("datePrefix") String datePrefix);
}
src/main/java/com/ruoyi/production/mapper/ProductionProductMainMapper.java
@@ -10,6 +10,7 @@
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.ArrayList;
import java.util.List;
@Mapper
@@ -30,4 +31,6 @@
    ProductOrder getOrderByMainId(@Param("productMainId") Long productMainId);
    IPage<ProductionProductMainDto> listProductionDetails(@Param("ew") SalesLedgerProductionAccountingDto salesLedgerProductionAccountingDto, Page page);
    ArrayList<Long> listMain(List<Long> idList);
}
src/main/java/com/ruoyi/production/pojo/ProductionProductInput.java
@@ -24,6 +24,7 @@
    private BigDecimal quantity;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "租户ID")
src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -20,10 +20,11 @@
    @ApiModelProperty(value = "产品id")
    private Long productModelId;
    @ApiModelProperty(value = "报工数量")
    @ApiModelProperty(value = "报工数量(总数量)")
    private BigDecimal quantity;
    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @ApiModelProperty(value = "租户ID")
src/main/java/com/ruoyi/production/pojo/SalesLedgerProductionAccounting.java
@@ -23,24 +23,9 @@
    private Long id;
    /**
     * é”€å”®æŽ’产-报工表id
     * æŠ¥å·¥è¡¨id
     */
    private Long salesLedgerWorkId;
    /**
     * é”€å”®æŽ’产表id
     */
    private Long salesLedgerSchedulingId;
    /**
     * é”€å”®å°è´¦id
     */
    private Long salesLedgerId;
    /**
     * é”€å”®äº§å“id
     */
    private Long salesLedgerProductId;
    private Long productMainId;
    /**
     * ç”Ÿäº§äººid
@@ -101,6 +86,5 @@
    @TableField(fill = FieldFill.INSERT)
    private Long tenantId;
    private Long ProductMainId;
}
src/main/java/com/ruoyi/production/service/ProductOrderService.java
@@ -21,4 +21,8 @@
    List<ProcessRoute> listProcessRoute(Long productModelId);
    List<ProductStructureDto> listProcessBom(Long orderId);
    Boolean addProductOrder(ProductOrder productOrder);
    Boolean delete(Long[] id);
}
src/main/java/com/ruoyi/production/service/ProductionProductMainService.java
@@ -6,10 +6,15 @@
import com.ruoyi.production.dto.ProductionProductMainDto;
import com.ruoyi.production.pojo.ProductionProductMain;
import java.util.ArrayList;
import java.util.List;
public interface ProductionProductMainService extends IService<ProductionProductMain> {
    IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto);
    Boolean addProductMain(ProductionProductMainDto productionProductMainDto);
    Boolean removeProductMain(Long id);
    ArrayList<Long> listMain(List<Long> idList);
}
src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -1,22 +1,29 @@
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.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.production.dto.ProductBomDto;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.production.dto.ProductOrderDto;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.ProcessRouteService;
import com.ruoyi.production.service.ProductOrderService;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements ProductOrderService {
@@ -39,6 +46,23 @@
    @Autowired
    private ProductWorkOrderMapper productWorkOrderMapper;
    @Autowired
    private ProductionProductMainMapper productionProductMainMapper;
    @Autowired
    private ProductionProductOutputMapper productionProductOutputMapper;
    @Autowired
    private ProductionProductInputMapper productionProductInputMapper;
    @Autowired
    private QualityInspectMapper qualityInspectMapper;
    @Autowired
    private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    @Autowired
    private StockUtils stockUtils;
    @Override
    public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) {
@@ -69,11 +93,7 @@
            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);
                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
                int sequenceNumber = 1; // é»˜è®¤åºå·
                if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                    String lastNo = lastWorkOrder.getWorkOrderNo().toString();
@@ -110,4 +130,139 @@
    public List<ProductStructureDto> listProcessBom(Long orderId) {
        return productOrderMapper.listProcessBom(orderId);
    }
    @Override
    public Boolean addProductOrder(ProductOrder productOrder) {
        String string = generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        productOrder.setNpsNo(string);
        productOrder.setCompleteQuantity(BigDecimal.ZERO);
        this.save(productOrder);
        if (ObjectUtils.isNotEmpty(productOrder.getRouteId())) {
            this.bindingRoute(productOrder);
        }
        return true;
    }
    @Override
    public Boolean delete(Long[] ids) {
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
                        .in(ProductOrder::getId, ids)
        );
        if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) {
            // æ‰¹é‡æŸ¥è¯¢processRouteItems
            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                    new LambdaQueryWrapper<ProductProcessRouteItem>()
                            .in(ProductProcessRouteItem::getProductOrderId, ids)
            );
            if (!com.baomidou.mybatisplus.core.toolkit.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 (!com.baomidou.mybatisplus.core.toolkit.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 (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(productMainIds)) {
                        productionProductOutputMapper.deleteByProductMainIds(productMainIds);
                        productionProductInputMapper.deleteByProductMainIds(productMainIds);
                        List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
                                new LambdaQueryWrapper<QualityInspect>()
                                        .in(QualityInspect::getProductMainId, productMainIds)
                        );
                        //删除出库记录
                        for (Long productMainId : productMainIds) {
                            //删除生产出库记录
                            stockUtils.deleteStockOutRecord(productMainId, StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
                            //删除报废的入库记录
                            stockUtils.deleteStockInRecord(productMainId, StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
                        }
                        qualityInspects.forEach(qualityInspect -> {
                            //inspectState=1 å·²æäº¤ ä¸èƒ½åˆ é™¤
                            if (qualityInspect.getInspectState() == 1) {
                                throw new RuntimeException("已提交的检验单不能删除");
                            }
                        });
                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
                        salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
                                .in(SalesLedgerProductionAccounting::getProductMainId, productMainIds));
                    }
                    // åˆ é™¤ç”Ÿäº§ä¸»è¡¨æ•°æ®
                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
                    // åˆ é™¤å·¥å•数据
                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
                }
            }
            // æ‰¹é‡åˆ é™¤processRouteItem
            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
                    .in(ProductProcessRouteItem::getProductOrderId, ids));
            // æ‰¹é‡åˆ é™¤productProcessRoute
            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
                    .in(ProductProcessRoute::getProductOrderId, ids));
            // æ‰¹é‡åˆ é™¤productOrder
            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
                    .in(ProductOrder::getId, ids));
        }
        return true;
    }
    //获取当前生产订单号
    public String getMaxOrderNoByDate(String datePrefix) {
        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
        // åŒ¹é…ä»¥ SC + æ—¥æœŸå¼€å¤´çš„订单号
        queryWrapper.likeRight("nps_no", "SC" + datePrefix);
        // æŒ‰è®¢å•号倒序排列
        queryWrapper.orderByDesc("nps_no");
        queryWrapper.last("LIMIT 1");
        ProductOrder latestOrder = this.getOne(queryWrapper);
        return latestOrder != null ? latestOrder.getNpsNo() : null;
    }
    public String generateNextOrderNo(String datePrefix) {
        String maxOrderNo = getMaxOrderNoByDate(datePrefix);
        int sequence = 1; // é»˜è®¤èµ·å§‹åºå·
        if (maxOrderNo != null && !maxOrderNo.isEmpty()) {
            // æå–流水号部分(假设格式为 SC + æ—¥æœŸ + æµæ°´å·ï¼‰
            String sequenceStr = maxOrderNo.substring(("SC" + datePrefix).length());
            try {
                sequence = Integer.parseInt(sequenceStr) + 1;
            } catch (NumberFormatException e) {
                // å¼‚常情况下重置为1
                sequence = 1;
            }
        }
        // ç”Ÿæˆæ–°è®¢å•号
        return "SC" + datePrefix + String.format("%04d", sequence);
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductProcessRouteItemServiceImpl.java
@@ -101,14 +101,12 @@
//                    // åˆ é™¤è´¨æ£€
//                    qualityInspectMapper.delete(new LambdaQueryWrapper<QualityInspect>()
//                            .eq(QualityInspect::getProductMainId, mainId));
                    salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
                            .eq(SalesLedgerProductionAccounting::getProductMainId, main.getId()));
                }
            }
            // æŸ¥è¯¢è®¢å• + åˆ é™¤æ ¸ç®—
            ProductOrder productOrder = productOrderMapper.selectById(productOrderId);
            if (productOrder != null && productOrder.getSalesLedgerId() != null) {
                salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
                        .eq(SalesLedgerProductionAccounting::getSalesLedgerId, productOrder.getSalesLedgerId()));
            }
            // åˆ é™¤å…³è”工单
            productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
                    .eq(ProductWorkOrder::getProductProcessRouteItemId, routeItemId));
@@ -144,11 +142,7 @@
        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        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);
            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
            int sequenceNumber = 1; // é»˜è®¤åºå·
            if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                String lastNo = lastWorkOrder.getWorkOrderNo().toString();
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -11,8 +11,10 @@
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.production.dto.ProductStructureDto;
@@ -24,6 +26,7 @@
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.quality.mapper.*;
import com.ruoyi.quality.pojo.*;
import com.ruoyi.quality.service.IQualityInspectService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -33,6 +36,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -41,6 +45,7 @@
@Transactional(rollbackFor = Exception.class)
public class ProductionProductMainServiceImpl extends ServiceImpl<ProductionProductMainMapper, ProductionProductMain> implements ProductionProductMainService {
    private IQualityInspectService qualityInspectService;
    private ProductionProductMainMapper productionProductMainMapper;
@@ -148,7 +153,7 @@
            productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity()));
            productionProductInput.setProductMainId(productionProductMain.getId());
            productionProductInputMapper.insert(productionProductInput);
            stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId());
            stockUtils.substractStock(productStructureDto.getProductModelId(), productionProductInput.getQuantity(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(), productionProductMain.getId());
        }
        /*新增报工产出表*/
@@ -202,7 +207,7 @@
                }
            }else {
                //直接入库
                stockUtils.addStock(productProcessRouteItem.getProductModelId(), productionProductOutput.getQuantity(), StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
                stockUtils.addStock(productProcessRouteItem.getProductModelId(), productionProductOutput.getQuantity(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId());
            }
            /*更新工单和生产订单*/
            ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId());
@@ -229,10 +234,7 @@
            productOrderMapper.updateById(productOrder);
            /*添加生产核算*/
            SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder()
                    .salesLedgerWorkId(productionProductMain.getId())
                    .salesLedgerSchedulingId(0L)
                    .salesLedgerId(productOrder.getSalesLedgerId())
                    .salesLedgerProductId(productOrder.getSaleLedgerProductId())
                    .productMainId(productionProductMain.getId())
                    .schedulingUserId(user.getUserId())
                    .schedulingUserName(user.getNickName())
                    .finishedNum(productQty)
@@ -246,13 +248,14 @@
        //如果报废数量>0,需要进入报废的库存
        if (ObjectUtils.isNotEmpty(dto.getScrapQty())) {
            if (dto.getScrapQty().compareTo(BigDecimal.ZERO) > 0) {
                stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId());
                stockUtils.addUnStock(productModel.getId(), dto.getScrapQty(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode(), productionProductMain.getId());
            }
        }
        return true;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean removeProductMain(Long id) {
        ProductionProductMain productionProductMain = productionProductMainMapper.selectById(id);
        //该报工对应的工艺路线详情
@@ -261,20 +264,39 @@
        /*删除核算*/
        salesLedgerProductionAccountingMapper.delete(
                new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
                        .eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, productionProductMain.getId())
                        .eq(SalesLedgerProductionAccounting::getProductMainId, productionProductMain.getId())
        );
        /*更新工单和生产订单*/
        ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId());
        productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().subtract(productionProductOutput.getQuantity()));
        if (productWorkOrder != null && productionProductOutput != null) {
            BigDecimal outputQty = productionProductOutput.getQuantity() == null ? BigDecimal.ZERO : productionProductOutput.getQuantity();
            BigDecimal scrapQty = productionProductOutput.getScrapQty() == null ? BigDecimal.ZERO : productionProductOutput.getScrapQty();
            BigDecimal completeQty = productWorkOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productWorkOrder.getCompleteQuantity();
            BigDecimal validQuantity = outputQty.subtract(scrapQty);
            productWorkOrder.setCompleteQuantity(completeQty.subtract(validQuantity));
        productWorkOrder.setActualEndTime(null);
        productWorkOrderMapper.updateById(productWorkOrder);
        } else {
            throw new ServiceException("操作失败:工单信息或产出记录不存在");
        }
        //判断是否是最后一道工序
        List<ProductProcessRouteItem> productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.<ProductProcessRouteItem>lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId()));
        if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
        if (productProcessRouteItem.getDragSort() != null && productProcessRouteItems != null && productProcessRouteItem.getDragSort() == productProcessRouteItems.size()) {
            ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId());
            productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().subtract(productionProductOutput.getQuantity()));
            if (productOrder != null) {
                BigDecimal orderCompleteQty = productOrder.getCompleteQuantity() == null ? BigDecimal.ZERO : productOrder.getCompleteQuantity();
                BigDecimal outputQty = productionProductOutput.getQuantity() != null
                        ? productionProductOutput.getQuantity() : BigDecimal.ZERO;
                productOrder.setCompleteQuantity(orderCompleteQty.subtract(outputQty));
            productOrder.setEndTime(null);
            productOrderMapper.updateById(productOrder);
            } else {
                throw new ServiceException("关联的生产订单不存在");
            }
        }
        //删除质检
        qualityInspectMapper.selectList(
@@ -285,7 +307,9 @@
                    new LambdaQueryWrapper<QualityInspectParam>()
                            .eq(QualityInspectParam::getInspectId, q.getId()));
            qualityInspectMapper.deleteById(q.getId());
                stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
        });
        // åˆ é™¤äº§å‡ºè®°å½•
        productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>()
                .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId()));
@@ -293,13 +317,18 @@
        productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
                .eq(ProductionProductInput::getProductMainId, productionProductMain.getId()));
        //删除报废的入库记录
        stockUtils.deleteStockInRecord(productionProductMain.getId(), StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
        stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
        //删除不需要质检的合格入库
        stockUtils.deleteStockInRecord(productionProductMain.getId(), StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode());
        stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode());
        //删除投入对应的出库记录
        stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
        stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
        // åˆ é™¤ä¸»è¡¨
        productionProductMainMapper.deleteById(productionProductMain.getId());
        return true;
    }
    @Override
    public ArrayList<Long> listMain(List<Long> idList) {
        return productionProductMainMapper.listMain(idList);
    }
}
src/main/java/com/ruoyi/production/service/impl/SalesLedgerWorkServiceImpl.java
@@ -1,185 +1,182 @@
package com.ruoyi.production.service.impl;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.dto.Details;
import com.ruoyi.procurementrecord.dto.ProcurementAddDto;
import com.ruoyi.procurementrecord.dto.ProcurementRecordOutAdd;
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordOutServiceImpl;
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
import com.ruoyi.production.dto.ProductionReportDto;
import com.ruoyi.production.dto.SalesLedgerWorkDto;
import com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper;
import com.ruoyi.production.mapper.SalesLedgerWorkMapper;
import com.ruoyi.production.pojo.SalesLedgerProductionAccounting;
import com.ruoyi.production.pojo.SalesLedgerWork;
import com.ruoyi.production.service.SalesLedgerProductionAccountingService;
import com.ruoyi.production.service.SalesLedgerWorkService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.mapper.LossMapper;
import com.ruoyi.sales.pojo.Loss;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author :yys
 * @date : 2025/7/21 14:40
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SalesLedgerWorkServiceImpl extends ServiceImpl<SalesLedgerWorkMapper, SalesLedgerWork> implements SalesLedgerWorkService {
    private final SalesLedgerWorkMapper salesLedgerWorkMapper;
    private final SysUserMapper sysUserMapper;
    private final LossMapper lossMapper;
    private final SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    @Override
    public IPage<SalesLedgerWorkDto> listPage(Page page, SalesLedgerWorkDto salesLedgerWorkDto) {
        IPage<SalesLedgerWorkDto> iPage = salesLedgerWorkMapper.listPage(page, salesLedgerWorkDto);
        List<Loss> losses = lossMapper.selectList(null);
        if(!CollectionUtils.isEmpty(losses)){
            iPage.getRecords().forEach(item -> {
                String[] split = item.getSpecificationModel().split("\\*");
                if(split.length == 2 && isNumeric(split[1]) && isNumeric(split[0])){
                    // è®¡ç®—损耗(100000代表 æŸè€—çš„ 100 å’Œ å•位转换的1000)
                    BigDecimal divide = new BigDecimal(split[0])
                            .multiply(new BigDecimal(split[1]))
                            .multiply(item.getFinishedNum())
                            .multiply(losses.get(0).getRate())
                            .divide(new BigDecimal(100000), 2, RoundingMode.HALF_UP);
                    item.setLoss(divide.toString());
                }
            });
        }
        return iPage;
    }
    public static boolean isNumeric(String str) {
        if (str == null || str.isEmpty()) {
            return false;
        }
        // éåŽ†å­—ç¬¦ä¸²çš„æ¯ä¸ªå­—ç¬¦ï¼Œæ£€æŸ¥æ˜¯å¦ä¸ºæ•°å­—
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }
    private final ProcurementRecordServiceImpl procurementRecordService;
    @Override
    public int productionReport(ProductionReportDto productionReportDto) {
        SalesLedgerWork salesLedgerWork = salesLedgerWorkMapper.selectById(productionReportDto.getId());
        SysUser sysUser = sysUserMapper.selectUserById(productionReportDto.getSchedulingUserId());
        if (salesLedgerWork == null) throw new RuntimeException("报工数据不存在");
        if (salesLedgerWork.getStatus() == 3) throw new RuntimeException("报工已完成");
        if (sysUser == null) throw new RuntimeException("生产人不存在");
        salesLedgerWork.setFinishedNum(salesLedgerWork.getFinishedNum().add(productionReportDto.getFinishedNum()));
        if(salesLedgerWork.getSchedulingNum().compareTo(salesLedgerWork.getFinishedNum()) <= 0){
            salesLedgerWork.setStatus(3);
        }else{
            salesLedgerWork.setStatus(2);
        }
        salesLedgerWorkMapper.updateById(salesLedgerWork);
        // æ–°å¢žæŠ¥å·¥æ•°æ®
        SalesLedgerProductionAccounting.SalesLedgerProductionAccountingBuilder builder = SalesLedgerProductionAccounting.builder()
                .salesLedgerWorkId(salesLedgerWork.getId())
                .salesLedgerSchedulingId(salesLedgerWork.getSalesLedgerSchedulingId())
                .salesLedgerId(salesLedgerWork.getSalesLedgerId())
                .salesLedgerProductId((long)salesLedgerWork.getSalesLedgerProductId())
                .schedulingUserId(sysUser.getUserId())
                .schedulingUserName(sysUser.getNickName())
                .finishedNum(productionReportDto.getFinishedNum())
                .workHours(salesLedgerWork.getWorkHours())
                .process(salesLedgerWork.getProcess())
                .schedulingDate(LocalDate.parse(productionReportDto.getSchedulingDate(), DateTimeFormatter.ISO_LOCAL_DATE));
        salesLedgerProductionAccountingMapper.insert(builder.build());
        // ç”Ÿäº§æŠ¥å·¥æˆåŠŸ -> å…¥åº“
        LoginUser loginUser = SecurityUtils.getLoginUser();
        ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
        procurementRecordOutAdd.setType(2);
        procurementRecordOutAdd.setTypeName("生产入库");
        procurementRecordOutAdd.setNickName(loginUser.getNickName());
        List<Details> details = new ArrayList<>();
        Details details1 = new Details();
        details1.setInboundQuantity(productionReportDto.getFinishedNum());
        details1.setId(Integer.parseInt(salesLedgerWork.getSalesLedgerProductId().toString()));
        details1.setUnitPrice(productionReportDto.getUnitPrice());
        details1.setTotalPrice(productionReportDto.getTotalPrice());
        details.add(details1);
        procurementRecordOutAdd.setDetails(details);
        procurementRecordService.add(procurementRecordOutAdd);
        return 0;
    }
    @Override
    public int productionReportUpdate(ProductionReportDto productionReportDto) {
        SalesLedgerProductionAccounting salesLedgerProductionAccounting = salesLedgerProductionAccountingMapper.selectById(productionReportDto.getId());
        if(salesLedgerProductionAccounting == null) throw new RuntimeException("报工数据不存在");
        SysUser sysUser = sysUserMapper.selectUserById(productionReportDto.getSchedulingUserId());
        if(sysUser == null) throw new RuntimeException("生产人不存在");
        salesLedgerProductionAccounting.setFinishedNum(productionReportDto.getFinishedNum());
        salesLedgerProductionAccounting.setSchedulingUserId(sysUser.getUserId());
        salesLedgerProductionAccounting.setSchedulingUserName(sysUser.getNickName());
        salesLedgerProductionAccounting.setSchedulingDate(LocalDate.parse(productionReportDto.getSchedulingDate(), DateTimeFormatter.ISO_LOCAL_DATE));
        salesLedgerProductionAccountingMapper.updateById(salesLedgerProductionAccounting);
        // æ›´æ–°æŠ¥å·¥æ•°æ®
        SalesLedgerWork salesLedgerWork = salesLedgerWorkMapper.selectById(salesLedgerProductionAccounting.getSalesLedgerWorkId());
        if(salesLedgerWork == null) throw new RuntimeException("报工数据不存在");
        salesLedgerWork.setFinishedNum(productionReportDto.getFinishedNum());
        if(salesLedgerWork.getSchedulingNum().compareTo(salesLedgerWork.getFinishedNum()) <= 0){
            salesLedgerWork.setStatus(3);
        }else{
            salesLedgerWork.setStatus(2);
        }
        salesLedgerWork.setSchedulingUserId(sysUser.getUserId());
        salesLedgerWork.setSchedulingUserName(sysUser.getNickName());
        salesLedgerWork.setSchedulingDate(LocalDate.parse(productionReportDto.getSchedulingDate(), DateTimeFormatter.ISO_LOCAL_DATE));
        salesLedgerWorkMapper.updateById(salesLedgerWork);
        return 0;
    }
    @Override
    public List<ProductionReportDto> getList(Long id) {
        SalesLedgerWork salesLedgerWork = salesLedgerWorkMapper.selectById(id);
        if(salesLedgerWork == null) throw new RuntimeException("报工数据不存在");
        LambdaQueryWrapper<SalesLedgerProductionAccounting> salesLedgerProductionAccountingLambdaQueryWrapper = new LambdaQueryWrapper<>();
        salesLedgerProductionAccountingLambdaQueryWrapper.eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, id);
        List<SalesLedgerProductionAccounting> salesLedgerProductionAccountingList = salesLedgerProductionAccountingMapper.selectList(salesLedgerProductionAccountingLambdaQueryWrapper);
        if(CollectionUtils.isEmpty(salesLedgerProductionAccountingList)) throw new RuntimeException("没有生产记录数据");
        return salesLedgerProductionAccountingList.stream().map(salesLedgerProductionAccounting -> {
            ProductionReportDto productionReportDto = new ProductionReportDto();
            BeanUtils.copyProperties(salesLedgerProductionAccounting, productionReportDto);
            productionReportDto.setSchedulingDate(salesLedgerProductionAccounting.getSchedulingDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
            productionReportDto.setSchedulingNum(salesLedgerWork.getSchedulingNum());
            return productionReportDto;
        }).collect(Collectors.toList());
    }
}
//package com.ruoyi.production.service.impl;
//
//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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.ruoyi.common.utils.SecurityUtils;
//import com.ruoyi.framework.security.LoginUser;
//import com.ruoyi.framework.web.domain.AjaxResult;
//import com.ruoyi.procurementrecord.dto.Details;
//import com.ruoyi.procurementrecord.dto.ProcurementAddDto;
//import com.ruoyi.procurementrecord.dto.ProcurementRecordOutAdd;
//import com.ruoyi.procurementrecord.service.impl.ProcurementRecordOutServiceImpl;
//import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
//import com.ruoyi.production.dto.ProductionReportDto;
//import com.ruoyi.production.dto.SalesLedgerWorkDto;
//import com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper;
//import com.ruoyi.production.mapper.SalesLedgerWorkMapper;
//import com.ruoyi.production.pojo.SalesLedgerProductionAccounting;
//import com.ruoyi.production.pojo.SalesLedgerWork;
//import com.ruoyi.production.service.SalesLedgerProductionAccountingService;
//import com.ruoyi.production.service.SalesLedgerWorkService;
//import com.ruoyi.project.system.domain.SysUser;
//import com.ruoyi.project.system.mapper.SysUserMapper;
//import com.ruoyi.sales.mapper.LossMapper;
//import com.ruoyi.sales.pojo.Loss;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.BeanUtils;
//import org.springframework.stereotype.Service;
//import org.springframework.util.CollectionUtils;
//
//import java.math.BigDecimal;
//import java.math.RoundingMode;
//import java.time.LocalDate;
//import java.time.format.DateTimeFormatter;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.stream.Collectors;
//
///**
// * @author :yys
// * @date : 2025/7/21 14:40
// */
//@Service
//@RequiredArgsConstructor
//@Slf4j
//public class SalesLedgerWorkServiceImpl extends ServiceImpl<SalesLedgerWorkMapper, SalesLedgerWork> implements SalesLedgerWorkService {
//
//    private final SalesLedgerWorkMapper salesLedgerWorkMapper;
//
//    private final SysUserMapper sysUserMapper;
//
//    private final LossMapper lossMapper;
//
//    private final SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
//
//    @Override
//    public IPage<SalesLedgerWorkDto> listPage(Page page, SalesLedgerWorkDto salesLedgerWorkDto) {
//        IPage<SalesLedgerWorkDto> iPage = salesLedgerWorkMapper.listPage(page, salesLedgerWorkDto);
//        List<Loss> losses = lossMapper.selectList(null);
//        if(!CollectionUtils.isEmpty(losses)){
//            iPage.getRecords().forEach(item -> {
//                String[] split = item.getSpecificationModel().split("\\*");
//                if(split.length == 2 && isNumeric(split[1]) && isNumeric(split[0])){
//                    // è®¡ç®—损耗(100000代表 æŸè€—çš„ 100 å’Œ å•位转换的1000)
//                    BigDecimal divide = new BigDecimal(split[0])
//                            .multiply(new BigDecimal(split[1]))
//                            .multiply(item.getFinishedNum())
//                            .multiply(losses.get(0).getRate())
//                            .divide(new BigDecimal(100000), 2, RoundingMode.HALF_UP);
//                    item.setLoss(divide.toString());
//                }
//
//            });
//        }
//        return iPage;
//    }
//
//    public static boolean isNumeric(String str) {
//        if (str == null || str.isEmpty()) {
//            return false;
//        }
//        // éåŽ†å­—ç¬¦ä¸²çš„æ¯ä¸ªå­—ç¬¦ï¼Œæ£€æŸ¥æ˜¯å¦ä¸ºæ•°å­—
//        for (int i = 0; i < str.length(); i++) {
//            if (!Character.isDigit(str.charAt(i))) {
//                return false;
//            }
//        }
//        return true;
//    }
//
//    private final ProcurementRecordServiceImpl procurementRecordService;
//
//    @Override
//    public int productionReport(ProductionReportDto productionReportDto) {
//        SalesLedgerWork salesLedgerWork = salesLedgerWorkMapper.selectById(productionReportDto.getId());
//        SysUser sysUser = sysUserMapper.selectUserById(productionReportDto.getSchedulingUserId());
//        if (salesLedgerWork == null) throw new RuntimeException("报工数据不存在");
//        if (salesLedgerWork.getStatus() == 3) throw new RuntimeException("报工已完成");
//        if (sysUser == null) throw new RuntimeException("生产人不存在");
//        salesLedgerWork.setFinishedNum(salesLedgerWork.getFinishedNum().add(productionReportDto.getFinishedNum()));
//        if(salesLedgerWork.getSchedulingNum().compareTo(salesLedgerWork.getFinishedNum()) <= 0){
//            salesLedgerWork.setStatus(3);
//        }else{
//            salesLedgerWork.setStatus(2);
//        }
//        salesLedgerWorkMapper.updateById(salesLedgerWork);
//        // æ–°å¢žæŠ¥å·¥æ•°æ®
//        SalesLedgerProductionAccounting.SalesLedgerProductionAccountingBuilder builder = SalesLedgerProductionAccounting.builder()
//                .productMainId(null)
//                .schedulingUserId(sysUser.getUserId())
//                .schedulingUserName(sysUser.getNickName())
//                .finishedNum(productionReportDto.getFinishedNum())
//                .workHours(salesLedgerWork.getWorkHours())
//                .process(salesLedgerWork.getProcess())
//                .schedulingDate(LocalDate.parse(productionReportDto.getSchedulingDate(), DateTimeFormatter.ISO_LOCAL_DATE));
//        salesLedgerProductionAccountingMapper.insert(builder.build());
//        // ç”Ÿäº§æŠ¥å·¥æˆåŠŸ -> å…¥åº“
//        LoginUser loginUser = SecurityUtils.getLoginUser();
//        ProcurementAddDto procurementRecordOutAdd = new ProcurementAddDto();
//        procurementRecordOutAdd.setType(2);
//        procurementRecordOutAdd.setTypeName("生产入库");
//        procurementRecordOutAdd.setNickName(loginUser.getNickName());
//        List<Details> details = new ArrayList<>();
//        Details details1 = new Details();
//        details1.setInboundQuantity(productionReportDto.getFinishedNum());
//        details1.setId(Integer.parseInt(salesLedgerWork.getSalesLedgerProductId().toString()));
//        details1.setUnitPrice(productionReportDto.getUnitPrice());
//        details1.setTotalPrice(productionReportDto.getTotalPrice());
//        details.add(details1);
//        procurementRecordOutAdd.setDetails(details);
//        procurementRecordService.add(procurementRecordOutAdd);
//
//        return 0;
//    }
//
//    @Override
//    public int productionReportUpdate(ProductionReportDto productionReportDto) {
//        SalesLedgerProductionAccounting salesLedgerProductionAccounting = salesLedgerProductionAccountingMapper.selectById(productionReportDto.getId());
//        if(salesLedgerProductionAccounting == null) throw new RuntimeException("报工数据不存在");
//        SysUser sysUser = sysUserMapper.selectUserById(productionReportDto.getSchedulingUserId());
//        if(sysUser == null) throw new RuntimeException("生产人不存在");
//        salesLedgerProductionAccounting.setFinishedNum(productionReportDto.getFinishedNum());
//        salesLedgerProductionAccounting.setSchedulingUserId(sysUser.getUserId());
//        salesLedgerProductionAccounting.setSchedulingUserName(sysUser.getNickName());
//        salesLedgerProductionAccounting.setSchedulingDate(LocalDate.parse(productionReportDto.getSchedulingDate(), DateTimeFormatter.ISO_LOCAL_DATE));
//        salesLedgerProductionAccountingMapper.updateById(salesLedgerProductionAccounting);
//
//        // æ›´æ–°æŠ¥å·¥æ•°æ®
//        SalesLedgerWork salesLedgerWork = salesLedgerWorkMapper.selectById(salesLedgerProductionAccounting.getSalesLedgerWorkId());
//        if(salesLedgerWork == null) throw new RuntimeException("报工数据不存在");
//        salesLedgerWork.setFinishedNum(productionReportDto.getFinishedNum());
//        if(salesLedgerWork.getSchedulingNum().compareTo(salesLedgerWork.getFinishedNum()) <= 0){
//            salesLedgerWork.setStatus(3);
//        }else{
//            salesLedgerWork.setStatus(2);
//        }
//        salesLedgerWork.setSchedulingUserId(sysUser.getUserId());
//        salesLedgerWork.setSchedulingUserName(sysUser.getNickName());
//        salesLedgerWork.setSchedulingDate(LocalDate.parse(productionReportDto.getSchedulingDate(), DateTimeFormatter.ISO_LOCAL_DATE));
//        salesLedgerWorkMapper.updateById(salesLedgerWork);
//        return 0;
//    }
//
//    @Override
//    public List<ProductionReportDto> getList(Long id) {
//        SalesLedgerWork salesLedgerWork = salesLedgerWorkMapper.selectById(id);
//        if(salesLedgerWork == null) throw new RuntimeException("报工数据不存在");
//        LambdaQueryWrapper<SalesLedgerProductionAccounting> salesLedgerProductionAccountingLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        salesLedgerProductionAccountingLambdaQueryWrapper.eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, id);
//        List<SalesLedgerProductionAccounting> salesLedgerProductionAccountingList = salesLedgerProductionAccountingMapper.selectList(salesLedgerProductionAccountingLambdaQueryWrapper);
//        if(CollectionUtils.isEmpty(salesLedgerProductionAccountingList)) throw new RuntimeException("没有生产记录数据");
//        return salesLedgerProductionAccountingList.stream().map(salesLedgerProductionAccounting -> {
//            ProductionReportDto productionReportDto = new ProductionReportDto();
//            BeanUtils.copyProperties(salesLedgerProductionAccounting, productionReportDto);
//            productionReportDto.setSchedulingDate(salesLedgerProductionAccounting.getSchedulingDate().format(DateTimeFormatter.ISO_LOCAL_DATE));
//            productionReportDto.setSchedulingNum(salesLedgerWork.getSchedulingNum());
//            return productionReportDto;
//        }).collect(Collectors.toList());
//    }
//}
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
@@ -2,21 +2,18 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.procurementrecord.service.impl.ProcurementRecordServiceImpl;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityInspectFile;
import com.ruoyi.quality.pojo.QualityInspectParam;
import com.ruoyi.quality.pojo.QualityUnqualified;
import com.ruoyi.quality.service.IQualityInspectFileService;
import com.ruoyi.quality.service.IQualityInspectParamService;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.quality.service.IQualityUnqualifiedService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -74,7 +71,7 @@
        .in(QualityInspectFile::getInspectId,ids));
        //删除入库记录
        for (Integer id : ids) {
            stockUtils.deleteStockInRecord(Long.valueOf(id), StockQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
            stockUtils.deleteStockInRecord(Long.valueOf(id), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
        }
        //删除检验单
        return AjaxResult.success(qualityInspectService.removeBatchByIds(ids));
src/main/java/com/ruoyi/quality/pojo/QualityInspect.java
@@ -152,4 +152,9 @@
    @ApiModelProperty("关联检测标准主表id")
    private Long testStandardId;
    @TableField(exist = false)
    private String workOrderNo;
    @TableField(exist = false)
    private String purchaseContractNo;
}
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -8,7 +8,8 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.HackLoopTableRenderPolicy;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
@@ -93,7 +94,7 @@
            qualityUnqualifiedMapper.insert(qualityUnqualified);
        } else {
            //合格直接入库
            stockUtils.addStock(qualityInspect.getProductModelId(), qualityInspect.getQuantity(), StockQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), qualityInspect.getId());
            stockUtils.addStock(qualityInspect.getProductModelId(), qualityInspect.getQuantity(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode(), qualityInspect.getId());
        }
        qualityInspect.setInspectState(1);//已提交
        return qualityInspectMapper.updateById(qualityInspect);
src/main/java/com/ruoyi/quality/service/impl/QualityUnqualifiedServiceImpl.java
@@ -7,8 +7,9 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.procurementrecord.utils.StockUtils;
@@ -98,11 +99,7 @@
                            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);
                                ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
                                int sequenceNumber = 1; // é»˜è®¤åºå·
                                if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                                    String lastNo = lastWorkOrder.getWorkOrderNo().toString();
@@ -130,11 +127,11 @@
                    break;
                case "报废":
                    //调用不合格库存接口 å…¥ä¸åˆæ ¼åº“
                    stockUtils.addUnStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId());
                    stockUtils.addUnStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInUnQualifiedRecordTypeEnum.DEFECTIVE_SCRAP.getCode(), unqualified.getId());
                    break;
                case "让步放行":
                    //调用提交合格的接口
                    stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId());
                    stockUtils.addStock(qualityInspect.getProductModelId(), unqualified.getQuantity(), StockInQualifiedRecordTypeEnum.DEFECTIVE_PASS.getCode(), unqualified.getId());
                    qualityInspect.setCheckResult("合格");
                    qualityInspectService.submit(qualityInspect);
                    break;
src/main/java/com/ruoyi/sales/controller/ShipmentApprovalController.java
@@ -1,29 +1,18 @@
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.google.common.math.LongMath;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.procurementrecord.dto.ProcurementAddDto;
import com.ruoyi.procurementrecord.dto.ProcurementRecordOutAdd;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut;
import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage;
import com.ruoyi.procurementrecord.service.ProcurementRecordOutService;
import com.ruoyi.procurementrecord.service.ProcurementRecordService;
import com.ruoyi.procurementrecord.utils.StockUtils;
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;
@@ -31,9 +20,6 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
@RestController
@@ -101,7 +87,7 @@
            //出库
            stockUtils.addStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId());
            stockUtils.addStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId());
        }
        return AjaxResult.success();
src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -37,7 +37,7 @@
    /**
     * å®¢æˆ·åˆåŒå·
     */
    @Excel(name = "客户合同号")
    @Excel(name = "客户合同号", type = Excel.Type.IMPORT)
    private String customerContractNo;
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -5,16 +5,15 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.impl.ProductOrderServiceImpl;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.quality.mapper.QualityInspectMapper;
@@ -25,7 +24,6 @@
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.InvoiceRegistrationProduct;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShippingInfo;
@@ -92,6 +90,8 @@
    private ProductStructureMapper productStructureMapper;
    @Autowired
    private StockInventoryMapper stockInventoryMapper;
    @Autowired
    private ProductOrderServiceImpl productOrderServiceImpl;
    @Override
    public SalesLedgerProduct selectSalesLedgerProductById(Long id) {
@@ -228,9 +228,7 @@
            /*删除对应的生产数据并重新新增*/
            deleteProductionData(Arrays.asList(salesLedgerProduct.getId()));
            // åˆ é™¤ç”Ÿäº§æ ¸ç®—数据
            LambdaQueryWrapper<SalesLedgerProductionAccounting> reportWrapper = new LambdaQueryWrapper<>();
            reportWrapper.in(SalesLedgerProductionAccounting::getSalesLedgerId, salesLedgerId);
            salesLedgerProductionAccountingMapper.delete(reportWrapper);
            addProductionData(salesLedgerProduct);
        }
@@ -272,7 +270,8 @@
        productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
        productOrder.setProductModelId(salesLedgerProduct.getProductModelId());
        productOrder.setSaleLedgerProductId(salesLedgerProduct.getId());
        productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
        String string = productOrderServiceImpl.generateNextOrderNo(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        productOrder.setNpsNo(string);
        productOrder.setQuantity(salesLedgerProduct.getQuantity());//需求数量
        productOrder.setCompleteQuantity(BigDecimal.ZERO);//完成数量
        productOrderMapper.insert(productOrder);
@@ -303,13 +302,7 @@
                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);
                    ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectMax(datePrefix);
                    int sequenceNumber = 1; // é»˜è®¤åºå·
                    if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                        String lastNo = lastWorkOrder.getWorkOrderNo().toString();
@@ -396,9 +389,9 @@
                        //删除出库记录
                        for (Long productMainId : productMainIds) {
                            //删除生产出库记录
                            stockUtils.deleteStockOutRecord(productMainId, StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
                            stockUtils.deleteStockOutRecord(productMainId, StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
                            //删除报废的入库记录
                            stockUtils.deleteStockInRecord(productMainId, StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
                            stockUtils.deleteStockInRecord(productMainId, StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
                        }
                        qualityInspects.forEach(qualityInspect -> {
                            //inspectState=1 å·²æäº¤ ä¸èƒ½åˆ é™¤
@@ -407,6 +400,8 @@
                            }
                        });
                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
                        salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>()
                                .in(SalesLedgerProductionAccounting::getProductMainId, productMainIds));
                    }
                    // åˆ é™¤ç”Ÿäº§ä¸»è¡¨æ•°æ®
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -25,6 +25,8 @@
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.ProductionProductMainService;
import com.ruoyi.production.service.impl.ProductionProductMainServiceImpl;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysDeptMapper;
@@ -146,6 +148,8 @@
    private ProductMapper productMapper;
    @Autowired
    private ProductStructureMapper productStructureMapper;
    @Autowired
    private ProductionProductMainService productionProductMainService;
;
    @Override
@@ -560,18 +564,13 @@
        commonFileService.deleteByBusinessIds(idList, FileNameType.SALE.getValue());
        // åˆ é™¤ç”Ÿäº§ç®¡æŽ§æ•°æ®
        // åˆ é™¤ç”Ÿäº§è®¢å•数据
        LambdaQueryWrapper<SalesLedgerScheduling> in = new LambdaQueryWrapper<SalesLedgerScheduling>()
                .in(SalesLedgerScheduling::getSalesLedgerId, idList);
        salesLedgerSchedulingMapper.delete(in);
        // åˆ é™¤ç”Ÿäº§æ´¾å·¥æ•°æ®
        LambdaQueryWrapper<SalesLedgerWork> workOrderWrapper = new LambdaQueryWrapper<>();
        workOrderWrapper.in(SalesLedgerWork::getSalesLedgerId, idList);
        salesLedgerWorkMapper.delete(workOrderWrapper);
        // åˆ é™¤ç”Ÿäº§æ ¸ç®—数据
        LambdaQueryWrapper<SalesLedgerProductionAccounting> reportWrapper = new LambdaQueryWrapper<>();
        reportWrapper.in(SalesLedgerProductionAccounting::getSalesLedgerId, idList);
        salesLedgerProductionAccountingMapper.delete(reportWrapper);
        //查询生产报工id
        ArrayList<Long> mainIdList = productionProductMainService.listMain(idList);
        if (CollectionUtils.isNotEmpty(mainIdList)) {
            mainIdList.stream().forEach(mainId -> {
                productionProductMainService.removeProductMain(mainId);
            });
        }
        // 2. å†åˆ é™¤ä¸»è¡¨æ•°æ®
        return salesLedgerMapper.deleteBatchIds(idList);
    }
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -7,7 +7,7 @@
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.sales.dto.ShippingInfoDto;
@@ -66,7 +66,7 @@
        //扣减库存
        if(!"已发货".equals(byId.getStatus())){
            SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId());
            stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId());
            stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId());
        }
        byId.setExpressNumber(req.getExpressNumber());
        byId.setExpressCompany(req.getExpressCompany());
@@ -90,7 +90,7 @@
        // æ‰£å·²å‘货库存
        for (ShippingInfo shippingInfo : shippingInfos) {
            if("已发货".equals(shippingInfo.getStatus())) {
                stockUtils.deleteStockOutRecord(shippingInfo.getId(), StockQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode());
                stockUtils.deleteStockOutRecord(shippingInfo.getId(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode());
            }
        }
        // åˆ é™¤å‘货审批
src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -2,7 +2,8 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
@@ -46,7 +47,7 @@
    @PostMapping("/addstockInventory")
    @ApiOperation("新增库存")
    public R addstockInventory(@RequestBody StockInventoryDto stockInventoryDto) {
        stockInventoryDto.setRecordType(String.valueOf(StockQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode()));
        stockInventoryDto.setRecordType(String.valueOf(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode()));
        stockInventoryDto.setRecordId(0L);
        return R.ok(stockInventoryService.addstockInventory(stockInventoryDto));
    }
@@ -55,7 +56,7 @@
    @PostMapping("/subtractStockInventory")
    @ApiOperation("扣减库存")
    public R subtractStockInventory(@RequestBody StockInventoryDto stockInventoryDto) {
        stockInventoryDto.setRecordType(String.valueOf(StockQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_OUT.getCode()));
        stockInventoryDto.setRecordType(String.valueOf(StockOutQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_OUT.getCode()));
        stockInventoryDto.setRecordId(0L);
        return R.ok(stockInventoryService.subtractStockInventory(stockInventoryDto));
    }
src/main/java/com/ruoyi/stock/controller/StockUninventoryController.java
@@ -2,7 +2,8 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutUnQualifiedRecordTypeEnum;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.dto.StockUninventoryDto;
@@ -37,7 +38,7 @@
    @PostMapping("/addstockUninventory")
    @ApiOperation("新增库存")
    public R addstockUninventory(@RequestBody StockUninventoryDto stockUninventoryDto) {
        stockUninventoryDto.setRecordType(String.valueOf(StockUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode()));
        stockUninventoryDto.setRecordType(String.valueOf(StockInUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode()));
        stockUninventoryDto.setRecordId(0L);
        return R.ok(stockUninventoryService.addStockUninventory(stockUninventoryDto));
    }
@@ -46,7 +47,7 @@
    @PostMapping("/subtractstockUninventory")
    @ApiOperation("扣减库存")
    public R subtractstockUninventory(@RequestBody StockUninventoryDto stockUninventoryDto) {
        stockUninventoryDto.setRecordType(String.valueOf(StockUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode()));
        stockUninventoryDto.setRecordType(String.valueOf(StockOutUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode()));
        stockUninventoryDto.setRecordId(0L);
        return R.ok(stockUninventoryService.subtractStockUninventory(stockUninventoryDto));
    }
src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -4,8 +4,8 @@
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.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.common.utils.OrderUtils;
@@ -102,9 +102,9 @@
        List<StockInRecordExportData> list = stockInRecordMapper.listStockInRecordExportData(stockInRecordDto);
        for (StockInRecordExportData stockInRecordExportData : list) {
            if (stockInRecordExportData.getType().equals("0")) {
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockOutQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
            }else {
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockInUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
            }
        }
        ExcelUtil<StockInRecordExportData> util = new ExcelUtil<>(StockInRecordExportData.class);
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -5,7 +5,8 @@
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
@@ -127,7 +128,7 @@
                            item.getSpecificationModel().equals(dto.getModel())) {
                        StockInventoryDto stockInventoryDto = new StockInventoryDto();
                        stockInventoryDto.setRecordId(0L);
                        stockInventoryDto.setRecordType(StockQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode());
                        stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode());
                        stockInventoryDto.setQualitity(dto.getQualitity());
                        stockInventoryDto.setRemark(dto.getRemark());
                        stockInventoryDto.setWarnNum(dto.getWarnNum());
src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -4,8 +4,8 @@
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.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.common.utils.OrderUtils;
@@ -105,9 +105,9 @@
        List<StockOutRecordExportData> list = stockOutRecordMapper.listStockOutRecordExportData(stockOutRecordDto);
        for (StockOutRecordExportData stockInRecordExportData : list) {
            if (stockInRecordExportData.getType().equals("0")) {
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockOutQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
            }else {
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
                stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockInUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
            }
        }
        ExcelUtil<StockOutRecordExportData> util = new ExcelUtil<>(StockOutRecordExportData.class);
src/main/resources/application-zxsq.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,245 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: RuoYi
  # ç‰ˆæœ¬
  version: 3.8.9
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # æ–‡ä»¶è·¯å¾„ ç¤ºä¾‹ï¼ˆ Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  profile: /javaWork/product-inventory-management/file
  # èŽ·å–ip地址开关
  addressEnabled: false
  # éªŒè¯ç ç±»åž‹ math æ•°å­—计算 char å­—符验证
  captchaType: math
  # ååŒå®¡æ‰¹ç¼–号前缀(配置文件后缀命名)
  approvalNumberPrefix: NEW
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 9005
  servlet:
    # åº”用的访问路径
    context-path: /
  tomcat:
    # tomcat的URI编码
    uri-encoding: UTF-8
    # è¿žæŽ¥æ•°æ»¡åŽçš„æŽ’队数,默认为100
    accept-count: 1000
    threads:
      # tomcat最大线程数,默认为200
      max: 800
      # Tomcat启动初始化的线程数,默认值10
      min-spare: 100
# æ—¥å¿—配置
logging:
  level:
    com.ruoyi: warn
    org.springframework: warn
minio:
  endpoint: http://114.132.189.42/
  port: 7019
  secure: false
  accessKey: admin
  secretKey: 12345678
  preview-expiry: 24 # é¢„览地址默认24小时
  default-bucket: jxc
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # ä¸»åº“数据源
      master:
        url: jdbc:mysql://172.17.0.1:3306/product-inventory-management-zxsq?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: xd@123456..
      # ä»Žåº“数据源
      slave:
        # ä»Žæ•°æ®æºå¼€å…³/默认关闭
        enabled: false
        url:
        username:
        password:
      # åˆå§‹è¿žæŽ¥æ•°
      initialSize: 5
      # æœ€å°è¿žæŽ¥æ± æ•°é‡
      minIdle: 10
      # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
      maxActive: 20
      # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
      maxWait: 60000
      # é…ç½®è¿žæŽ¥è¶…æ—¶æ—¶é—´
      connectTimeout: 30000
      # é…ç½®ç½‘络超时时间
      socketTimeout: 60000
      # é…ç½®é—´éš”多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å°ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      minEvictableIdleTimeMillis: 300000
      # é…ç½®ä¸€ä¸ªè¿žæŽ¥åœ¨æ± ä¸­æœ€å¤§ç”Ÿå­˜çš„æ—¶é—´ï¼Œå•位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # é…ç½®æ£€æµ‹è¿žæŽ¥æ˜¯å¦æœ‰æ•ˆ
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      webStatFilter:
        enabled: true
      statViewServlet:
        enabled: true
        # è®¾ç½®ç™½åå•,不填则允许所有访问
        allow:
        url-pattern: /druid/*
        # æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·åå’Œå¯†ç 
        login-username: ruoyi
        login-password: 123456
      filter:
        stat:
          enabled: true
          # æ…¢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 1GB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 2GB
  # æœåŠ¡æ¨¡å—
  devtools:
    restart:
      # çƒ­éƒ¨ç½²å¼€å…³
      enabled: false
  # redis é…ç½®
  redis:
    # åœ°å€
    #    host: 127.0.0.1
    host: 172.17.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 1
    # å¯†ç 
    #    password: root2022!
    password:
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10s
    lettuce:
      pool:
        # è¿žæŽ¥æ± ä¸­çš„æœ€å°ç©ºé—²è¿žæŽ¥
        min-idle: 0
        # è¿žæŽ¥æ± ä¸­çš„æœ€å¤§ç©ºé—²è¿žæŽ¥
        max-idle: 8
        # è¿žæŽ¥æ± çš„æœ€å¤§æ•°æ®åº“连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
  # Quartz定时任务配置(新增部分)
  quartz:
    job-store-type: jdbc  # ä½¿ç”¨æ•°æ®åº“存储
    jdbc:
      initialize-schema: never  # é¦–次运行时自动创建表结构,成功后改为never
      schema: classpath:org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql  # MySQL表结构脚本
    properties:
      org:
        quartz:
          scheduler:
            instanceName: RuoYiScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate  # MySQL适配
            tablePrefix: qrtz_  # è¡¨åå‰ç¼€ï¼Œä¸Žè„šæœ¬ä¸€è‡´
            isClustered: false  # å•节点模式(集群需改为true)
            clusterCheckinInterval: 10000
            txIsolationLevelSerializable: true
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10  # çº¿ç¨‹æ± å¤§å°
            threadPriority: 5
            makeThreadsDaemons: true
          updateCheck: false  # å…³é—­ç‰ˆæœ¬æ£€æŸ¥
# token配置
token:
  # ä»¤ç‰Œè‡ªå®šä¹‰æ ‡è¯†
  header: Authorization
  # ä»¤ç‰Œå¯†é’¥
  secret: abcdefghijklmnopqrstuvwxyz
  # ä»¤ç‰Œæœ‰æ•ˆæœŸï¼ˆé»˜è®¤30分钟)
  expireTime: 450
# MyBatis Plus配置
mybatis-plus:
  # æœç´¢æŒ‡å®šåŒ…别名   æ ¹æ®è‡ªå·±çš„项目来
  typeAliasesPackage: com.ruoyi.**.pojo
  # é…ç½®mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # åŠ è½½å…¨å±€çš„é…ç½®æ–‡ä»¶
  configLocation: classpath:mybatis/mybatis-config.xml
  global-config:
    enable-sql-runner: true
    db-config:
      id-type: auto
# PageHelper分页插件
pagehelper:
  helperDialect: mysql
  supportMethodsArguments: true
  params: count=countSql
# Swagger配置
swagger:
  # æ˜¯å¦å¼€å¯swagger
  enabled: true
  # è¯·æ±‚前缀
  pathMapping: /dev-api
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# ä»£ç ç”Ÿæˆ
gen:
  # ä½œè€…
  author: ruoyi
  # é»˜è®¤ç”ŸæˆåŒ…路径 system éœ€æ”¹æˆè‡ªå·±çš„æ¨¡å—名称 å¦‚ system monitor tool
  packageName: com.ruoyi.project.system
  # è‡ªåŠ¨åŽ»é™¤è¡¨å‰ç¼€ï¼Œé»˜è®¤æ˜¯true
  autoRemovePre: false
  # è¡¨å‰ç¼€ï¼ˆç”Ÿæˆç±»åä¸ä¼šåŒ…含表前缀,多个用逗号分隔)
  tablePrefix: sys_
  # æ˜¯å¦å…è®¸ç”Ÿæˆæ–‡ä»¶è¦†ç›–到本地(自定义路径),默认不允许
  allowOverwrite: false
file:
  temp-dir: /javaWork/product-inventory-management/file/temp/uploads
  upload-dir: /javaWork/product-inventory-management/file/prod/uploads
src/main/resources/mapper/production/ProductOrderMapper.xml
@@ -17,8 +17,9 @@
        select po.*,
        sl.sales_contract_no,
        sl.customer_name,
        slp.product_category,
        slp.specification_model,
        p.product_name as product_category,
        pm.model as specification_model,
        pm.unit,
        ppr.process_route_code,
        pb.bom_no,
        ROUND(po.complete_quantity / po.quantity * 100, 2) AS completionStatus,
@@ -38,6 +39,8 @@
        FROM shipping_info
        GROUP BY sales_ledger_id
        ) shipping_status_counts ON sl.id = shipping_status_counts.sales_ledger_id
            left join product_model pm on po.product_model_id = pm.id
            left join product p on pm.product_id = p.id
        left join sales_ledger_product slp on po.sale_ledger_product_id = slp.id
        left join product_process_route ppr on po.id = ppr.product_order_id
        left join product_bom pb on pb.id = ppr.bom_id
@@ -66,8 +69,7 @@
        select pr.*
        from process_route pr
                 left join product_model pm on pr.product_model_id = pm.id
                 left join sales_ledger_product slp on pm.id = slp.product_model_id
        where slp.id = #{productModelId}
        where pm.id = #{productModelId}
    </select>
    <select id="listProcessBom" resultType="com.ruoyi.production.dto.ProductStructureDto">
        select ps.id,
src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -87,4 +87,12 @@
            actual_start_time &gt;= #{startDate}
            AND actual_start_time &lt;= #{endDate}
    </select>
    <select id="selectMax" resultType="com.ruoyi.production.pojo.ProductWorkOrder">
        SELECT SUBSTRING(work_order_no, 3) as work_order_no
        FROM product_work_order
        WHERE SUBSTRING(work_order_no, 3) like concat(#{datePrefix},'%')
        order by work_order_no  desc
        limit 1
        ;
    </select>
</mapper>
src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -71,7 +71,7 @@
        slpa.work_hours * slpa.finished_num AS wages
        FROM
        production_product_main ppm
        LEFT JOIN sales_ledger_production_accounting slpa ON slpa.sales_ledger_work_id = ppm.id
        LEFT JOIN sales_ledger_production_accounting slpa ON slpa.product_main_id = ppm.id
        LEFT JOIN production_product_output ppo ON ppm.id = ppo.product_main_id
        LEFT JOIN product_work_order pwo ON pwo.id = ppm.work_order_id
        LEFT JOIN product_order po ON po.id = pwo.product_order_id
@@ -93,6 +93,20 @@
            </if>
        </where>
    </select>
    <select id="listMain" resultType="java.lang.Long">
        SELECT ppm.id FROM production_product_main ppm
            left join product_work_order pwo on pwo.id = ppm.work_order_id
                  left join product_order po on po.id = pwo.product_order_id
                  left join sales_ledger sl on sl.id = po.sales_ledger_id
        <where>
            <if test="idList != null and idList.size() > 0">
                and sl.id in
                <foreach item="id" collection="idList" open="(" separator="," close=")">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>
    <delete id="deleteByWorkOrderIds" parameterType="java.util.List">
        DELETE FROM production_product_main
src/main/resources/mapper/production/SalesLedgerProductionAccountingMapper.xml
@@ -68,7 +68,7 @@
        '%'
        ) as output_rate
        FROM sales_ledger_production_accounting slpa
        LEFT JOIN production_product_main ppm ON slpa.sales_ledger_work_id = ppm.id
        LEFT JOIN production_product_main ppm ON slpa.product_main_id = ppm.id
        LEFT JOIN production_product_output ppout ON ppm.id = ppout.product_main_id
        <where>
            <if test="ew.schedulingUserName != null and ew.schedulingUserName !=''">
src/main/resources/mapper/purchase/PaymentRegistrationMapper.xml
@@ -199,6 +199,7 @@
        </where>
        GROUP BY T1.supplier_name
    </select>
    <select id="supplierNameListPageDetails" resultType="com.ruoyi.purchase.dto.PaymentRegistrationDto">
        SELECT
        T1.supplier_id,
@@ -209,7 +210,7 @@
        T1.purchase_contract_number,
        T2.payment_date
        FROM purchase_ledger T1
        LEFT JOIN payment_registration T2 ON T1.id = T2.purchase_ledger_id
        INNER JOIN payment_registration T2 ON T1.id = T2.purchase_ledger_id
        <where>
            T1.supplier_id = #{req.supplierId}
            <if test="req.supplierName != null and req.supplierName != '' ">
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -28,7 +28,8 @@
        pl.approve_user_ids,
        sm.is_white,
        pl.approval_status,
        pl.payment_method
        pl.payment_method,
        pl.remarks
        from purchase_ledger pl
        left join sales_ledger_product slp on slp.sales_ledger_id = pl.id and slp.type=2
        left join product_record pr on pl.id = pr.purchase_ledger_id
src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -3,30 +3,49 @@
<mapper namespace="com.ruoyi.quality.mapper.QualityInspectMapper">
    <select id="qualityInspectListPage" resultType="com.ruoyi.quality.pojo.QualityInspect">
        SELECT
        *
        FROM quality_inspect
        where
        qi.*,
        <choose>
            <when test="qualityInspect.inspectType == 0">
                pl.purchase_contract_number as purchase_contract_no
            </when>
            <otherwise>
                pwo.work_order_no
            </otherwise>
        </choose>
        FROM
        quality_inspect qi
        <choose>
            <when test="qualityInspect.inspectType == 0 ">
                LEFT JOIN purchase_ledger pl ON pl.id = qi.purchase_ledger_id
            </when>
            <otherwise>
                LEFT JOIN production_product_main ppm ON qi.product_main_id = ppm.id
                LEFT JOIN product_work_order pwo ON ppm.work_order_id = pwo.id
            </otherwise>
        </choose>
        WHERE
        inspect_type=#{qualityInspect.inspectType}
        <if test="qualityInspect.supplier != null and qualityInspect.supplier != '' ">
            AND supplier like concat('%',#{qualityInspect.supplier},'%')
            AND qi.supplier like concat('%',#{qualityInspect.supplier},'%')
        </if>
        <if test="qualityInspect.customer != null and qualityInspect.customer != '' ">
            AND customer like concat('%',#{qualityInspect.customer},'%')
            AND qi.customer like concat('%',#{qualityInspect.customer},'%')
        </if>
        <if test="qualityInspect.process != null and qualityInspect.process != '' ">
            AND process like concat('%',#{qualityInspect.process},'%')
            AND qi.process like concat('%',#{qualityInspect.process},'%')
        </if>
        <if test="qualityInspect.productName != null and qualityInspect.productName != '' ">
            AND product_name like concat('%',#{qualityInspect.productName},'%')
            AND qi.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')
            AND qi.check_time &gt;= DATE_FORMAT(#{qualityInspect.entryDateStart},'%Y-%m-%d')
        </if>
        <if test="qualityInspect.entryDateEnd != null and qualityInspect.entryDateEnd != '' ">
            AND check_time &lt;= DATE_FORMAT(#{qualityInspect.entryDateEnd},'%Y-%m-%d')
            AND qi.check_time &lt;= DATE_FORMAT(#{qualityInspect.entryDateEnd},'%Y-%m-%d')
        </if>
        ORDER BY check_time DESC
        ORDER BY qi.check_time DESC
    </select>
    <select id="qualityInspectExport" resultType="com.ruoyi.quality.pojo.QualityInspect">
        SELECT
        *
src/main/resources/mapper/sales/ReceiptPaymentMapper.xml
@@ -432,22 +432,23 @@
        </where>
    </select>
    <select id="invoiceLedgerSalesAccount" resultType="com.ruoyi.sales.dto.InvoiceLedgerDto">
        SELECT
        T1.sales_contract_no,
        SUM(contract_amount) AS invoice_total,
        T1.contract_amount AS invoice_total,
        IFNULL( SUM(T2.receipt_payment_amount) , 0 ) AS receipt_payment_amount,
        IFNULL((IFNULL(SUM(contract_amount),0)  - IFNULL(SUM(T2.receipt_payment_amount),0)),0) AS unReceipt_payment_amount,
        IFNULL((T1.contract_amount - IFNULL(SUM(T2.receipt_payment_amount), 0)), 0) AS unReceipt_payment_amount,
        T2.receipt_payment_date
        FROM sales_ledger T1
        LEFT JOIN receipt_payment T2 ON T1.id = T2.sales_ledger_id
        INNER JOIN receipt_payment T2 ON T1.id = T2.sales_ledger_id
        <where>
            T1.customer_id = #{invoiceLedgerDto.customerId}
            <if test="invoiceLedgerDto.searchText != null and invoiceLedgerDto.searchText != '' ">
                T1.customer_name LIKE CONCAT ('%',#{invoiceLedgerDto.searchText},'%')
                AND T1.customer_name LIKE CONCAT ('%', #{invoiceLedgerDto.searchText}, '%')
            </if>
        </where>
        GROUP BY T1.sales_contract_no,T2.receipt_payment_date
        GROUP BY T1.id, T1.sales_contract_no, T1.contract_amount, T2.receipt_payment_date
    </select>
</mapper>