diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/BomController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/BomController.java new file mode 100644 index 00000000..e1e48953 --- /dev/null +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/BomController.java @@ -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 add(@Valid @RequestBody BomMaterialDTO request){ + bomControllerService.add(request); + return ApiResult.success(); + } + + /** + * 更新 + */ + @PostMapping("update") + public ApiResult update(@Valid @RequestBody BomUpdateQO request){ + bomControllerService.update(request); + return ApiResult.success(); + } + + /** + * 搜索 + * @param request 搜索参数 + */ + @PostMapping("search") + public ApiResult> search(@Valid @RequestBody BomSearchQO request){ + return ApiResult.success(bomControllerService.search(request)); + } + +} diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/MaterialController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/MaterialController.java index de15d41e..d04ae01e 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/MaterialController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/MaterialController.java @@ -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 ids) throws Exception { + materialControllerService.exportSelect(response,ids); + } + + /** + * 批量上传物料图片 + * @param files 文件列表 + */ + @Transactional + @PostMapping("uploadPics") + public ApiResult uploadPics(HttpServletResponse response, @Valid @RequestParam("files") @NotEmpty List 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); + } + } diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/StructuralPackageController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/StructuralPackageController.java index 3b26a5cc..f23c78f6 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/StructuralPackageController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/StructuralPackageController.java @@ -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); + } + } diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/processor/MaterialZipImportProcessor.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/processor/MaterialZipImportProcessor.java new file mode 100644 index 00000000..e37f5514 --- /dev/null +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/processor/MaterialZipImportProcessor.java @@ -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 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); + } +} diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/BomControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/BomControllerService.java new file mode 100644 index 00000000..68366e31 --- /dev/null +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/BomControllerService.java @@ -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 search(@Valid BomSearchQO request) { + return bomService.search(request); + } +} diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/BomMaterialService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/BomMaterialService.java new file mode 100644 index 00000000..9346708d --- /dev/null +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/BomMaterialService.java @@ -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"); + } +} diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/MaterialControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/MaterialControllerService.java index 163282a5..1d4c386a 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/MaterialControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/MaterialControllerService.java @@ -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 ids) throws IOException { + if (CollectionUtil.isEmpty(ids)){ + exportTemplate(response); + }else { + List wmsMaterials = materialService.listByIds(ids); + List 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 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 files) throws Exception { + List pics = new ArrayList<>(); + List 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> 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()); + } + } } diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/StructuralPackageControllerService.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/StructuralPackageControllerService.java index a9b25e07..bd5b50ee 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/StructuralPackageControllerService.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/service/StructuralPackageControllerService.java @@ -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 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 modelNos=StrUtil.split(modelNo, ","); + List 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 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()); + } } diff --git a/nflg-wms-admin/src/main/resources/template/钢构包导出.xlsx b/nflg-wms-admin/src/main/resources/template/钢构包导出.xlsx new file mode 100644 index 00000000..ad80eb6c Binary files /dev/null and b/nflg-wms-admin/src/main/resources/template/钢构包导出.xlsx differ diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/BomMaterialDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/BomMaterialDTO.java new file mode 100644 index 00000000..97b96e9d --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/BomMaterialDTO.java @@ -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 children; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialAllExcelExportDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialAllExcelExportDTO.java new file mode 100644 index 00000000..a6b57a77 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialAllExcelExportDTO.java @@ -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; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialExcelExportDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialExcelExportDTO.java index a5b1478e..0137d2c9 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialExcelExportDTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/MaterialExcelExportDTO.java @@ -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; } diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/PackageMaterialDTO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/PackageMaterialDTO.java index 4d49e798..1d285870 100644 --- a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/PackageMaterialDTO.java +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/dto/PackageMaterialDTO.java @@ -40,7 +40,7 @@ public class PackageMaterialDTO { /** * 版本 */ - private String version; + private Integer version; /** * 创建人 diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BomSearchQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BomSearchQO.java new file mode 100644 index 00000000..01050ba9 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BomSearchQO.java @@ -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; +} diff --git a/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BomUpdateQO.java b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BomUpdateQO.java new file mode 100644 index 00000000..4f055a15 --- /dev/null +++ b/nflg-wms-common/src/main/java/com/nflg/wms/common/pojo/qo/BomUpdateQO.java @@ -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 children; +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsBom.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsBom.java new file mode 100644 index 00000000..d7fcfceb --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/WmsBom.java @@ -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; + +/** + *

