maven
2 天以前 bee04140fad1310e3d2e66ccbeb6f8b649bff6e8
Merge remote-tracking branch 'origin/dev_New' into dev_New
已添加15个文件
已修改20个文件
1005 ■■■■■ 文件已修改
doc/20260128_add_unique_to_staff_on_job.sql 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/controller/HomeController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/mapper/HomeMapper.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/HomeService.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeAccidentController.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeCertificationController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/controller/SafeContingencyPlanController.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeAccidentMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/mapper/SafeContingencyPlanMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeAccident.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/pojo/SafeContingencyPlan.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeAccidentService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/SafeContingencyPlanService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeAccidentServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeContingencyPlanServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/safe/service/impl/SafeHazardRecordServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/home/HomeMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeAccidentMapper.xml 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/safe/SafeContingencyPlanMapper.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260128_add_unique_to_staff_on_job.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
ALTER TABLE staff_on_job ADD unique (staff_no);
src/main/java/com/ruoyi/approve/service/impl/ApproveProcessServiceImpl.java
@@ -358,7 +358,9 @@
            case 6:
                return "报价审批";
            case 7:
                return "出库审批";
                return "发货审批";
            case 8:
                return "危险作业审批";
        }
        return null;
    }
src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -7,6 +7,7 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.home.dto.*;
import com.ruoyi.home.service.HomeService;
import com.ruoyi.dto.MapDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -96,6 +97,41 @@
        return AjaxResult.success(list);
    }
    @GetMapping("/productSalesAnalysis")
    @ApiOperation("各产品销售金额分析")
    public AjaxResult productSalesAnalysis() {
        List<MapDto> list = homeService.productSalesAnalysis();
        return AjaxResult.success(list);
    }
    @GetMapping("/rawMaterialPurchaseAmountRatio")
    @ApiOperation("原材料采购金额占比")
    public AjaxResult rawMaterialPurchaseAmountRatio(){
        List<MapDto> list = homeService.rawMaterialPurchaseAmountRatio();
        return AjaxResult.success(list);
    }
    @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);
    }
    /********************************************************营销采购类**************************************************/
    @GetMapping("/business")
    @Log(title = "销售-采购-库存数据", businessType = BusinessType.OTHER)
@@ -130,6 +166,7 @@
    }
    /********************************************************质量类*****************************************************/
    @GetMapping("/qualityStatistics")
    @Log(title = "质量分析", businessType = BusinessType.OTHER)
src/main/java/com/ruoyi/home/mapper/HomeMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.home.mapper;
import com.ruoyi.dto.MapDto;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * é¦–页统计 Mapper
 *
 * @author antigravity
 */
@Mapper
public interface HomeMapper {
    /**
     * æŸ¥è¯¢äº§å“å‘¨è½¬å¤©æ•°
     *
     * @return äº§å“å‘¨è½¬å¤©æ•°åˆ—表
     */
    List<MapDto> productTurnoverDays();
}
src/main/java/com/ruoyi/home/service/HomeService.java
@@ -1,9 +1,8 @@
package com.ruoyi.home.service;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.dto.MapDto;
import com.ruoyi.home.dto.*;
import com.ruoyi.production.dto.ProductOrderDto;
import com.ruoyi.production.dto.ProductWorkOrderDto;
import java.text.ParseException;
import java.util.List;
@@ -45,4 +44,14 @@
    ProductCategoryDistributionDto productCategoryDistribution();
    List<CustomerContributionRankingDto> customerContributionRanking(Integer type);
    List<MapDto> productSalesAnalysis();
    List<MapDto> rawMaterialPurchaseAmountRatio();
    List<MapDto> salesPurchaseStorageProductCount();
    List<Map<String, Object>> productInOutAnalysis(Integer type);
    List<MapDto> productTurnoverDays();
}
src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -2,8 +2,8 @@
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.extension.plugins.pagination.Page;
import com.ruoyi.home.mapper.HomeMapper;
import com.ruoyi.approve.mapper.ApproveProcessMapper;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.basic.mapper.CustomerMapper;
@@ -12,7 +12,6 @@
import com.ruoyi.basic.mapper.SupplierManageMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.pojo.SupplierManage;
import com.ruoyi.collaborativeApproval.mapper.NoticeMapper;
import com.ruoyi.collaborativeApproval.pojo.Notice;
@@ -86,6 +85,9 @@
    private SalesLedgerProductMapper salesLedgerProductMapper;
    @Autowired
    private StockInventoryMapper stockInventoryMapper;
    @Autowired
    private ProcurementRecordMapper procurementRecordStorageMapper;
    @Autowired
