团队冲刺(补交)之出库模块

后端
实体类

点击查看代码
package com.example.entity;


import jakarta.persistence.*;

@Entity
@Table(name = "stockout")
public class Stockout {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", columnDefinition = "INT COMMENT '出库id'")
    private Integer id;

    @Column(name = "request_id", columnDefinition = "INT COMMENT '关联领用单'")
    private Integer requestId;

    @Column(name = "part_name", columnDefinition = "VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '备件名称'")
    private String partName;

    @Column(name = "part_model", columnDefinition = "VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '备件型号'")
    private String partModel;

    @Column(name = "sn", columnDefinition = "VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '备件SN'")
    private String sn;

    @Column(name = "operator_id", columnDefinition = "INT COMMENT '出库操作员'")
    private Integer operatorId;
    @Column(name = "location_id", columnDefinition = "varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '仓库ID'")
    private String locationId;

    @Column(name = "location_name", columnDefinition = "VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '出库仓库'")
    private String locationName;

    @Column(name = "out_time", columnDefinition = "VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '出库时间'")
    private String outTime;

    @Column(name = "status", columnDefinition = "VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '出库状态'")
    private String status;

    // Getters and Setters

    public String getLocationId() {
        return locationId;
    }

    public void setLocationId(String locationId) {
        this.locationId = locationId;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getRequestId() {
        return requestId;
    }

    public void setRequestId(Integer requestId) {
        this.requestId = requestId;
    }

    public String getPartName() {
        return partName;
    }

    public void setPartName(String partName) {
        this.partName = partName;
    }

    public String getPartModel() {
        return partModel;
    }

    public void setPartModel(String partModel) {
        this.partModel = partModel;
    }

    public String getSn() {
        return sn;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    public Integer getOperatorId() {
        return operatorId;
    }

    public void setOperatorId(Integer operatorId) {
        this.operatorId = operatorId;
    }

    public String getLocationName() {
        return locationName;
    }

    public void setLocationName(String locationName) {
        this.locationName = locationName;
    }

    public String getOutTime() {
        return outTime;
    }

    public void setOutTime(String outTime) {
        this.outTime = outTime;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Stockout() {
    }

    public Stockout(Integer id, Integer requestId, String partName, String partModel, String sn, Integer operatorId, String locationId, String locationName, String outTime, String status) {
        this.id = id;
        this.requestId = requestId;
        this.partName = partName;
        this.partModel = partModel;
        this.sn = sn;
        this.operatorId = operatorId;
        this.locationId = locationId;
        this.locationName = locationName;
        this.outTime = outTime;
        this.status = status;
    }
}
controller层
点击查看代码
package com.example.controller;

import com.example.dao.StockoutRepository;
import com.example.dao.UserRepository;
import com.example.entity.Stockout;
import com.example.service.StockoutService;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import java.util.List;

import static org.springframework.data.domain.Sort.Direction.DESC;

@RestController
@RequestMapping("/api/stockouts")
public class StockoutController {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private StockoutRepository stockoutRepository;

    private final StockoutService stockoutService;

    public StockoutController(StockoutService stockoutService) {
        this.stockoutService = stockoutService;
    }

    /**
     * 创建出库单
     */
    @PostMapping
    public ResponseEntity<Stockout> create(@RequestBody Stockout stockout) {
        return ResponseEntity.ok(stockoutService.createStockout(stockout));
    }


    @GetMapping
    public ResponseEntity<Page<Stockout>> list(
            @RequestParam(required = false) String locationName,
            @PageableDefault(sort = "outTime", direction = DESC) Pageable pageable) {
        return ResponseEntity.ok(stockoutService.getStockouts(locationName, pageable));
    }

    /**
     * 查看出库单详情
     */
    @GetMapping("/{id}")
    public ResponseEntity<Stockout> detail(@PathVariable Integer id) {
        return ResponseEntity.ok(stockoutService.getStockoutDetail(id));
    }

    /**
     * 更新出库状态
     */
    @PutMapping("/{id}/status")
    public ResponseEntity<Void> updateStatus(
            @PathVariable Integer id,
            @RequestParam String status) {
        stockoutService.updateStatus(id, status);
        return ResponseEntity.noContent().build();
    }
    @PostMapping("/batch")
    public ResponseEntity<List<Stockout>> createBatch(@RequestBody List<Stockout> stockouts) {
        // 验证操作员有效性
        stockouts.forEach(stockout -> {
            if (!userRepository.existsById(stockout.getOperatorId())) {
                throw new RuntimeException("无效操作员ID: " + stockout.getOperatorId());
            }
        });
        return ResponseEntity.ok(stockoutService.createBatch(stockouts));
    }


    @GetMapping("/all")
    public ResponseEntity<List<Stockout>> getAllStockouts(
            @RequestParam(required = false) List<String> status) { // 改为接收List

        if (status != null && !status.isEmpty()) {
            // 使用新的IN查询方法
            return ResponseEntity.ok(stockoutRepository.findByStatusIn(status));
        }
        return ResponseEntity.ok(stockoutRepository.findAll());
    }


}


dao层
点击查看代码
package com.example.dao;


import com.example.entity.Stockout;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface StockoutRepository extends JpaRepository<Stockout, Integer> {

    Page<Stockout> findByLocationName(String locationName, Pageable pageable);
    // StockoutRepository.java 新增方法
    List<Stockout> findByStatus(String status);
    // 添加这两个方法


    List<Stockout> findByStatusIn(List<String> statuses);

    List<Stockout> findBySn(String sn);
}



service层
点击查看代码
package com.example.service;// StockoutService.java
import com.example.dao.StockoutRepository;
import com.example.dao.UsageRequestRepository;
import com.example.entity.Stockout;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class StockoutService {

    private final StockoutRepository stockoutRepository;
    private final UsageRequestRepository usageRequestRepository;

    public StockoutService(StockoutRepository stockoutRepository,
                           UsageRequestRepository usageRequestRepository) {
        this.stockoutRepository = stockoutRepository;
        this.usageRequestRepository = usageRequestRepository;
    }

    /**
     * 创建出库记录(自动触发填充备件信息)
     */
    @Transactional
    public Stockout createStockout(Stockout stockout) {
        // 验证关联领用单是否存在
        if (stockout.getRequestId() != null &&
                !usageRequestRepository.existsById(stockout.getRequestId())) {
            throw new RuntimeException("关联领用单不存在");
        }

        // 数据库触发器会自动填充 part_name 和 part_model
        return stockoutRepository.save(stockout);
    }

    /**
     * 获取分页列表(带仓库过滤)
     */
    public Page<Stockout> getStockouts(String locationName, Pageable pageable) {
        if (locationName != null) {
            return stockoutRepository.findByLocationName(locationName, pageable);
        }
        return stockoutRepository.findAll(pageable);
    }

    /**
     * 更新出库状态
     */
    @Transactional
    public void updateStatus(Integer id, String status) {
        Stockout stockout = stockoutRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("出库记录不存在"));
        stockout.setStatus(status);
        stockoutRepository.save(stockout);
    }

    /**
     * 获取单个出库记录详情
     */
    public Stockout getStockoutDetail(Integer id) {
        return stockoutRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("出库记录不存在"));
    }
    @Transactional
    public List<Stockout> createBatch(List<Stockout> stockouts) {
        // 验证领用单ID有效性
        Set<Integer> requestIds = stockouts.stream()
                .map(Stockout::getRequestId)
                .collect(Collectors.toSet());

        if (!usageRequestRepository.existsAllByIdIn(requestIds)) {
            throw new RuntimeException("包含无效的领用单ID");
        }

        return stockoutRepository.saveAll(stockouts);
    }

}
前端与领用审核一起,审核完直接出库 ![](https://img2024.cnblogs.com/blog/3478919/202506/3478919-20250615212914997-1087349449.png)
posted @ 2025-06-15 21:29  YANGzLIN...11  阅读(16)  评论(0)    收藏  举报