feat: 添加功能

This commit is contained in:
曹鹏飞 2025-07-04 16:19:59 +08:00
parent f3a7e14206
commit f386039140
25 changed files with 1005 additions and 32 deletions

View File

@ -0,0 +1,54 @@
package com.nflg.wms.admin.controller;
import com.nflg.wms.admin.service.BomControllerService;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import com.nflg.wms.common.pojo.qo.BomSearchQO;
import com.nflg.wms.common.pojo.qo.BomUpdateQO;
import com.nflg.wms.starter.BaseController;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 齐套管理
*/
@RestController
@RequestMapping("/bom")
public class BomController extends BaseController {
@Resource
private BomControllerService bomControllerService;
/**
* 新增
*/
@PostMapping("add")
public ApiResult<Void> add(@Valid @RequestBody BomMaterialDTO request){
bomControllerService.add(request);
return ApiResult.success();
}
/**
* 更新
*/
@PostMapping("update")
public ApiResult<Void> update(@Valid @RequestBody BomUpdateQO request){
bomControllerService.update(request);
return ApiResult.success();
}
/**
* 搜索
* @param request 搜索参数
*/
@PostMapping("search")
public ApiResult<PageData<BomMaterialDTO>> search(@Valid @RequestBody BomSearchQO request){
return ApiResult.success(bomControllerService.search(request));
}
}

View File

@ -12,7 +12,10 @@ import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
@ -65,9 +68,38 @@ public class MaterialController extends BaseController {
/**
* 导出未设置物料清单
*/
@PostMapping("export")
@PostMapping("exportNotSet")
public void exportNotSet(HttpServletResponse response) throws Exception {
materialControllerService.exportNotSet(response);
}
/**
* 导出选择的数据
* @param ids id列表为空时导出模板
*/
@PostMapping("exportSelect")
public void exportSelect(HttpServletResponse response,@RequestBody List<Long> ids) throws Exception {
materialControllerService.exportSelect(response,ids);
}
/**
* 批量上传物料图片
* @param files 文件列表
*/
@Transactional
@PostMapping("uploadPics")
public ApiResult uploadPics(HttpServletResponse response, @Valid @RequestParam("files") @NotEmpty List<MultipartFile> files) throws Exception {
return materialControllerService.uploadPics(response,files);
}
/**
* 上传物料图片zip压缩包
* @param file zip压缩包
*/
@Transactional
@PostMapping("uploadZip")
public ApiResult uploadZip(HttpServletResponse response, @Valid @RequestParam("file") @NotEmpty MultipartFile file) throws Exception {
return materialControllerService.uploadZip(response,file);
}
}

View File

