liding
9 天以前 cf65d0a608b21f07dc50a98b864dfe47def4f86b
fix:1.产品删除
2.原材料展示
3.菜单优化
4.区分角色编辑删除
已修改15个文件
265 ■■■■ 文件已修改
src/main/java/com/ruoyi/basic/controller/ProductController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/consumables/controller/ConsumablesInRecordController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/consumables/controller/ConsumablesOutRecordController.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductOrderController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/controller/RawMaterialController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/controller/StockInRecordController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/StockInRecordService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInRecordServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/consumables/ConsumablesInventoryMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/quality/RawMaterialMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInventoryMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysMenuMapper.xml 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/ProductController.java
@@ -17,11 +17,8 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -36,7 +33,7 @@
    private IProductService productService;
    private IProductModelService productModelService;
    @Autowired
    private ISalesLedgerProductService salesLedgerProductService;
    /**
     * 查询产品
@@ -80,13 +77,6 @@
    public AjaxResult remove(@RequestBody Long[] ids) {
        if (ids == null || ids.length == 0) {
            return AjaxResult.error("请传入要删除的ID");
        }
        // 检查是否有销售商品记录关联该产品
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SalesLedgerProduct::getProductId, ids);
        List<SalesLedgerProduct> salesLedgerProductList = salesLedgerProductService.list(queryWrapper);
        if (salesLedgerProductList.size() > 0) {
            return AjaxResult.error("该产品存在销售/采购记录,不能删除");
        }
        return toAjax(productService.delProductByIds(ids));
    }
src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
@@ -12,23 +12,28 @@
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductService;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.AjaxResult;
import lombok.AllArgsConstructor;
import com.ruoyi.consumables.mapper.ConsumablesInventoryMapper;
import com.ruoyi.consumables.pojo.ConsumablesInventory;
import com.ruoyi.stock.mapper.StockInventoryMapper;
import com.ruoyi.stock.pojo.StockInventory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Service
@AllArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductModelMapper productModelMapper;
    @Autowired
    private StockInventoryMapper stockInventoryMapper;
    @Autowired
    private ConsumablesInventoryMapper consumablesInventoryMapper;
    @Override
    public List<ProductTreeDto> selectProductList(ProductDto productDto) {
@@ -115,15 +120,21 @@
    @Override
    public int delProductByIds(Long[] ids) {
        List<StockInventory> stockInventoryList = stockInventoryMapper.selectList(new LambdaQueryWrapper<StockInventory>().in(StockInventory::getProductId, Arrays.asList(ids)));
        List<ConsumablesInventory> consumablesInventoryList = consumablesInventoryMapper.selectList(new LambdaQueryWrapper<ConsumablesInventory>().in(ConsumablesInventory::getProductId, Arrays.asList(ids)));
        if (!stockInventoryList.isEmpty() || !consumablesInventoryList.isEmpty()) {
            throw new RuntimeException("该产品存在库存关联!");
        }
        // 1. 删除子表 product_model 中关联的数据
        LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ProductModel::getProductId, ids);
        productModelMapper.delete(queryWrapper);
        // 2. 删除主表 product 数据
        int deleteCount = productMapper.deleteBatchIds(Arrays.asList(ids));
        return deleteCount;
        return productMapper.deleteBatchIds(Arrays.asList(ids));
    }
}
src/main/java/com/ruoyi/consumables/controller/ConsumablesInRecordController.java
@@ -2,14 +2,18 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.consumables.dto.ConsumablesInRecordDto;
import com.ruoyi.consumables.service.ConsumablesInRecordService;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.word.WeighbridgeDocGenerator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -22,6 +26,8 @@
public class ConsumablesInRecordController {
    @Autowired
    private ConsumablesInRecordService consumablesInRecordService;
    @Autowired
    private WeighbridgeDocGenerator weighbridgeDocGenerator;
    @GetMapping("/listPage")
    @Log(title = "生产入库-入库管理-列表", businessType = BusinessType.OTHER)
@@ -31,9 +37,23 @@
        return AjaxResult.success(result);
    }
    @PostMapping("/editStockInStock")
    @PreAuthorize("@ss.hasPermi('c_receipt_edit')")
    @ApiOperation("编辑入库记录")
    public AjaxResult editStockInStock(@RequestBody ConsumablesInRecordDto consumablesInRecordDto) {
        if (consumablesInRecordDto.getId() == null) {
            return AjaxResult.error("入库记录ID不能为空");
        }
        StockInRecordDto stockInRecordDto = new StockInRecordDto();
        BeanUtils.copyProperties(consumablesInRecordDto, stockInRecordDto);
        String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto);
        consumablesInRecordDto.setWeighbridgeDocPath(absoluteDocPath);
        consumablesInRecordDto.setStockInNum(consumablesInRecordDto.getQualitity());
        return AjaxResult.success(consumablesInRecordService.updateById(consumablesInRecordDto));
    }
    @DeleteMapping("")
    @PreAuthorize("@ss.hasPermi('c_receipt_cancel')")
    @Log(title = "入库管理-删除入库", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
src/main/java/com/ruoyi/consumables/controller/ConsumablesOutRecordController.java
@@ -2,14 +2,18 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.consumables.dto.ConsumablesOutRecordDto;
import com.ruoyi.consumables.service.ConsumablesOutRecordService;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.word.WeighbridgeDocGenerator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -30,6 +34,8 @@
public class ConsumablesOutRecordController {
    @Autowired
    private ConsumablesOutRecordService consumablesUnInventoryDto;
    @Autowired
    private WeighbridgeDocGenerator weighbridgeDocGenerator;
    @GetMapping("/listPage")
    @Log(title = "生产出库-出库管理-列表", businessType = BusinessType.OTHER)
@@ -45,13 +51,24 @@
        return AjaxResult.success(consumablesUnInventoryDto.add(consumablesOutRecordDto));
    }
    @PutMapping("/{id}")
    @Log(title = "出库管理-更新出库", businessType = BusinessType.UPDATE)
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody ConsumablesOutRecordDto consumablesOutRecordDto) {
        return AjaxResult.success(consumablesUnInventoryDto.update(id, consumablesOutRecordDto));
    @PostMapping("/editStockOut")
    @PreAuthorize("@ss.hasPermi('c_dispatch_edit')")
    @ApiOperation("编辑出库记录")
    public AjaxResult update(@RequestBody ConsumablesOutRecordDto consumablesOutRecordDto) {
        if (consumablesOutRecordDto.getId() == null) {
            return AjaxResult.error("出库记录ID不能为空");
        }
        StockInRecordDto stockInRecordDto = new StockInRecordDto();
        BeanUtils.copyProperties(consumablesOutRecordDto, stockInRecordDto);
        stockInRecordDto.setStockInNum(consumablesOutRecordDto.getStockOutNum());
        String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto);
        consumablesOutRecordDto.setWeighbridgeDocPath(absoluteDocPath);
        consumablesOutRecordDto.setStockOutNum(consumablesOutRecordDto.getQualitity());
        return AjaxResult.success(consumablesUnInventoryDto.updateById(consumablesOutRecordDto));
    }
    @DeleteMapping("")
    @PreAuthorize("@ss.hasPermi('c_dispatch_cancel')")
    @Log(title = "出库管理-删除出库", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
src/main/java/com/ruoyi/production/controller/ProductOrderController.java
@@ -14,7 +14,6 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;
@RequestMapping("/productOrder")
@@ -63,7 +62,7 @@
    @ApiOperation("新增生产订单")
    @PostMapping("addProductOrder")
    @PostMapping("/addProductOrder")
    public R addProductOrder(@RequestBody ProductOrder productOrder) {
        return R.ok(productOrderService.addProductOrder(productOrder));
    }
src/main/java/com/ruoyi/quality/controller/QualityUnqualifiedController.java
@@ -4,7 +4,8 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.quality.pojo.QualityUnqualified;
import com.ruoyi.quality.service.IQualityUnqualifiedService;
import org.springframework.util.CollectionUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@@ -39,12 +40,8 @@
     * @return
     */
    @DeleteMapping("/del")
    @PreAuthorize("@ss.hasPermi('nonconforming_cancel')")
    public AjaxResult delQualityUnqualified(@RequestBody List<Integer> ids) {
       qualityUnqualifiedService.listByIds(ids).stream().forEach(qualityUnqualified -> {
           if (qualityUnqualified.getInspectState()==1){
               throw new RuntimeException("该不合格数据已经处理无法删除!");
           }
       });
        return AjaxResult.success(qualityUnqualifiedService.removeBatchByIds(ids));
    }