@@ -125,8 +127,9 @@
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserDeptMapper sysUserDeptMapper;
    @Autowired
    private StockInventoryMapper stockInventoryMapper;
    private HomeMapper homeMapper;
    @Override
    public HomeBusinessDto business() {
@@ -900,4 +903,199 @@
        }
        return result;
    }
    @Override
    public List<MapDto> productSalesAnalysis() {
        // èŽ·å–æ‰€æœ‰äº§å“å¤§ç±»çš„é”€å”®é¢
        List<Map<String, Object>> analysisResults = salesLedgerProductMapper.selectProductSalesAnalysis();
        if (CollectionUtils.isEmpty(analysisResults)) {
            return new ArrayList<>();
        }
        // è®¡ç®—总销售额
        BigDecimal totalSalesAmount = analysisResults.stream()
                .map(r -> (BigDecimal) r.get("value"))
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return analysisResults.stream()
                .map(result -> {
                    MapDto mapDto = new MapDto();
                    String name = (String) result.get("name");
                    BigDecimal value = (BigDecimal) result.get("value");
                    mapDto.setName(name);
                    mapDto.setValue(value != null ? value.setScale(2, RoundingMode.HALF_UP).toString() : "0.00");
                    if (totalSalesAmount.compareTo(BigDecimal.ZERO) == 0 || value == null) {
                        mapDto.setRate("0.00");
                    } else {
                        String rate = value.divide(totalSalesAmount, 4, RoundingMode.HALF_UP)
                                .multiply(new BigDecimal("100"))
                                .setScale(2, RoundingMode.HALF_UP)
                                .toString();
                        mapDto.setRate(rate);
                    }
                    return mapDto;
                })
                .collect(Collectors.toList());
    }
    @Override
    public List<MapDto> rawMaterialPurchaseAmountRatio() {
        // èŽ·å–æ‰€æœ‰åŽŸææ–™çš„é‡‡è´­é¢
        List<Map<String, Object>> analysisResults = salesLedgerProductMapper.selectRawMaterialPurchaseAnalysis();
        if (CollectionUtils.isEmpty(analysisResults)) {
            return new ArrayList<>();
        }
        // è®¡ç®—总采购额
        BigDecimal totalPurchaseAmount = analysisResults.stream()
                .map(r -> (BigDecimal) r.get("value"))
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return analysisResults.stream()
                .map(result -> {
                    MapDto mapDto = new MapDto();
                    String name = (String) result.get("name");
                    BigDecimal value = (BigDecimal) result.get("value");
                    mapDto.setName(name);
                    mapDto.setValue(value != null ? value.setScale(2, RoundingMode.HALF_UP).toString() : "0.00");
                    if (totalPurchaseAmount.compareTo(BigDecimal.ZERO) == 0 || value == null) {
                        mapDto.setRate("0.00");
                    } else {
                        String rate = value.divide(totalPurchaseAmount, 4, RoundingMode.HALF_UP)
                                .multiply(new BigDecimal("100"))
                                .setScale(2, RoundingMode.HALF_UP)
                                .toString();
                        mapDto.setRate(rate);
                    }
                    return mapDto;
                })
                .collect(Collectors.toList());
    }
    @Override
    public List<MapDto> salesPurchaseStorageProductCount() {
        LocalDate now = LocalDate.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String currentMonthStart = now.with(TemporalAdjusters.firstDayOfMonth()).format(dtf);
        String currentMonthNow = now.format(dtf);
        LocalDate lastMonth = now.minusMonths(1);
        String lastMonthStart = lastMonth.with(TemporalAdjusters.firstDayOfMonth()).format(dtf);
        String lastMonthEnd = lastMonth.with(TemporalAdjusters.lastDayOfMonth()).format(dtf);
        // é”€å”®
        int currentSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, currentMonthStart, currentMonthNow);
        int lastSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, lastMonthStart, lastMonthEnd);
        // é‡‡è´­
        int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart, currentMonthNow);
        int lastPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, lastMonthStart, lastMonthEnd);
        // å‚¨å­˜
        int currentStorage = stockInventoryMapper.selectStorageProductCountByDate(currentMonthStart, currentMonthNow);
        int lastStorage = stockInventoryMapper.selectStorageProductCountByDate(lastMonthStart, lastMonthEnd);
        List<MapDto> list = new ArrayList<>();
        list.add(createMapDto("销售产品数", currentSales, lastSales));
        list.add(createMapDto("采购产品数", currentPurchase, lastPurchase));
        list.add(createMapDto("储存产品数", currentStorage, lastStorage));
        return list;
    }
    private MapDto createMapDto(String name, int current, int last) {
        MapDto dto = new MapDto();
        dto.setName(name);
        dto.setValue(String.valueOf(current));
        if (last == 0) {
            dto.setRate(current > 0 ? "100.00" : "0.00");
        } else {
            BigDecimal curDec = new BigDecimal(current);
            BigDecimal lastDec = new BigDecimal(last);
            // å¢žé•¿çއ
            String rate = curDec.subtract(lastDec)
                    .divide(lastDec, 4, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal("100"))
                    .setScale(2, RoundingMode.HALF_UP)
                    .toString();
            dto.setRate(rate);
        }
        return dto;
    }
    @Override
    public List<Map<String, Object>> productInOutAnalysis(Integer type) {
        String targetName;
        if (type == 1) {
            targetName = "原材料";
        } else if (type == 2) {
            targetName = "成品";
        } else if (type == 3) {
            targetName = "半成品";
        } else {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Product::getProductName, targetName).isNull(Product::getParentId);
        Product rootCategory = productMapper.selectOne(queryWrapper);
        if (rootCategory == null) {
            log.warn("未找到名称为 {} çš„顶级产品分类", targetName);
            return new ArrayList<>();
        }
        Long rootCategoryId = rootCategory.getId();
        LocalDate now = LocalDate.now();
        DateTimeFormatter displayDtf = DateTimeFormatter.ofPattern("M/d");
        String startDate = now.minusDays(6).toString();
        String endDate = now.toString();
        List<Map<String, Object>> inCounts = stockInventoryMapper.selectDailyStockInCounts(rootCategoryId, startDate, endDate + " 23:59:59");
        List<Map<String, Object>> outCounts = stockInventoryMapper.selectDailyStockOutCounts(rootCategoryId, startDate, endDate + " 23:59:59");
        Map<LocalDate, BigDecimal> inMap = inCounts.stream()
                .collect(Collectors.toMap(
                        m -> ((java.sql.Date) m.get("date")).toLocalDate(),
                        m -> (BigDecimal) m.get("count"),
                        BigDecimal::add
                ));
        Map<LocalDate, BigDecimal> outMap = outCounts.stream()
                .collect(Collectors.toMap(
                        m -> ((java.sql.Date) m.get("date")).toLocalDate(),
                        m -> (BigDecimal) m.get("count"),
                        BigDecimal::add
                ));
        List<Map<String, Object>> result = new ArrayList<>();
        for (int i = 6; i >= 0; i--) {
            LocalDate date = now.minusDays(i);
            Map<String, Object> dataPoint = new LinkedHashMap<>();
            dataPoint.put("date", date.format(displayDtf)); // 1/23
            dataPoint.put("inCount", inMap.getOrDefault(date, BigDecimal.ZERO));
            dataPoint.put("outCount", outMap.getOrDefault(date, BigDecimal.ZERO));
            result.add(dataPoint);
        }
        return result;
    }
    @Override
    public List<MapDto> productTurnoverDays() {
        return homeMapper.productTurnoverDays();
    }
}
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -7,10 +7,13 @@
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.dto.StockUninventoryDto;
import com.ruoyi.stock.pojo.StockInRecord;
import com.ruoyi.stock.pojo.StockOutRecord;
import com.ruoyi.stock.service.StockInRecordService;
import com.ruoyi.stock.service.StockInventoryService;
import com.ruoyi.stock.service.StockOutRecordService;
import com.ruoyi.stock.service.StockUninventoryService;
import com.ruoyi.stock.service.impl.StockInRecordServiceImpl;
import com.ruoyi.stock.service.impl.StockOutRecordServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@@ -27,6 +30,7 @@
    private final StockUninventoryService stockUninventoryService;
    private final StockInventoryService stockInventoryService;
    private final StockInRecordService stockInRecordService;
    private final StockOutRecordService stockOutRecordService;
    /**
     * ä¸åˆæ ¼å…¥åº“
@@ -93,11 +97,18 @@
    }
    //不合格库存删除
    public void deleteStockRecord(Long recordId, String recordType) {
    public void deleteStockInRecord(Long recordId, String recordType) {
        StockInRecord one = stockInRecordService.getOne(new QueryWrapper<StockInRecord>()
                .lambda().eq(StockInRecord::getRecordId, recordId)
                .eq(StockInRecord::getRecordType, recordType));
        stockInRecordService.batchDelete(Collections.singletonList(one.getId()));
    }
    public void deleteStockOutRecord(Long recordId, String recordType) {
        StockOutRecord one = stockOutRecordService.getOne(new QueryWrapper<StockOutRecord>()
                .lambda().eq(StockOutRecord::getRecordId, recordId)
                .eq(StockOutRecord::getRecordType, recordType));
        stockOutRecordService.batchDelete(Collections.singletonList(one.getId()));
    }
}
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -287,9 +287,9 @@
        productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>()
                .eq(ProductionProductInput::getProductMainId, productionProductMain.getId()));
        //删除报废的入库记录
        stockUtils.deleteStockRecord(productionProductMain.getId(), StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
        stockUtils.deleteStockInRecord(productionProductMain.getId(), StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
        //删除投入对应的出库记录
        stockUtils.deleteStockRecord(productionProductMain.getId(), StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
        stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
        // åˆ é™¤ä¸»è¡¨
        productionProductMainMapper.deleteById(productionProductMain.getId());
        return true;
src/main/java/com/ruoyi/quality/controller/QualityInspectController.java
@@ -74,7 +74,7 @@
        .in(QualityInspectFile::getInspectId,ids));
        //删除入库记录
        for (Integer id : ids) {
            stockUtils.deleteStockRecord(Long.valueOf(id), StockQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
            stockUtils.deleteStockInRecord(Long.valueOf(id), StockQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode());
        }
        //删除检验单
        return AjaxResult.success(qualityInspectService.removeBatchByIds(ids));
src/main/java/com/ruoyi/safe/controller/SafeAccidentController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.pojo.SafeAccident;
import com.ruoyi.safe.pojo.SafeContingencyPlan;
import com.ruoyi.safe.service.SafeAccidentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--事故上报记录 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:40:31
 */