@ -6,6 +6,7 @@ import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.PackageMaterialDTO;
import com.nflg.wms.common.pojo.qo.*;
import com.nflg.wms.common.pojo.vo.PackageVO;
import com.nflg.wms.starter.BaseController;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
@ -23,7 +24,7 @@ import java.util.List;
*/
@RestController
@RequestMapping("/package")
public class StructuralPackageController {
public class StructuralPackageController extends BaseController {
@Resource
private StructuralPackageControllerService packageControllerService;
@ -111,4 +112,22 @@ public class StructuralPackageController {
return packageControllerService.importMaterials(response,packageId,file);
}
/**
* 导入钢构包
* @param file 文件
*/
@Transactional
@PostMapping("importKit")
public ApiResult importKit(HttpServletResponse response, @RequestParam(value = "file") MultipartFile file) throws IOException {
return packageControllerService.importKit(response,file);
}
/**
* 导出钢构包
*/
@GetMapping("exportKit")
public void exportKit(HttpServletResponse response,@Valid @RequestParam @NotNull Long id) throws Exception {
packageControllerService.exportKit(response,id);
}
}

View File

@ -0,0 +1,115 @@
package com.nflg.wms.admin.processor;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.nflg.wms.admin.service.BomMaterialService;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import com.nflg.wms.repository.entity.WmsMaterial;
import com.nflg.wms.repository.service.IWmsMaterialService;
import com.nflg.wms.starter.service.FileUploadService;
import jakarta.annotation.Resource;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Component;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;
import tech.powerjob.worker.log.OmsLogger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@Component(value = "materialZipImportProcessor")
public class MaterialZipImportProcessor implements BasicProcessor {
@Resource
private IWmsMaterialService materialService;
@Resource
private BomMaterialService bomMaterialService;
@Resource
private FileUploadService fileUploadService;
@Override
public ProcessResult process(TaskContext context) throws Exception {
OmsLogger omsLogger = context.getOmsLogger();
List<String> params=StrUtil.split(context.getInstanceParams(), "|");
String zipUrl=params.get(0);
String userName= params.get(1);
if (StrUtil.isBlank(zipUrl)) {
omsLogger.error("无效的zip地址");
return new ProcessResult(false, "无效的zip地址");
}
try (InputStream is = new URL(zipUrl).openStream(); ZipInputStream zis = new ZipInputStream(is)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
String name = entry.getName();
omsLogger.info("开始处理文件:{}",name);
if (!entry.isDirectory()) {
ByteArrayOutputStream osOut = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = zis.read(buffer)) > 0) {
osOut.write(buffer, 0, len);
}
String materialNo = name.substring(0, name.lastIndexOf("."));
omsLogger.info("物料编号:{}", materialNo);
BomMaterialDTO bomMaterialDTO = bomMaterialService.getMaterial(materialNo);
if (Objects.isNull(bomMaterialDTO)) {
omsLogger.error("主数据中未查找到该物料:{}", materialNo);
} else {
WmsMaterial wmsMaterial = materialService.getCurrent(materialNo);
if (Objects.isNull(wmsMaterial) || !(StrUtil.isNotBlank(wmsMaterial.getImage()) && Objects.nonNull(wmsMaterial.getWeight()))) {
omsLogger.info("添加图纸");
wmsMaterial = new WmsMaterial()
.setId(null)
.setVersion(Objects.isNull(wmsMaterial) ? 1 : wmsMaterial.getVersion() + 1)
.setNo(bomMaterialDTO.getNo())
.setDescribe(bomMaterialDTO.getDescribe())
.setDrawingNo(bomMaterialDTO.getDrawingNo())
.setCreateBy(userName)
.setCreateTime(LocalDateTime.now());
} else {
omsLogger.info("更新图纸");
wmsMaterial.setDescribe(bomMaterialDTO.getDescribe());
wmsMaterial.setDrawingNo(bomMaterialDTO.getDrawingNo());
wmsMaterial.setUpdateBy(userName);
wmsMaterial.setUpdateTime(LocalDateTime.now());
}
try(ByteArrayInputStream isIn = new ByteArrayInputStream(osOut.toByteArray())) {
String picUrl=fileUploadService.upload(buildFilePath(name), isIn);
omsLogger.info("上传后的图片地址:{}", picUrl);
wmsMaterial.setImage(picUrl);
if (materialService.saveOrUpdate(wmsMaterial)){
omsLogger.info("保存成功,id:"+wmsMaterial.getId());
}else {
omsLogger.error("保存失败");
}
}catch (Exception ex){
omsLogger.error("上传图片失败:{}", ex.getMessage());
}
}
}
omsLogger.info("处理完毕");
omsLogger.info("-----------------------------------------");
zis.closeEntry();
}
}
return new ProcessResult(true, "处理完毕");
}
private String buildFilePath(String fileName) {
String fileType="." + FilenameUtils.getExtension(fileName);
return StrUtil.format("admin/task/{}/{}/{}{}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))
, RandomUtil.randomString(4), IdUtil.fastUUID(), fileType);
}
}

View File

@ -0,0 +1,53 @@
package com.nflg.wms.admin.service;
import cn.hutool.core.convert.Convert;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import com.nflg.wms.common.pojo.qo.BomSearchQO;
import com.nflg.wms.common.pojo.qo.BomUpdateQO;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.repository.entity.WmsBom;
import com.nflg.wms.repository.service.IWmsBomService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Objects;
@Component
public class BomControllerService {
@Resource
private IWmsBomService bomService;
@Transactional
public void add(@Valid BomMaterialDTO dto) {
WmsBom parent = Convert.convert(WmsBom.class, dto);
parent.setCreateBy(UserUtil.getUserName());
parent.setCreateTime(LocalDateTime.now());
bomService.add(parent, dto.getChildren().stream().map(it->{
WmsBom wmsBom = Convert.convert(WmsBom.class, it);
wmsBom.setCreateBy(UserUtil.getUserName());
wmsBom.setCreateTime(LocalDateTime.now());
return wmsBom;
}).toList());
}
public void update(@Valid BomUpdateQO request) {
bomService.update(request.getParentId(),request.getChildren().stream().map(it->{
WmsBom wmsBom = Convert.convert(WmsBom.class, it);
wmsBom.setUpdateBy(UserUtil.getUserName());
wmsBom.setUpdateTime(LocalDateTime.now());
if (Objects.isNull(wmsBom.getId())){
wmsBom.setParentId(request.getParentId());
}
return wmsBom;
}).toList());
}
public PageData<BomMaterialDTO> search(@Valid BomSearchQO request) {
return bomService.search(request);
}
}