@@ -64,6 +61,8 @@
     * @return
     */
    @PostMapping("/update")
    @PreAuthorize("@ss.hasPermi('nonconforming_edit')")
    @ApiOperation("不合格管理修改")
    public AjaxResult update(@RequestBody QualityUnqualified qualityUnqualified) {
        return AjaxResult.success(qualityUnqualifiedService.updateById(qualityUnqualified));
    }
src/main/java/com/ruoyi/quality/controller/RawMaterialController.java
@@ -2,13 +2,15 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.RawMaterialInspectState;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.quality.dto.RawMaterialDto;
import com.ruoyi.quality.pojo.*;
import com.ruoyi.quality.pojo.QualityInspectFile;
import com.ruoyi.quality.pojo.RawMaterial;
import com.ruoyi.quality.pojo.RawMaterialQualityInspectItem;
import com.ruoyi.quality.service.IQualityInspectFileService;
import com.ruoyi.quality.service.RawMaterialQualityInspectItemService;
import com.ruoyi.quality.service.RawMaterialService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -96,17 +98,11 @@
     * 原料删除
     */
    @DeleteMapping("")
    @PreAuthorize("@ss.hasPermi('raw_cancel')")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody List<Integer> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return AjaxResult.error("请选择至少一条数据");
        }
        //如果已经提交就不允许删除
        List<RawMaterial> rawMaterials = rawMaterialService.list(Wrappers.<RawMaterial>lambdaQuery()
                .in(RawMaterial::getId,ids)
                .eq(RawMaterial::getInspectState, RawMaterialInspectState.RawMaterialInspectStateSubmitted.getCode()));
        if(!CollectionUtils.isEmpty(rawMaterials)){
            throw new RuntimeException("已提交的数据不允许删除");
        }
        //删除检验参数
        rawMaterialQualityInspectItemService.remove(Wrappers.<RawMaterialQualityInspectItem>lambdaQuery()
src/main/java/com/ruoyi/stock/controller/StockInRecordController.java
@@ -7,9 +7,11 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.service.StockInRecordService;
import com.ruoyi.stock.word.WeighbridgeDocGenerator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -22,6 +24,9 @@
public class StockInRecordController {
    @Autowired
    private StockInRecordService stockInRecordService;
    @Autowired
    private WeighbridgeDocGenerator weighbridgeDocGenerator;
    @GetMapping("/listPage")
    @Log(title = "生产入库-入库管理-列表", businessType = BusinessType.OTHER)
@@ -31,9 +36,21 @@
        return AjaxResult.success(result);
    }
    @PostMapping("/editStockInStock")
    @PreAuthorize("@ss.hasPermi('receipt_edit')")
    @ApiOperation("编辑入库记录")
    public AjaxResult editStockInStock(@RequestBody StockInRecordDto stockInRecordDto) {
        if (stockInRecordDto.getId() == null) {
            return AjaxResult.error("入库记录ID不能为空");
        }
        stockInRecordDto.setStockInNum(stockInRecordDto.getNetWeight());
        String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto);
        stockInRecordDto.setWeighbridgeDocPath(absoluteDocPath);
        return AjaxResult.success(stockInRecordService.updateById(stockInRecordDto));
    }
    @DeleteMapping("")
    @PreAuthorize("@ss.hasPermi('receipt_cancel')")
    @Log(title = "入库管理-删除入库", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
src/main/java/com/ruoyi/stock/controller/StockOutRecordController.java
@@ -2,14 +2,18 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.dto.StockOutRecordDto;
import com.ruoyi.stock.service.StockOutRecordService;
import com.ruoyi.stock.word.WeighbridgeDocGenerator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
@@ -30,6 +34,8 @@
public class StockOutRecordController {
    @Autowired
    private StockOutRecordService stockOutRecordService;
    @Autowired
    private WeighbridgeDocGenerator weighbridgeDocGenerator;
    @GetMapping("/listPage")
    @Log(title = "生产出库-出库管理-列表", businessType = BusinessType.OTHER)
@@ -45,13 +51,24 @@
        return AjaxResult.success(stockOutRecordService.add(stockOutRecordDto));
    }
    @PutMapping("/{id}")
    @Log(title = "出库管理-更新出库", businessType = BusinessType.UPDATE)
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody StockOutRecordDto stockOutRecordDto) {
        return AjaxResult.success(stockOutRecordService.update(id, stockOutRecordDto));
    @PostMapping("/editStockOut")
    @PreAuthorize("@ss.hasPermi('dispatch_edit')")
    @ApiOperation("编辑出库记录")
    public AjaxResult update(@RequestBody StockOutRecordDto stockOutRecordDto) {
        if (stockOutRecordDto.getId() == null) {
            return AjaxResult.error("出库记录ID不能为空");
        }
        StockInRecordDto stockInRecordDto = new StockInRecordDto();
        BeanUtils.copyProperties(stockOutRecordDto, stockInRecordDto);
        stockInRecordDto.setStockInNum(stockOutRecordDto.getStockOutNum());
        String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto);
        stockOutRecordDto.setWeighbridgeDocPath(absoluteDocPath);
        stockOutRecordDto.setStockOutNum(stockOutRecordDto.getStockOutNum());
        return AjaxResult.success(stockOutRecordService.updateById(stockOutRecordDto));
    }
    @DeleteMapping("")
    @PreAuthorize("@ss.hasPermi('dispatch_cancel')")
    @Log(title = "出库管理-删除出库", businessType = BusinessType.DELETE)
    public AjaxResult delete(@RequestBody List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
src/main/java/com/ruoyi/stock/service/StockInRecordService.java
@@ -14,8 +14,6 @@
    int add(StockInRecordDto stockInRecordDto);
    int update(Long id, StockInRecordDto stockInRecordDto);
    int batchDelete(List<Long> ids);
    void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto);
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.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.common.utils.OrderUtils;
@@ -51,20 +51,6 @@
        StockInRecord stockInRecord = new StockInRecord();
        BeanUtils.copyProperties(stockInRecordDto, stockInRecord);
        return stockInRecordMapper.insert(stockInRecord);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(Long id, StockInRecordDto stockInRecordDto) {
        // 判断对象是否存在
        StockInRecord stockInRecord = stockInRecordMapper.selectById(id);
        if (stockInRecord == null){
            throw new BaseException("该入库记录不存在,无法更新!!!");
        }
        String[] ignoreProperties = {"id", "inbound_batches"};//排除id属性
        BeanUtils.copyProperties(stockInRecordDto, stockInRecord, ignoreProperties);
        return stockInRecordMapper.updateById(stockInRecord);
    }
    @Override