@RestController
@RequestMapping("/safeAccident")
@Api(tags = "安全生产--事故上报记录")
public class SafeAccidentController {
    @Autowired
    private SafeAccidentService safeAccidentService;
    @GetMapping("/page")
    @ApiOperation("分页查询")
    public R page(Page page, SafeAccident safeAccident) {
        return R.ok(safeAccidentService.pageSafeAccident(page, safeAccident));
    }
    @ApiOperation("新增事故上报记录")
    @PostMapping()
    public R add(@RequestBody SafeAccident safeAccident) {
        return R.ok(safeAccidentService.save(safeAccident));
    }
    @ApiOperation("修改事故上报记录")
    @PutMapping ()
    public R update(@RequestBody  SafeAccident safeAccident) {
        return R.ok(safeAccidentService.updateById(safeAccident));
    }
    @ApiOperation("删除事故上报记录")
    @DeleteMapping("/{ids}")
    public R delSafeCertification(@RequestBody List<Integer> ids) {
        return R.ok(safeAccidentService.removeBatchByIds(ids));
    }
}
src/main/java/com/ruoyi/safe/controller/SafeCertificationController.java
@@ -43,11 +43,13 @@
    public R add(@RequestBody SafeCertification safeCertification) {
        return R.ok(safeCertificationService.save(safeCertification));
    }
    @ApiOperation("修改安全规程与资质管理")
    @PutMapping ()
    public R update(@RequestBody  SafeCertification safeCertification) {
        return R.ok(safeCertificationService.updateById(safeCertification));
    }
    @ApiOperation("删除安全规程与资质管理")
    @DeleteMapping("/{ids}")
    public R delSafeCertification(@RequestBody List<Integer> ids) {
src/main/java/com/ruoyi/safe/controller/SafeContingencyPlanController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.ruoyi.safe.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.safe.pojo.SafeCertification;
import com.ruoyi.safe.pojo.SafeContingencyPlan;
import com.ruoyi.safe.service.SafeCertificationService;
import com.ruoyi.safe.service.SafeContingencyPlanService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--应急预案查阅 å‰ç«¯æŽ§åˆ¶å™¨
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:07:29
 */
@RestController
@RequestMapping("/safeContingencyPlan")
@Api(tags = "安全生产--应急预案查阅")
public class SafeContingencyPlanController {
    @Autowired
    private SafeContingencyPlanService safeContingencyPlanService;
    @GetMapping("/page")
    @ApiOperation("分页查询")
    public R page(Page page, SafeContingencyPlan safeContingencyPlan) {
        return R.ok(safeContingencyPlanService.pageSafeContingencyPlan(page, safeContingencyPlan));
    }
    @ApiOperation("新增应急预案查阅")
    @PostMapping()
    public R add(@RequestBody SafeContingencyPlan safeContingencyPlan) {
        return R.ok(safeContingencyPlanService.save(safeContingencyPlan));
    }
    @ApiOperation("修改应急预案查阅")
    @PutMapping ()
    public R update(@RequestBody  SafeContingencyPlan safeContingencyPlan) {
        return R.ok(safeContingencyPlanService.updateById(safeContingencyPlan));
    }
    @ApiOperation("删除应急预案查阅")
    @DeleteMapping("/{ids}")
    public R delSafeCertification(@RequestBody List<Integer> ids) {
        return R.ok(safeContingencyPlanService.removeBatchByIds(ids));
    }
}
src/main/java/com/ruoyi/safe/mapper/SafeAccidentMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.safe.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.pojo.SafeAccident;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--事故上报记录 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:40:31
 */
@Mapper
public interface SafeAccidentMapper extends BaseMapper<SafeAccident> {
    IPage<SafeAccident> pageSafeAccident(Page page, @Param("c") SafeAccident safeAccident);
}
src/main/java/com/ruoyi/safe/mapper/SafeContingencyPlanMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package com.ruoyi.safe.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.pojo.SafeContingencyPlan;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--应急预案查阅 Mapper æŽ¥å£
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:07:29
 */
@Mapper
public interface SafeContingencyPlanMapper extends BaseMapper<SafeContingencyPlan> {
    IPage<SafeContingencyPlan> pageSafeContingencyPlan(Page page, @Param("c") SafeContingencyPlan safeContingencyPlan);
}
src/main/java/com/ruoyi/safe/pojo/SafeAccident.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--事故上报记录
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:40:31
 */
@Getter
@Setter
@TableName("safe_accident")
@ApiModel(value = "SafeAccident对象", description = "安全生产--事故上报记录")
public class SafeAccident implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("事故编号")
    private String accidentCode;
    @ApiModelProperty("事故名称")
    private String accidentName;
    @ApiModelProperty("事故类型")
    private String accidentType;
    @ApiModelProperty("事故发生时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime happenTime;
    @ApiModelProperty("事故发生位置")
    private String happenLocation;
    @ApiModelProperty("事故等级")
    private String accidentGrade;
    @ApiModelProperty("事故直接原因")
    private String accidentCause;
    @ApiModelProperty("事故根本原因")
    private String rootCause;
    @ApiModelProperty("人员损失情况")
    private String personLoss;
    @ApiModelProperty("直接财产损失(元)    ")
    private BigDecimal assetLoss;
    @ApiModelProperty("生产影响情况")
    private String productionLoss;
    @ApiModelProperty("现场应急处置措施")
    private String handleMeasures;
    @ApiModelProperty("事故责任人")
    private String responsiblePerson;
    @ApiModelProperty("备注")
    private String remark;
    @ApiModelProperty("上报时间")
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @ApiModelProperty("上报人id")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty("上报人")
    @TableField(exist = false)
    private String createUserName;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
}
src/main/java/com/ruoyi/safe/pojo/SafeContingencyPlan.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
package com.ruoyi.safe.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--应急预案查阅
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:07:29
 */
@Getter
@Setter
@TableName("safe_contingency_plan")
@ApiModel(value = "SafeContingencyPlan对象", description = "安全生产--应急预案查阅")
public class SafeContingencyPlan implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @ApiModelProperty("应急预案编码")
    private String planCode;
    @ApiModelProperty("应急预案名称")
    private String planName;
    @ApiModelProperty("预案类型")
    private String planType;
    @ApiModelProperty("适用范围")
    private String applyScope;
    @ApiModelProperty("核心责任人")
    private Integer coreResponsorUserId;
    @ApiModelProperty("核心责任人")
    @TableField(exist = false)
    private String coreResponsorUserName;
    @ApiModelProperty("应急处置步骤")
    private String execSteps;
    @ApiModelProperty("发布生效时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate publishTime;
    @ApiModelProperty("备注")
    private String remark;
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @ApiModelProperty("最后修订时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT)
    private Integer tenantId;
}
src/main/java/com/ruoyi/safe/service/SafeAccidentService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.safe.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.pojo.SafeAccident;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--事故上报记录 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:40:31
 */
public interface SafeAccidentService extends IService<SafeAccident> {
    IPage<SafeAccident> pageSafeAccident(Page page, SafeAccident safeAccident);
}
src/main/java/com/ruoyi/safe/service/SafeContingencyPlanService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.safe.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.pojo.SafeContingencyPlan;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--应急预案查阅 æœåŠ¡ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:07:29
 */
public interface SafeContingencyPlanService extends IService<SafeContingencyPlan> {
    IPage<SafeContingencyPlan> pageSafeContingencyPlan(Page page, SafeContingencyPlan safeContingencyPlan);
}
src/main/java/com/ruoyi/safe/service/impl/SafeAccidentServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.ruoyi.safe.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.pojo.SafeAccident;
import com.ruoyi.safe.mapper.SafeAccidentMapper;
import com.ruoyi.safe.service.SafeAccidentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--事故上报记录 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:40:31
 */
@Service
public class SafeAccidentServiceImpl extends ServiceImpl<SafeAccidentMapper, SafeAccident> implements SafeAccidentService {
    @Autowired
    private SafeAccidentMapper safeAccidentMapper;
    @Override
    public IPage<SafeAccident> pageSafeAccident(Page page, SafeAccident safeAccident) {
        return safeAccidentMapper.pageSafeAccident(page, safeAccident);
    }
}
src/main/java/com/ruoyi/safe/service/impl/SafeContingencyPlanServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package com.ruoyi.safe.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.safe.pojo.SafeContingencyPlan;
import com.ruoyi.safe.mapper.SafeContingencyPlanMapper;
import com.ruoyi.safe.service.SafeContingencyPlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * <p>
 * å®‰å…¨ç”Ÿäº§--应急预案查阅 æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author èŠ¯å¯¼è½¯ä»¶ï¼ˆæ±Ÿè‹ï¼‰æœ‰é™å…¬å¸
 * @since 2026-01-28 02:07:29
 */
@Service
public class SafeContingencyPlanServiceImpl extends ServiceImpl<SafeContingencyPlanMapper, SafeContingencyPlan> implements SafeContingencyPlanService {
    @Autowired
    private SafeContingencyPlanMapper safeContingencyPlanMapper;
    @Override
    public IPage<SafeContingencyPlan> pageSafeContingencyPlan(Page page, SafeContingencyPlan safeContingencyPlan) {
        return safeContingencyPlanMapper.pageSafeContingencyPlan(page, safeContingencyPlan);
    }
}
src/main/java/com/ruoyi/safe/service/impl/SafeHazardRecordServiceImpl.java
@@ -16,6 +16,7 @@
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
@@ -51,6 +52,10 @@
        safeHazardRecord.setApplyUserId(SecurityUtils.getUserId().intValue());
        safeHazardRecord.setApplyTime(LocalDate.now());
        safeHazardRecordMapper.insert(safeHazardRecord);
        String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String no = "LY" + String.format("%s%03d", datePrefix, safeHazardRecord.getId());
        safeHazardRecord.setMaterialRecordCode(no);
        safeHazardRecordMapper.updateById(safeHazardRecord);
        //减库存
        safeHazard.setStockQty(safeHazard.getStockQty().subtract(safeHazardRecord.getApplyQty()));
        safeHazardMapper.updateById(safeHazard);
src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -12,6 +12,7 @@
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
 * äº§å“ä¿¡æ¯Mapper接口
@@ -33,4 +34,10 @@
    IPage<ProcurementBusinessSummaryDto> procurementBusinessSummaryListPage(Page page,@Param("req") ProcurementBusinessSummaryDto procurementBusinessSummaryDto);
    List<LossProductModelDto> selectProductBomStructure(@Param("salesLedegerId") Long salesLedegerId);
    List<Map<String, Object>> selectProductSalesAnalysis();
    List<Map<String, Object>> selectRawMaterialPurchaseAnalysis();
    int selectProductCountByTypeAndDate(@Param("type") Integer type, @Param("startDate") String startDate, @Param("endDate") String endDate);
}
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -7,6 +7,8 @@
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.framework.web.domain.R;
import com.ruoyi.procurementrecord.utils.StockUtils;
@@ -388,6 +390,13 @@
                                new LambdaQueryWrapper<QualityInspect>()
                                        .in(QualityInspect::getProductMainId, productMainIds)
                        );
                        //删除出库记录
                        for (Long productMainId : productMainIds) {
                            //删除生产出库记录
                            stockUtils.deleteStockOutRecord(productMainId, StockQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode());
                            //删除报废的入库记录
                            stockUtils.deleteStockInRecord(productMainId, StockUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode());
                        }
                        qualityInspects.forEach(qualityInspect -> {
                            //inspectState=1 å·²æäº¤ ä¸èƒ½åˆ é™¤
                            if (qualityInspect.getInspectState() == 1) {
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -1,7 +1,6 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -9,14 +8,11 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
@@ -27,7 +23,6 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.project.system.domain.SysDept;
@@ -151,6 +146,7 @@
    private ProductMapper productMapper;
    @Autowired
    private ProductStructureMapper productStructureMapper;
;
    @Override
    public List<SalesLedger> selectSalesLedgerList(SalesLedgerDto salesLedgerDto) {
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -8,7 +8,6 @@
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.StockQualifiedRecordTypeEnum;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.sales.dto.ShippingInfoDto;
@@ -16,7 +15,6 @@
import com.ruoyi.sales.mapper.ShippingInfoMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ICommonFileService;
import com.ruoyi.sales.service.ShippingInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -88,7 +86,7 @@
        // æ‰£å·²å‘货库存
        for (ShippingInfo shippingInfo : shippingInfos) {
            if("已发货".equals(shippingInfo.getStatus())) {
                stockUtils.deleteStockRecord(shippingInfo.getId(), StockQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode());
                stockUtils.deleteStockOutRecord(shippingInfo.getId(), StockQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode());
            }
        }
        // åˆ é™¤å‘货审批
src/main/java/com/ruoyi/staff/service/impl/StaffLeaveServiceImpl.java
@@ -5,6 +5,8 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.staff.dto.StaffLeaveDto;
import com.ruoyi.staff.mapper.StaffLeaveMapper;
import com.ruoyi.staff.mapper.StaffOnJobMapper;
@@ -29,6 +31,9 @@
    @Autowired
    private StaffOnJobMapper staffOnJobMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    //新增离职列表分页查询
    @Override
@@ -61,6 +66,12 @@
        }
        staffLeaveMapper.insert(staffLeave);
        // æ›´æ–°å¯¹åº”用户状态为停用
        // æ ¹æ®å‘˜å·¥ç¼–号查询用户
        SysUser sysUser = sysUserMapper.selectUserByUserName(staffOnJob.getStaffNo());
        sysUser.setStatus("1");
        sysUserMapper.updateUser(sysUser);
        // æ›´æ–°ç¦»èŒçŠ¶æ€ä¸ºç¦»èŒ
        staffOnJob.setStaffState(0);
       return staffOnJobMapper.updateById(staffOnJob);
src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -13,6 +13,7 @@
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
/**
 * <p>
@@ -40,5 +41,11 @@
    BigDecimal selectTotal();
    int selectStorageProductCountByDate(@Param("startDate") String startDate, @Param("endDate") String endDate);
    List<Map<String, Object>> selectDailyStockInCounts(@Param("rootCategoryId") Long rootCategoryId, @Param("startDate") String startDate, @Param("endDate") String endDate);
    List<Map<String, Object>> selectDailyStockOutCounts(@Param("rootCategoryId") Long rootCategoryId, @Param("startDate") String startDate, @Param("endDate") String endDate);
    BigDecimal selectTotalByDate( @Param("now") LocalDate now);
}
src/main/java/com/ruoyi/stock/pojo/StockOutRecord.java
@@ -29,7 +29,7 @@
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    private Long id;
    @ApiModelProperty("入库批次")
    private String outboundBatches;
src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java
@@ -80,7 +80,7 @@
                    StockInventoryDto stockInRecordDto = new StockInventoryDto();
                    stockInRecordDto.setProductModelId(stockInventory.getProductModelId());
                    stockInRecordDto.setQualitity(stockInRecord.getStockInNum());
                    stockInventoryMapper.updateAddStockInventory(stockInRecordDto);
                    stockInventoryMapper.updateSubtractStockInventory(stockInRecordDto);
                }
            }else if (stockInRecord.getType().equals("1")) {
                StockUninventory stockUninventory = stockUninventoryMapper.selectOne(new LambdaQueryWrapper<StockUninventory>().eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId()));
@@ -90,7 +90,7 @@
                    StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
                    stockUninventoryDto.setProductModelId(stockUninventory.getProductModelId());
                    stockUninventoryDto.setQualitity(stockInRecord.getStockInNum());
                    stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
                    stockUninventoryMapper.updateSubtractStockUnInventory(stockUninventoryDto);
                }
            }
        }
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -25,6 +25,7 @@
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@@ -83,7 +84,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) {
            //  æ–°å¢žå‡ºåº“记录
        //  æ–°å¢žå‡ºåº“记录
        StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
        stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId());
        stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType());
@@ -92,14 +93,18 @@
        stockOutRecordDto.setType("0");
        stockOutRecordService.add(stockOutRecordDto);
        StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper<StockInventory>().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()));
        if (stockInventoryDto.getQualitity().compareTo( oldStockInventory.getQualitity().subtract(oldStockInventory.getLockedQuantity()))>0) {
            throw new RuntimeException("库存不足无法出库");
        }
        if (ObjectUtils.isEmpty(oldStockInventory)) {
            throw new RuntimeException("产品库存不存在");
        }else {
            stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
        }
        BigDecimal lockedQty = oldStockInventory.getLockedQuantity();
        if (lockedQty == null) {
            lockedQty = BigDecimal.ZERO;
        }
        if (stockInventoryDto.getQualitity().compareTo(oldStockInventory.getQualitity().subtract(lockedQty)) > 0) {
            throw new RuntimeException("库存不足无法出库");
        }
        stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto);
        return true;
    }
src/main/resources/mapper/home/HomeMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.home.mapper.HomeMapper">
    <select id="productTurnoverDays" resultType="com.ruoyi.dto.MapDto">
        SELECT p.product_name                                                      AS name,
               DATEDIFF(IFNULL(MAX(sor.create_time), NOW()), MAX(sir.create_time)) AS value
        FROM product p
                 JOIN product_model pm ON p.id = pm.product_id
                 JOIN stock_in_record sir ON pm.id = sir.product_model_id
                 LEFT JOIN stock_out_record sor ON pm.id = sor.product_model_id
        GROUP BY p.id, p.product_name
    </select>
</mapper>
src/main/resources/mapper/safe/SafeAccidentMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.safe.mapper.SafeAccidentMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeAccident">
        <id column="id" property="id" />
        <result column="accident_code" property="accidentCode" />
        <result column="accident_name" property="accidentName" />
        <result column="accident_type" property="accidentType" />
        <result column="happen_time" property="happenTime" />
        <result column="happen_location" property="happenLocation" />
        <result column="accident_grade" property="accidentGrade" />
        <result column="accident_cause" property="accidentCause" />
        <result column="root_cause" property="rootCause" />
        <result column="person_loss" property="personLoss" />
        <result column="asset_loss" property="assetLoss" />
        <result column="production_loss" property="productionLoss" />
        <result column="handle_measures" property="handleMeasures" />
        <result column="responsible_person" property="responsiblePerson" />
        <result column="remark" property="remark" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
        <result column="tenant_id" property="tenantId" />
    </resultMap>
    <select id="pageSafeAccident" resultType="com.ruoyi.safe.pojo.SafeAccident">
        select sa.*,
               su.nick_name createUserName,
        from safe_accident sa
        left join sys_user su on sa.create_user = su.user_id
        where 1=1
        <if test="c.accidentCode != null and c.accidentCode != ''">
            and sa.accident_code like concat('%', #{c.accidentCode}, '%')
        </if>
        <if test="c.accidentName != null and c.accidentName != ''">
            and sa.accident_name like concat('%', #{accidentName}, '%')
        </if>
        <if test="c.accidentType != null and c.accidentType != ''">
            and sa.accident_type like concat('%', #{accidentType}, '%')
        </if>
        <if test="c.accidentGrade != null and c.accidentGrade != ''">
            and sa.accident_grade like concat('%', #{accidentGrade}, '%')
        </if>
    </select>
</mapper>
src/main/resources/mapper/safe/SafeContingencyPlanMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.safe.mapper.SafeContingencyPlanMapper">
    <!-- é€šç”¨æŸ¥è¯¢æ˜ å°„结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.safe.pojo.SafeContingencyPlan">
        <id column="id" property="id" />
        <result column="plan_code" property="planCode" />
        <result column="plan_name" property="planName" />
        <result column="plan_type" property="planType" />
        <result column="apply_scope" property="applyScope" />
        <result column="core_responsor_user_id" property="coreResponsorUserId" />
        <result column="exec_steps" property="execSteps" />
        <result column="publish_time" property="publishTime" />
        <result column="remark" property="remark" />
        <result column="create_time" property="createTime" />
        <result column="create_user" property="createUser" />
        <result column="update_time" property="updateTime" />
        <result column="update_user" property="updateUser" />
        <result column="tenant_id" property="tenantId" />
    </resultMap>
    <select id="pageSafeContingencyPlan" resultType="com.ruoyi.safe.pojo.SafeContingencyPlan">
         select scp.*, su.nick_name coreResponsorUserName
        from safe_contingency_plan scp
        left join sys_user su on scp.core_responsor_user_id = su.user_id
        where 1=1
        <if test="c.planCode != null and c.planCode != ''">
            and scp.plan_code like concat('%', #{c.planCode}, '%')
        </if>
        <if test="c.planName != null and c.planName != ''">
            and scp.plan_name like concat('%', #{c.planName}, '%')
        </if>
        <if test="c.planType != null and c.planType != ''">
            and scp.plan_type like concat('%', #{c.planType}, '%')
        </if>
    </select>
</mapper>
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -147,7 +147,7 @@
                       LEFT JOIN product_structure ps ON pb.id = ps.bom_id
                       LEFT JOIN product_model pm1 ON pm1.id = ps.product_model_id
                       LEFT JOIN product p ON p.id = pm1.product_id
              WHERE sl.id = #{salesLedegerId}) A
               WHERE sl.id = #{salesLedegerId}) A
        group by a.model, a.product_name, a.unit
    </select>
    <select id="selectProduct" resultType="com.ruoyi.sales.pojo.SalesLedgerProduct">
@@ -158,4 +158,46 @@
        from product_model pm
        left join product p on pm.product_id = p.id
    </select>
</mapper>
    <select id="selectProductSalesAnalysis" resultType="java.util.LinkedHashMap">
        SELECT
            product_category as name,
            SUM( tax_inclusive_total_price ) AS value
        FROM
            sales_ledger_product
        WHERE
            type = 1
        GROUP BY
            product_category
        ORDER BY
            value DESC
        LIMIT 5
    </select>
    <select id="selectRawMaterialPurchaseAnalysis" resultType="java.util.LinkedHashMap">
        SELECT
            pr.product_name AS name,
            SUM( slp.tax_inclusive_total_price ) AS value
        FROM
            sales_ledger_product slp
            JOIN product pr ON slp.product_id = pr.id
        WHERE
            slp.type = 2
            AND pr.parent_id = ( SELECT id FROM product WHERE product_name = '原材料' )
        GROUP BY
            pr.id,
            pr.product_name
        ORDER BY
            value DESC
        LIMIT 5
    </select>
    <select id="selectProductCountByTypeAndDate" resultType="int">
        SELECT COUNT(*)
        FROM sales_ledger_product
        WHERE type = #{type}
        AND register_date &gt;= #{startDate}
        AND register_date &lt;= #{endDate}
    </select>
</mapper>
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -185,7 +185,7 @@
        p.product_name
    </select>
    <select id="selectTotal" resultType="java.math.BigDecimal">
        select ifnull(sum(qualitity),0)
        select ifnull(sum(qualitity), 0)
        from stock_inventory
    </select>
    <select id="selectTotalByDate" resultType="java.math.BigDecimal">
@@ -195,4 +195,41 @@
           create_time &gt;= #{now} and create_time &lt; DATE_ADD(#{now}, INTERVAL 1 DAY)
    </select>
    <select id="selectStorageProductCountByDate" resultType="int">
        SELECT COUNT(*)
        FROM (SELECT create_time
              FROM stock_inventory
              UNION ALL
              SELECT create_time
              FROM stock_uninventory) combined
        WHERE create_time &gt;= #{startDate}
          AND create_time &lt;= #{endDate}
    </select>
    <select id="selectDailyStockInCounts" resultType="java.util.Map">
        SELECT DATE(sir.create_time) AS date,
               SUM(sir.stock_in_num) AS count
        FROM stock_in_record sir
                 JOIN product_model pm ON sir.product_model_id = pm.id
                 JOIN product p ON pm.product_id = p.id
        WHERE (p.parent_id = #{rootCategoryId} OR p.id = #{rootCategoryId})
          AND sir.create_time &gt;= #{startDate}
          AND sir.create_time &lt;= #{endDate}
        GROUP BY DATE(sir.create_time)
        ORDER BY DATE(sir.create_time) ASC
    </select>
    <select id="selectDailyStockOutCounts" resultType="java.util.Map">
        SELECT DATE(sor.create_time)  AS date,
               SUM(sor.stock_out_num) AS count
        FROM stock_out_record sor
                 JOIN product_model pm ON sor.product_model_id = pm.id
                 JOIN product p ON pm.product_id = p.id
        WHERE (p.parent_id = #{rootCategoryId} OR p.id = #{rootCategoryId})
          AND sor.create_time &gt;= #{startDate}
          AND sor.create_time &lt;= #{endDate}
        GROUP BY DATE(sor.create_time)
        ORDER BY DATE(sor.create_time) ASC
    </select>
</mapper>