View File

@ -0,0 +1,16 @@
package com.nflg.wms.admin.service;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import org.springframework.stereotype.Component;
@Component
public class BomMaterialService {
public BomMaterialDTO getMaterial(String no){
// TODO 从主数据平台获取物料信息
return new BomMaterialDTO()
.setNo("test")
.setDescribe("测试的虚拟物料")
.setDrawingNo("tttt");
}
}

View File

@ -1,8 +1,14 @@
package com.nflg.wms.admin.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import com.nflg.wms.common.pojo.dto.MaterialAllExcelExportDTO;
import com.nflg.wms.common.pojo.dto.MaterialExcelExportDTO;
import com.nflg.wms.common.pojo.qo.MaterialAddQO;
import com.nflg.wms.common.pojo.qo.MaterialSearchQO;
@ -12,20 +18,31 @@ import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.WmsMaterial;
import com.nflg.wms.repository.service.IWmsMaterialService;
import com.nflg.wms.starter.service.FileUploadService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import org.apache.commons.io.FilenameUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.ttzero.excel.entity.ListSheet;
import org.ttzero.excel.entity.Workbook;
import tech.powerjob.client.PowerJobClient;
import tech.powerjob.common.request.query.JobInfoQuery;
import tech.powerjob.common.response.JobInfoDTO;
import tech.powerjob.common.response.ResultDTO;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -36,6 +53,15 @@ public class MaterialControllerService {
@Resource
private IWmsMaterialService materialService;
@Resource
private BomMaterialService bomMaterialService;
@Resource
private FileUploadService fileUploadService;
@Resource
private PowerJobClient powerJobClient;
public void add(@Valid MaterialAddQO request) {
WmsMaterial wmsMaterial = Convert.convert(WmsMaterial.class, request);
wmsMaterial.setCreateBy(UserUtil.getUserName());
@ -77,4 +103,100 @@ public class MaterialControllerService {
.addSheet(new ListSheet<>(datas).setRowHeight(100))
.writeTo(response.getOutputStream());
}
public void exportSelect(HttpServletResponse response, List<Long> ids) throws IOException {
if (CollectionUtil.isEmpty(ids)){
exportTemplate(response);
}else {
List<WmsMaterial> wmsMaterials = materialService.listByIds(ids);
List<MaterialAllExcelExportDTO> datas = wmsMaterials.stream().map(model -> Convert.convert(MaterialAllExcelExportDTO.class, model)).collect(Collectors.toList());
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
if (CollectionUtil.isEmpty(datas)) {
}else {
new Workbook()
.addSheet(new ListSheet<>(datas).setRowHeight(100))
.writeTo(response.getOutputStream());
}
}
}
private void exportTemplate(HttpServletResponse response) throws IOException {
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode("图纸导入模板.xlsx", StandardCharsets.UTF_8));
List<MaterialExcelExportDTO> datas = new ArrayList<>();
datas.add(new MaterialExcelExportDTO()
.setNo("")
.setDescribe("")
.setWidth("")
.setHeight("")
.setWeight("")
.setLength("")
.setRequirement(""));
new Workbook()
.addSheet(new ListSheet<>(datas))
.writeTo(response.getOutputStream());
}
@Transactional
public ApiResult uploadPics(HttpServletResponse response, @Valid @NotEmpty List<MultipartFile> files) throws Exception {
List<String> pics = new ArrayList<>();
List<WmsMaterial> materials = new ArrayList<>();
for (MultipartFile file : files){
String name = file.getOriginalFilename();
String materialNo = name.substring(0, name.lastIndexOf("."));
BomMaterialDTO bomMaterialDTO = bomMaterialService.getMaterial(materialNo);
if (Objects.isNull(bomMaterialDTO)) {
pics.add(name);
} else {
WmsMaterial wmsMaterial=materialService.getCurrent(materialNo);
if (Objects.isNull(wmsMaterial) || !(StrUtil.isNotBlank(wmsMaterial.getImage()) && Objects.nonNull(wmsMaterial.getWeight()))){
wmsMaterial=new WmsMaterial()
.setId(null)
.setVersion(Objects.isNull(wmsMaterial)?1:wmsMaterial.getVersion()+1)
.setNo(bomMaterialDTO.getNo())
.setDescribe(bomMaterialDTO.getDescribe())
.setDrawingNo(bomMaterialDTO.getDrawingNo())
.setCreateBy(UserUtil.getUserName())
.setCreateTime(LocalDateTime.now());
}else {
wmsMaterial.setDescribe(bomMaterialDTO.getDescribe());
wmsMaterial.setDrawingNo(bomMaterialDTO.getDrawingNo());
wmsMaterial.setUpdateBy(UserUtil.getUserName());
wmsMaterial.setUpdateTime(LocalDateTime.now());
}
String url = fileUploadService.upload(buildFilePath(name), file);
wmsMaterial.setImage(url);
materials.add(wmsMaterial);
}
}
if (CollectionUtil.isEmpty(pics)) {
if (CollectionUtil.isNotEmpty(materials)) {
materialService.saveOrUpdateBatch(materials);
}
return ApiResult.success();
}else {
return ApiResult.error("以下图片SAP料号无效:"+StrUtil.join(",", pics));
}
}
private String buildFilePath(String fileName) {
String fileType="." + FilenameUtils.getExtension(fileName);
return StrUtil.format("admin/{}/{}/{}/{}{}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")), UserUtil.getUserId()
, RandomUtil.randomString(4), IdUtil.fastUUID(), fileType);
}
public ApiResult uploadZip(HttpServletResponse response, @Valid @NotEmpty MultipartFile file) throws Exception{
String name = file.getOriginalFilename();
VUtil.trueThrowBusinessError(!StrUtil.endWith(name, ".zip")).throwMessage("请上传zip格式的压缩包");
String url = fileUploadService.upload(buildFilePath(name), file);
JobInfoQuery query = new JobInfoQuery();
query.setJobNameEq("图纸zip导入");
ResultDTO<List<JobInfoDTO>> result = powerJobClient.queryJob(query);
if (result.isSuccess()) {
powerJobClient.runJob(result.getData().get(0).getId(),url+"|"+UserUtil.getUserName(),0);
return ApiResult.success("任务已提交");
} else {
return ApiResult.error(result.getMessage());
}
}
}