src/main/resources/mapper/consumables/ConsumablesInventoryMapper.xml
@@ -60,8 +60,7 @@
        select
        si.id,
        -- 当前净重 = 入库净重 - 出库净重
        (COALESCE(sir.total_net_weight,0) - COALESCE(sor.total_net_weight,0)) as net_weight,
        si.qualitity,
        (COALESCE(sir.total_net_weight,0) - COALESCE(sor.total_net_weight,0)) as qualitity,
        si.purchaser,
        COALESCE(si.locked_quantity, 0) as locked_quantity,
        si.product_model_id,
@@ -85,7 +84,7 @@
        left join (
        select
        product_model_id,
        sum(net_weight) as total_net_weight
        sum(stock_in_num) as total_net_weight
        from consumables_in_record
        group by product_model_id
        ) sir on si.product_model_id = sir.product_model_id
@@ -93,7 +92,7 @@
        left join (
        select
        product_model_id,
        sum(net_weight) as total_net_weight
        sum(stock_out_num) as total_net_weight
        from consumables_out_record
        group by product_model_id
        ) sor on si.product_model_id = sor.product_model_id
src/main/resources/mapper/quality/RawMaterialMapper.xml
@@ -22,13 +22,13 @@
        FROM raw_material rm
        LEFT JOIN product_model pm ON rm.product_model_id = pm.id
        LEFT JOIN product p ON p.id = pm.product_id
        where
        1=1
        WHERE p.id IS NOT NULL
        AND rm.id IS NOT NULL
        <if test="params.checkType != null ">
            AND rm.check_type = #{params.checkType}
        </if>
        <if test="params.batchNo != null and params.batchNo != ''">
            and rm.batch_no like concat('%', #{params.batchNo}, '%')
            AND rm.batch_no LIKE CONCAT('%', #{params.batchNo}, '%')
        </if>
        <if test="params.inspectState != null ">
            AND rm.inspect_state = #{params.inspectState}
src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -60,8 +60,7 @@
        SELECT
        si.id,
        -- 当前净重 = 入库净重 - 出库净重
        (COALESCE(sir.total_net_weight, 0) - COALESCE(sor.total_net_weight, 0)) AS net_weight,
        si.qualitity,
        (COALESCE(sir.total_net_weight, 0) - COALESCE(sor.total_net_weight, 0)) AS qualitity,
        COALESCE(si.locked_quantity, 0) AS locked_quantity,
        si.product_model_id,
        si.create_time,
src/main/resources/mapper/system/SysMenuMapper.xml
@@ -30,8 +30,77 @@
    </resultMap>
    <sql id="selectMenuVo">
        select menu_id, menu_name, parent_id, order_num, path,app_component, component, `query`, route_name, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time
        from sys_menu
        WITH RECURSIVE valid_menus AS (
            SELECT
                menu_id,
                menu_name,
                parent_id,
                order_num,
                path,
                app_component,
                component,
                `query`,
                route_name,
                is_frame,
                is_cache,
                menu_type,
                visible,
                STATUS,
                IFNULL(perms, '') AS perms,
                icon,
                create_time,
                1 AS LEVEL
            FROM
                sys_menu
            WHERE
                STATUS = 0
              AND visible = 0
              AND (parent_id = 0 OR parent_id IS NULL) UNION ALL
            SELECT
                m.menu_id,
                m.menu_name,
                m.parent_id,
                m.order_num,
                m.path,
                m.app_component,
                m.component,
                m.`query`,
                m.route_name,
                m.is_frame,
                m.is_cache,
                m.menu_type,
                m.visible,
                m.STATUS,
                IFNULL(m.perms, '') AS perms,
                m.icon,
                m.create_time,
                vm.LEVEL + 1
            FROM
                sys_menu m
                    INNER JOIN valid_menus vm ON m.parent_id = vm.menu_id
            WHERE
                m.STATUS = 0
              AND m.visible = 0
        ) SELECT
              menu_id,
              menu_name,
              parent_id,
              order_num,
              path,
              app_component,
              component,
              `query`,
              route_name,
              is_frame,
              is_cache,
              menu_type,
              visible,
              STATUS,
              perms,
              icon,
              create_time
        FROM
            valid_menus
    </sql>
    
    <select id="selectMenuList" parameterType="com.ruoyi.project.system.domain.SysMenu" resultMap="SysMenuResult">