+ * 齐套 + *

+ * + * @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; +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsBomMapper.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsBomMapper.java new file mode 100644 index 00000000..3e11c653 --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/mapper/WmsBomMapper.java @@ -0,0 +1,16 @@ +package com.nflg.wms.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.nflg.wms.repository.entity.WmsBom; + +/** + *

+ * 齐套 Mapper 接口 + *

+ * + * @author 代码生成器生成 + * @since 2025 + */ +public interface WmsBomMapper extends BaseMapper { + +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsBomService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsBomService.java new file mode 100644 index 00000000..62b90f03 --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsBomService.java @@ -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; + +/** + *

+ * 齐套 服务类 + *

+ * + * @author 代码生成器生成 + * @since 2025 + */ +public interface IWmsBomService extends IService { + + void add(WmsBom parent, List list); + + void update(Long parentId, List list); + + PageData search(@Valid BomSearchQO request); +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsMaterialService.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsMaterialService.java index 2280c40a..e7c78e19 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsMaterialService.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/IWmsMaterialService.java @@ -29,4 +29,6 @@ public interface IWmsMaterialService extends IService { List getHistory(@Valid @NotBlank String no); List getNotSet(); + + WmsMaterial getCurrent(String no); } diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsBomServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsBomServiceImpl.java new file mode 100644 index 00000000..8f3d3cfb --- /dev/null +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsBomServiceImpl.java @@ -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; + +/** + *

+ * 齐套 服务实现类 + *

+ * + * @author 代码生成器生成 + * @since 2025 + */ +@Service +public class WmsBomServiceImpl extends ServiceImpl implements IWmsBomService { + + @Transactional + @Override + public void add(WmsBom parent, List list) { + parent.setParentId(0L); + save(parent); + list.forEach(it -> { + it.setParentId(parent.getId()); + }); + saveBatch(list); + } + + @Transactional + @Override + public void update(Long parentId, List 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 search(BomSearchQO request) { + List boms = lambdaQuery() + .like(StrUtil.isNotBlank(request.getNo()), WmsBom::getNo, request.getNo()) + .like(StrUtil.isNotBlank(request.getDescribe()), WmsBom::getDescribe, request.getDescribe()) + .list(); + Set parentIds = boms.stream().map(WmsBom::getParentId).filter(parentId -> !Objects.equals(parentId, 0L)).collect(Collectors.toSet()); + if (CollectionUtil.isNotEmpty(parentIds)) { + boms.addAll(listByIds(parentIds)); + } + List 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() + .setPage(request.getPage()) + .setPageSize(request.getPageSize()) + .setTotal(datas.size()) + .setItems(datas); + } +} diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsMaterialServiceImpl.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsMaterialServiceImpl.java index 28c12938..a792a4da 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsMaterialServiceImpl.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/service/impl/WmsMaterialServiceImpl.java @@ -60,4 +60,9 @@ public class WmsMaterialServiceImpl extends ServiceImpl getNotSet() { return baseMapper.getNotSet(); } + + @Override + public WmsMaterial getCurrent(String no) { + return lambdaQuery().eq(WmsMaterial::getNo, no).orderByDesc(WmsMaterial::getId).last("limit 1").one(); + } } diff --git a/nflg-wms-repository/src/main/resources/mapper/WmsBomMapper.xml b/nflg-wms-repository/src/main/resources/mapper/WmsBomMapper.xml new file mode 100644 index 00000000..7d612ad7 --- /dev/null +++ b/nflg-wms-repository/src/main/resources/mapper/WmsBomMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/nflg-wms-repository/src/main/resources/mapper/WmsMaterialMapper.xml b/nflg-wms-repository/src/main/resources/mapper/WmsMaterialMapper.xml index 430b2ae8..113b586e 100644 --- a/nflg-wms-repository/src/main/resources/mapper/WmsMaterialMapper.xml +++ b/nflg-wms-repository/src/main/resources/mapper/WmsMaterialMapper.xml @@ -13,7 +13,7 @@ and describe like concat('%', #{request.describe}, '%') - ORDER BY "no",id DESC; + ORDER BY "no",id DESC