View File

@ -18,7 +18,11 @@ import com.nflg.wms.common.util.DateTimeUtil;
import com.nflg.wms.common.util.EecExcelUtil;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.WmsMaterial;
import com.nflg.wms.repository.entity.WmsModel;
import com.nflg.wms.repository.entity.WmsStructuralPackage;
import com.nflg.wms.repository.service.IWmsMaterialService;
import com.nflg.wms.repository.service.IWmsModelService;
import com.nflg.wms.repository.service.IWmsStructuralPackageService;
import com.nflg.wms.starter.service.FileUploadService;
import jakarta.annotation.Resource;
@ -26,14 +30,19 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.ttzero.excel.entity.ListSheet;
import org.ttzero.excel.entity.TemplateSheet;
import org.ttzero.excel.entity.Workbook;
import org.ttzero.excel.reader.ExcelReader;
import org.ttzero.excel.reader.Sheet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -48,6 +57,7 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Slf4j
@Component
public class StructuralPackageControllerService {
@ -57,6 +67,11 @@ public class StructuralPackageControllerService {
@Resource
private FileUploadService fileUploadService;
@Resource
private IWmsMaterialService materialService;
@Resource
private IWmsModelService modelService;
@Transactional
public void add(@Valid PackageAddQO request) {
@ -183,8 +198,10 @@ public class StructuralPackageControllerService {
}
if (StrUtil.isBlank(dto.getVersion())) {
sb.append("图纸版本不能为空;");
}else if (!NumberUtils.isCreatable(dto.getVersion())){
sb.append("图纸版本无效;");
} else {
materialDTO.setVersion(dto.getVersion());
materialDTO.setVersion(Integer.valueOf(dto.getVersion()));
}
dto.setError(sb.toString());
materialDTOS.add(materialDTO);
@ -203,4 +220,116 @@ public class StructuralPackageControllerService {
}
return false;
}
public ApiResult importKit(HttpServletResponse response, MultipartFile file) throws IOException {
WmsStructuralPackage packageInfo = new WmsStructuralPackage()
.setCreateBy(UserUtil.getUserName())
.setCreateTime(LocalDateTime.now());
List<PackageMaterialDTO> materials = new ArrayList<>();
StringBuilder sb=new StringBuilder();
Sheet sheet = ExcelReader.read(file.getInputStream()).sheet(0);
sheet.rows().forEach(row -> {
switch (row.getRowNum()) {
case 2:
String no = row.getString(1);
VUtil.trueThrowBusinessError(StrUtil.isBlank(no)).throwMessage("钢构包编码不能为空");
WmsMaterial material=materialService.getCurrent(no);
VUtil.trueThrowBusinessError(Objects.isNull(material)).throwMessage("钢构包编码无效");
packageInfo.setNo(no);
packageInfo.setName(material.getDescribe());
packageInfo.setDrawingNo(material.getDrawingNo());
String modelNo= row.getString(3);
VUtil.trueThrowBusinessError(StrUtil.isBlank(modelNo)).throwMessage("机型编号不能为空");
List<String> modelNos=StrUtil.split(modelNo, ",");
List<WmsModel> models=modelService.lambdaQuery().select(WmsModel::getId, WmsModel::getNo).eq(WmsModel::getEnable,true).in(WmsModel::getNo, modelNos).list();
modelNos.removeIf(mno -> models.stream().anyMatch(model -> model.getNo().equals(mno)));
VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(modelNos)).throwMessage("以下机型编号无效:"+StrUtil.join(",", modelNos));
packageInfo.setModelIds(StrUtil.join(",",models.stream().map(WmsModel::getId).toList()));
break;
case 3:
String cate = row.getString(1);
VUtil.trueThrowBusinessError(StrUtil.isBlank(cate)).throwMessage("种类不能为空");
packageInfo.setCate(cate);
String eco = row.getString(3);
VUtil.trueThrowBusinessError(StrUtil.isBlank(eco)).throwMessage("ECO不能为空");
packageInfo.setEco( eco);
break;
case 4:
String remark = row.getString(3);
packageInfo.setRemark(remark);
String version = row.getString(1);
VUtil.trueThrowBusinessError(StrUtil.isBlank(version)).throwMessage("版本号不能为空");
VUtil.trueThrowBusinessError(!NumberUtils.isCreatable(version)).throwMessage("版本号无效");
packageInfo.setVersion(Integer.valueOf(version));
VUtil.trueThrowBusinessError(packageService.lambdaQuery()
.eq(WmsStructuralPackage::getNo, packageInfo.getNo())
.eq(WmsStructuralPackage::getVersion, packageInfo.getVersion())
.exists())
.throwMessage("该版本已存在");
VUtil.trueThrowBusinessError(StrUtil.isBlank(packageInfo.getRemark())
&& packageService.lambdaQuery().eq(WmsStructuralPackage::getNo, packageInfo.getNo()).exists())
.throwMessage("修改日志不能为空");
break;
default:
if (row.getRowNum() > 6){
String mno = row.getString(0);
if (StrUtil.isBlank(mno)){
sb.append(StrUtil.format("第{}行零件编码不能为空;", row.getRowNum()));
break;
}
WmsMaterial material1 = materialService.getCurrent(mno);
if (Objects.isNull(material1)) {
sb.append("零件编码").append(mno).append("无效;");
break;
}
PackageMaterialDTO dto = new PackageMaterialDTO();
dto.setNo(mno);
dto.setName(material1.getDescribe());
dto.setVersion(material1.getVersion());
dto.setStation(row.getString(1));
dto.setTray(row.getString(2));
String num=row.getString(3);
if (StrUtil.isBlank(num)){
sb.append(StrUtil.format("第{}行数量不能为空;", row.getRowNum()));
}else if (!NumberUtils.isCreatable(num)){
sb.append(StrUtil.format("第{}行数量无效;", row.getRowNum()));
}else {
dto.setNum(new BigDecimal(num));
}
num=row.getString(4);
if (StrUtil.isBlank(num)){
sb.append(StrUtil.format("第{}行重量不能为空;", row.getRowNum()));
}else if (!NumberUtils.isCreatable(num)){
sb.append(StrUtil.format("第{}行重量无效;", row.getRowNum()));
}else {
dto.setWeight(new BigDecimal(num));
}
dto.setCreateBy(UserUtil.getUserName());
dto.setCreateTime(DateTimeUtil.format(LocalDate.now(), "yyyy-MM-dd"));
materials.add(dto);
}
break;
}
});
VUtil.trueThrowBusinessError(!sb.isEmpty()).throwMessage("数据校验失败:"+ sb);
packageInfo.setWeight(materials.stream()
.map(m -> m.getWeight().multiply(m.getNum()))
.reduce(BigDecimal.ZERO, BigDecimal::add));
packageInfo.setMaterials(JSONUtil.toJsonStr(materials));
packageService.add(packageInfo);
return ApiResult.success();
}
public void exportKit(HttpServletResponse response, @Valid @NotNull Long id) throws IOException {
PackageVO packageInfo = packageService.getInfo(id);
VUtil.trueThrowBusinessError(Objects.isNull(packageInfo)).throwMessage("数据不存在");
List<PackageMaterialDTO> list = JSONUtil.toList(packageInfo.getMaterials(), PackageMaterialDTO.class);
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(packageInfo.getNo()+"钢构包.xlsx", StandardCharsets.UTF_8));
new Workbook()
.addSheet(new TemplateSheet(new ClassPathResource("template/钢构包导出.xlsx").getInputStream())
.setData(packageInfo)
.setData("list", list)
).writeTo(response.getOutputStream());
}
}

View File

@ -0,0 +1,57 @@
package com.nflg.wms.common.pojo.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
@Data
@Accessors(chain = true)
public class BomMaterialDTO {
private Long id;
/**
* 父级id
*/
private Long parentId;
/**
* SAP料号
*/
@NotBlank
private String no;
/**
* 物料描述
*/
@NotBlank
private String describe;
/**
* 图号
*/
private String drawingNo;
/**
* 重量
*/
@NotBlank
private BigDecimal weight;
/**
* 数量
*/
@NotNull
private BigDecimal num;
/**
* 下级
*/
@NotEmpty
private List<BomMaterialDTO> children;
}

View File

@ -0,0 +1,90 @@
package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import org.ttzero.excel.annotation.ExcelColumn;
import org.ttzero.excel.annotation.MediaColumn;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class MaterialAllExcelExportDTO {
/**
* SAP料号
*/
@ExcelColumn("SAP料号")
private String no;
/**
* SAP料号描述
*/
@ExcelColumn("SAP料号描述")
private String describe;
/**
* 重量
*/
@ExcelColumn("重量")
private BigDecimal weight;
/**
* 长度
*/
@ExcelColumn("长度")
private BigDecimal length;
/**
* 宽度
*/
@ExcelColumn("宽度")
private BigDecimal width;
/**
* 高度
*/
@ExcelColumn("高度")
private BigDecimal height;
/**
* 打包要求
*/
@ExcelColumn("打包要求")
private String requirement;
/**
* 图片
*/
@MediaColumn
private String image;
/**
* 当前版本号
*/
@ExcelColumn("当前版本号")
private Integer version;
/**
* 创建人
*/
@ExcelColumn("创建人")
private String createBy;
/**
* 创建时间
*/
@ExcelColumn("创建时间")
private LocalDateTime createTime;
/**
* 最后更新人
*/
@ExcelColumn("最后更新人")
private String updateBy;
/**
* 最后更新时间
*/
@ExcelColumn("最后更新时间")
private LocalDateTime updateTime;
}

View File

@ -3,61 +3,64 @@ package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import org.ttzero.excel.annotation.ExcelColumn;
import org.ttzero.excel.annotation.MediaColumn;
import java.math.BigDecimal;
@Data
@Accessors(chain = true)
public class MaterialExcelExportDTO {
/**
* ID
*/
@ExcelColumn("ID")
private Long id;
/**
* SAP料号
*/
@ExcelColumn("*SAP料号")
@ExcelColumn("SAP料号")
private String no;
/**
* 物料描述
* SAP料号描述
*/
@ExcelColumn("*物料描述")
@ExcelColumn("SAP料号描述")
private String describe;
/**
* 图片
*/
@MediaColumn
private String image;
// /**
// * 图片
// */
// @MediaColumn
// private String image;
/**
* 当前版本号
*/
@ExcelColumn("当前版本号")
private Integer version;
// /**
// * 当前版本号
// */
// @ExcelColumn("当前版本号")
// private Integer version;
/**
* 重量
*/
@ExcelColumn("重量")
private BigDecimal weight;
private String weight;
/**
* 长度
*/
@ExcelColumn("长度")
private BigDecimal length;
private String length;
/**
* 宽度
*/
@ExcelColumn("宽度")
private BigDecimal width;
private String width;
/**
* 高度
*/
@ExcelColumn("高度")
private BigDecimal height;
private String height;
/**
* 打包要求
@ -65,9 +68,9 @@ public class MaterialExcelExportDTO {
@ExcelColumn("打包要求")
private String requirement;
/**
* 备注
*/
@ExcelColumn("备注")
private String remark;
// /**
// * 备注
// */
// @ExcelColumn("备注")
// private String remark;
}

View File

@ -40,7 +40,7 @@ public class PackageMaterialDTO {
/**
* 版本
*/
private String version;
private Integer version;
/**
* 创建人

View File

@ -0,0 +1,20 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class BomSearchQO extends PageQO{
/**
* SAP料号
*/
@NotBlank
private String no;
/**
* 物料描述
*/
@NotBlank
private String describe;
}

View File

@ -0,0 +1,24 @@
package com.nflg.wms.common.pojo.qo;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Data
public class BomUpdateQO {
/**
* 父级id
*/
@NotNull
private Long parentId;
/**
* 子级物料
*/
@NotEmpty
private List<BomMaterialDTO> children;
}

View File

@ -0,0 +1,84 @@
package com.nflg.wms.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* <p>
* 齐套
* </p>
*
* @author 代码生成器生成
* @since 2025
*/
@Getter
@Setter
@ToString
@TableName("wms_bom")
@Accessors(chain = true)
public class WmsBom implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 上级id
*/
private Long parentId;
/**
* SAP料号
*/
private String no;
/**
* 物料描述
*/
private String describe;
/**
* 图号
*/
private String drawingNo;
/**
* 数量
*/
private BigDecimal num;
/**
* 重量
*/
private BigDecimal weight;
/**
* 创建人
*/
private String createBy;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 最后更新人
*/
private String updateBy;
/**
* 最后更新时间
*/
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,16 @@
package com.nflg.wms.repository.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nflg.wms.repository.entity.WmsBom;
/**
* <p>
* 齐套 Mapper 接口
* </p>
*
* @author 代码生成器生成
* @since 2025
*/
public interface WmsBomMapper extends BaseMapper<WmsBom> {
}

View File

@ -0,0 +1,27 @@
package com.nflg.wms.repository.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import com.nflg.wms.common.pojo.qo.BomSearchQO;
import com.nflg.wms.repository.entity.WmsBom;
import jakarta.validation.Valid;
import java.util.List;
/**
* <p>
* 齐套 服务类
* </p>
*
* @author 代码生成器生成
* @since 2025
*/
public interface IWmsBomService extends IService<WmsBom> {
void add(WmsBom parent, List<WmsBom> list);
void update(Long parentId, List<WmsBom> list);
PageData<BomMaterialDTO> search(@Valid BomSearchQO request);
}

View File

@ -29,4 +29,6 @@ public interface IWmsMaterialService extends IService<WmsMaterial> {
List<MaterialVO> getHistory(@Valid @NotBlank String no);
List<WmsMaterial> getNotSet();
WmsMaterial getCurrent(String no);
}

View File

@ -0,0 +1,100 @@
package com.nflg.wms.repository.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.BomMaterialDTO;
import com.nflg.wms.common.pojo.qo.BomSearchQO;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.WmsBom;
import com.nflg.wms.repository.mapper.WmsBomMapper;
import com.nflg.wms.repository.service.IWmsBomService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* <p>
* 齐套 服务实现类
* </p>
*
* @author 代码生成器生成
* @since 2025
*/
@Service
public class WmsBomServiceImpl extends ServiceImpl<WmsBomMapper, WmsBom> implements IWmsBomService {
@Transactional
@Override
public void add(WmsBom parent, List<WmsBom> list) {
parent.setParentId(0L);
save(parent);
list.forEach(it -> {
it.setParentId(parent.getId());
});
saveBatch(list);
}
@Transactional
@Override
public void update(Long parentId, List<WmsBom> list) {
WmsBom parent = getById(parentId);
VUtil.trueThrowBusinessError(Objects.isNull(parent)).throwMessage("数据不存在");
parent.setUpdateBy(UserUtil.getUserName());
parent.setUpdateTime(LocalDateTime.now());
updateById(parent);
saveOrUpdateBatch(list);
}
@Override
public PageData<BomMaterialDTO> search(BomSearchQO request) {
List<WmsBom> boms = lambdaQuery()
.like(StrUtil.isNotBlank(request.getNo()), WmsBom::getNo, request.getNo())
.like(StrUtil.isNotBlank(request.getDescribe()), WmsBom::getDescribe, request.getDescribe())
.list();
Set<Long> parentIds = boms.stream().map(WmsBom::getParentId).filter(parentId -> !Objects.equals(parentId, 0L)).collect(Collectors.toSet());
if (CollectionUtil.isNotEmpty(parentIds)) {
boms.addAll(listByIds(parentIds));
}
List<BomMaterialDTO> datas = boms.stream()
.filter(it -> it.getParentId() == 0L)
.sorted(Comparator.comparing(WmsBom::getId))
.skip((long) (request.getPage() - 1) * request.getPageSize())
.limit(request.getPageSize())
.map(it -> new BomMaterialDTO()
.setId(it.getId())
.setParentId(it.getParentId())
.setNo(it.getNo())
.setDescribe(it.getDescribe())
.setDrawingNo(it.getDrawingNo())
.setNum(it.getNum())
.setWeight(it.getWeight())
.setChildren(boms.stream()
.filter(child -> child.getParentId().equals(it.getId()))
.map(child -> {
return new BomMaterialDTO()
.setId(child.getId())
.setParentId(child.getParentId())
.setNo(child.getNo())
.setDescribe(child.getDescribe())
.setDrawingNo(child.getDrawingNo())
.setNum(child.getNum())
.setWeight(child.getWeight());
})
.toList()
)).toList();
return new PageData<BomMaterialDTO>()
.setPage(request.getPage())
.setPageSize(request.getPageSize())
.setTotal(datas.size())
.setItems(datas);
}
}

View File

@ -60,4 +60,9 @@ public class WmsMaterialServiceImpl extends ServiceImpl<WmsMaterialMapper, WmsMa
public List<WmsMaterial> getNotSet() {
return baseMapper.getNotSet();
}
@Override
public WmsMaterial getCurrent(String no) {
return lambdaQuery().eq(WmsMaterial::getNo, no).orderByDesc(WmsMaterial::getId).last("limit 1").one();
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nflg.wms.repository.mapper.WmsBomMapper">
</mapper>

View File

@ -13,7 +13,7 @@
and describe like concat('%', #{request.describe}, '%')
</if>
</where>
ORDER BY "no",id DESC;
ORDER BY "no",id DESC
</select>
<select id="getHistory" resultType="com.nflg.wms.common.pojo.vo.MaterialVO">

View File

@ -16,7 +16,7 @@
and find_in_set(#{request.modelId},model_ids)>0
</if>
</where>
ORDER BY "no",id DESC;
ORDER BY "no",id DESC
</select>
<select id="getHistory" resultType="com.nflg.wms.common.pojo.vo.PackageVO">

View File

@ -33,7 +33,7 @@ public class CodeGeneratorTest {
)
.strategyConfig(builder -> {
builder
.addInclude("wms_structural_package") //只生成指定表
.addInclude("wms_material_task") //只生成指定表
.entityBuilder().idType(IdType.ASSIGN_ID)
.enableLombok()
.enableChainModel()