From 1937049b0e173ff9a0ac9f581822c010141722a7 Mon Sep 17 00:00:00 2001 From: zc Date: Fri, 20 Mar 2026 16:25:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../material/mapper/MaterialInfoMapper.java | 6 +- .../model/req/MaterialImportRowReq.java | 16 ++++ .../material/model/req/MaterialInfoReq.java | 1 + .../material/model/resp/MaterialInfoResp.java | 35 ++++++- .../material/service/MaterialInfoService.java | 12 ++- .../service/impl/MaterialInfoServiceImpl.java | 86 ++++++++++++------ .../model/entity/MaterialTypeDO.java | 9 +- .../model/query/MaterialTypeQuery.java | 6 -- .../model/req/MaterialTypeReq.java | 11 ++- .../model/resp/MaterialTypeDetailResp.java | 43 --------- .../model/resp/MaterialTypeResp.java | 12 ++- .../weighManage/service/WorkOrderService.java | 5 +- .../service/impl/WorkOrderServiceImpl.java | 57 ++++++++---- .../resources/mapper/MeterialInfoMapper.xml | 73 ++++++++------- .../meterial/MaterialInfoController.java | 17 +++- .../weighManage/WorkOrderController.java | 11 ++- .../main/resources/config/application-dev.yml | 14 +-- .../resources/config/application-prod.yml | 2 +- .../templates/import/materialInfo.xlsx | Bin 9819 -> 10102 bytes 19 files changed, 256 insertions(+), 160 deletions(-) delete mode 100644 wms-module-system/src/main/java/top/wms/admin/materialType/model/resp/MaterialTypeDetailResp.java diff --git a/wms-module-system/src/main/java/top/wms/admin/material/mapper/MaterialInfoMapper.java b/wms-module-system/src/main/java/top/wms/admin/material/mapper/MaterialInfoMapper.java index a6bda57..f58e75a 100644 --- a/wms-module-system/src/main/java/top/wms/admin/material/mapper/MaterialInfoMapper.java +++ b/wms-module-system/src/main/java/top/wms/admin/material/mapper/MaterialInfoMapper.java @@ -20,10 +20,12 @@ import java.util.List; */ @Repository public interface MaterialInfoMapper extends BaseMapper { - public int updateByName(List list); + int updateByName(@Param("list") List list); - public int updateByCode(List list); + int updateByCode(@Param("list") List list); IPage selectMaterialInfoPage(@Param("page") Page objectPage, @Param(Constants.WRAPPER) QueryWrapper queryWrapper); + + List selectMaterialInfoExport(@Param(Constants.WRAPPER) QueryWrapper queryWrapper); } diff --git a/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialImportRowReq.java b/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialImportRowReq.java index 1b76cc1..087cce1 100644 --- a/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialImportRowReq.java +++ b/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialImportRowReq.java @@ -1,7 +1,9 @@ package top.wms.admin.material.model.req; +import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import org.hibernate.validator.constraints.Length; @@ -35,6 +37,7 @@ public class MaterialImportRowReq implements Serializable { * 物料单位重量(g) */ @Schema(description = "物料单位重量(g)") + @NotNull(message = "物料单位重量不能为空") private BigDecimal unitWeight; /* @@ -42,4 +45,17 @@ public class MaterialImportRowReq implements Serializable { * */ @Schema(description = "物料规格") private String materialSpec; + + /** + * 物料类型名称 + */ + @Schema(description = "物料类型名称") + private String typeName; + + /** + * 流程名称 + */ + @Schema(description = "流程名称") + private String processName; + } diff --git a/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialInfoReq.java b/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialInfoReq.java index 444b51a..b18ba8c 100644 --- a/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialInfoReq.java +++ b/wms-module-system/src/main/java/top/wms/admin/material/model/req/MaterialInfoReq.java @@ -44,6 +44,7 @@ public class MaterialInfoReq implements Serializable { * 物料单位重量(g) */ @Schema(description = "物料单位重量(g)") + @NotNull(message = "物料单位重量不能为空") private Double unitWeight; /* diff --git a/wms-module-system/src/main/java/top/wms/admin/material/model/resp/MaterialInfoResp.java b/wms-module-system/src/main/java/top/wms/admin/material/model/resp/MaterialInfoResp.java index e48bbd2..f48ce74 100644 --- a/wms-module-system/src/main/java/top/wms/admin/material/model/resp/MaterialInfoResp.java +++ b/wms-module-system/src/main/java/top/wms/admin/material/model/resp/MaterialInfoResp.java @@ -9,6 +9,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import top.wms.admin.common.model.resp.BaseDetailResp; import java.io.Serial; +import java.math.BigDecimal; /** * 物料信息信息 @@ -62,13 +63,43 @@ public class MaterialInfoResp extends BaseDetailResp { * 物料类型名称 */ @Schema(description = "物料类型名称") - @ExcelIgnore + @ExcelProperty(value = "物料类型") private String typeName; /** * 流程名称 */ @Schema(description = "流程名称") - @ExcelIgnore + @ExcelProperty(value = "物料流程") private String processName; + + /** + * 物料类型ID + */ + @Schema(description = "物料类型ID") + @ExcelIgnore + private Long materialTypeId; + + /** + * 流程ID + */ + @Schema(description = "流程ID") + @ExcelIgnore + private Long materialProcessId; + + + /** + * 品类下行浮动范围(%) + */ + @Schema(description = "品类下行浮动范围(%)") + @ExcelIgnore + private BigDecimal downFloatRatio; + + /** + * 品类上行浮动范围(%) + */ + @Schema(description = "品类上行浮动范围(%)") + @ExcelIgnore + private BigDecimal upFloatRatio; + } diff --git a/wms-module-system/src/main/java/top/wms/admin/material/service/MaterialInfoService.java b/wms-module-system/src/main/java/top/wms/admin/material/service/MaterialInfoService.java index bf3cb55..4724791 100644 --- a/wms-module-system/src/main/java/top/wms/admin/material/service/MaterialInfoService.java +++ b/wms-module-system/src/main/java/top/wms/admin/material/service/MaterialInfoService.java @@ -21,11 +21,13 @@ import java.io.IOException; */ public interface MaterialInfoService extends BaseService { - /* - * - * 根据编码查询物料信息 - * */ - public MaterialInfoDO getMaterialInfoByCode(String code); + /** + * 根据编码查询物料信息 + * + * @param code 物料编码 + * @return 物料信息 + */ + MaterialInfoResp getMaterialInfoByCode(String code); /** * 下载导入模板 diff --git a/wms-module-system/src/main/java/top/wms/admin/material/service/impl/MaterialInfoServiceImpl.java b/wms-module-system/src/main/java/top/wms/admin/material/service/impl/MaterialInfoServiceImpl.java index 35c5c37..f111237 100644 --- a/wms-module-system/src/main/java/top/wms/admin/material/service/impl/MaterialInfoServiceImpl.java +++ b/wms-module-system/src/main/java/top/wms/admin/material/service/impl/MaterialInfoServiceImpl.java @@ -10,6 +10,7 @@ import cn.hutool.extra.validation.ValidationUtil; import cn.hutool.http.ContentType; import cn.hutool.json.JSONUtil; import com.alibaba.excel.EasyExcel; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -31,8 +32,10 @@ import top.continew.starter.cache.redisson.util.RedisUtils; import top.continew.starter.core.exception.BusinessException; import top.continew.starter.core.validation.CheckUtils; import top.continew.starter.extension.crud.model.query.PageQuery; +import top.continew.starter.extension.crud.model.query.SortQuery; import top.continew.starter.extension.crud.model.resp.PageResp; import top.continew.starter.extension.crud.service.BaseServiceImpl; +import top.continew.starter.file.excel.util.ExcelUtils; import top.continew.starter.web.util.FileUploadUtils; import top.wms.admin.common.constant.CacheConstants; import top.wms.admin.common.context.UserContextHolder; @@ -47,6 +50,10 @@ import top.wms.admin.material.model.resp.MaterialImportParseResp; import top.wms.admin.material.model.resp.MaterialInfoImportResp; import top.wms.admin.material.model.resp.MaterialInfoResp; import top.wms.admin.material.service.MaterialInfoService; +import top.wms.admin.materialProcess.mapper.MaterialProcessMapper; +import top.wms.admin.materialProcess.model.entity.MaterialProcessDO; +import top.wms.admin.materialType.mapper.MaterialTypeMapper; +import top.wms.admin.materialType.model.entity.MaterialTypeDO; import top.wms.admin.system.service.FileService; import javax.imageio.ImageIO; @@ -55,6 +62,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.Duration; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -79,6 +87,10 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl page(MaterialInfoQuery query, PageQuery pageQuery) { QueryWrapper queryWrapper = new QueryWrapper<>(); @@ -93,12 +105,28 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>(); + queryWrapper.like(StrUtil.isNotBlank(query.getMaterialName()), "mi.material_name", query.getMaterialName()); + queryWrapper.likeLeft(StrUtil.isNotBlank(query.getEncoding()), "mi.encoding", query.getEncoding()); + this.sort(queryWrapper, sortQuery); + + List list = baseMapper.selectMaterialInfoExport(queryWrapper); + ExcelUtils.export(list, "物料信息导出", MaterialInfoResp.class, response); + } + + @Override + public MaterialInfoResp getMaterialInfoByCode(String code) { + MaterialInfoResp materialInfoResp = new MaterialInfoResp(); + MaterialInfoDO materialInfoDO = baseMapper.lambdaQuery().eq(MaterialInfoDO::getEncoding, code).one(); + CheckUtils.throwIf(materialInfoDO == null, "物料信息不存在"); + MaterialTypeDO materialTypeDO = materialTypeMapper.selectById(materialInfoDO.getMaterialTypeId()); + CheckUtils.throwIf(materialTypeDO == null, "该物料对应类型不存在"); + BeanUtil.copyProperties(materialInfoDO, materialInfoResp); + materialInfoResp.setUpFloatRatio(materialTypeDO.getUpFloatRatio()); + materialInfoResp.setDownFloatRatio(materialTypeDO.getDownFloatRatio()); + return materialInfoResp; } @Override @@ -107,7 +135,7 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl encoding != null && !seenCode.add(encoding)); CheckUtils.throwIf(hasDuplicateEncoding, "存在重复物料编码,请检测数据"); - // 查询重复用户 + // 查询重复物料名 materialImportResp .setDuplicateNameRows(countExistByField(validRowList, MaterialImportRowReq::getMaterialName, MaterialInfoDO::getMaterialName, false)); - // 查询重复邮箱 + // 查询重复物料编码 materialImportResp .setDuplicateCodeRows(countExistByField(validRowList, MaterialImportRowReq::getEncoding, MaterialInfoDO::getEncoding, false)); // 设置导入会话并缓存数据,有效期10分钟 @@ -175,33 +203,46 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl existName = listExistByField(importMaterialList, MaterialImportRowReq::getMaterialName, MaterialInfoDO::getMaterialName); List existCode = listExistByField(importMaterialList, MaterialImportRowReq::getEncoding, MaterialInfoDO::getEncoding); CheckUtils.throwIf(isExitImportMaterial(req, importMaterialList, existName, existCode), "数据不符合导入策略,已退出导入"); + + //查询物料类型 + List collect = importMaterialList.stream().map(MaterialImportRowReq::getTypeName).distinct().toList(); + Map materialTypeMap = new HashMap<>(); + if(CollUtil.isNotEmpty(collect)){ + List materialTypeList = materialTypeMapper.selectList(new LambdaQueryWrapper().in(MaterialTypeDO::getTypeName, collect)); + materialTypeMap = materialTypeList.stream().collect(Collectors.toMap(MaterialTypeDO::getTypeName, MaterialTypeDO::getId, (k1, v1) -> v1)); + } + //查询物料流程 + List collect1 = importMaterialList.stream().map(MaterialImportRowReq::getProcessName).distinct().toList(); + List materialProcessList = materialProcessMapper.selectList(new LambdaQueryWrapper().in(MaterialProcessDO::getProcessName, collect1)); + Map materialProcessMap = new HashMap<>(); + if(CollUtil.isNotEmpty(materialProcessList)) { + materialProcessMap = materialProcessList.stream().collect(Collectors.toMap(MaterialProcessDO::getProcessName, MaterialProcessDO::getId, (k1, v1) -> v1)); + } + // 批量操作数据库集合 List insertList = new ArrayList<>(); List updateByNameList = new ArrayList<>(); List updateByCodeList = new ArrayList<>(); // ID生成器 - // IdGenerator idGenerator = DefaultIdGeneratorProvider.INSTANCE.getShare(); for (MaterialImportRowReq row : importMaterialList) { if (isSkipMaterialImport(req, row, existName, existCode)) { - // 按规则跳过该行 continue; } MaterialInfoDO materialDO = BeanUtil.toBeanIgnoreError(row, MaterialInfoDO.class); materialDO.setUnitWeight(NumberUtil.isValidNumber(row.getUnitWeight()) ? row.getUnitWeight() : null); materialDO.setMaterialSpec(StrUtil.isNotBlank(row.getMaterialSpec()) ? row.getMaterialSpec() : null); + materialDO.setMaterialProcessId(materialProcessMap.get(row.getProcessName())); + materialDO.setMaterialTypeId(materialTypeMap.get(row.getTypeName())); // 修改 or 新增 if (UPDATE.validate(req.getDuplicateName(), row.getMaterialName(), existName)) { materialDO.setMaterialName(row.getMaterialName()); - materialDO.setUpdateTime(LocalDateTime.now()); materialDO.setUpdateUser(UserContextHolder.getUserId()); updateByNameList.add(materialDO); } else if (UPDATE.validate(req.getDuplicateCode(), row.getEncoding(), existCode)) { materialDO.setEncoding(row.getEncoding()); - materialDO.setUpdateTime(LocalDateTime.now()); materialDO.setUpdateUser(UserContextHolder.getUserId()); updateByCodeList.add(materialDO); } else { - // materialDO.setId(idGenerator.generate()); insertList.add(materialDO); } } @@ -245,16 +286,9 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl filterImportData(List importRowList) { // 校验过滤 - List list = importRowList.stream() + return importRowList.stream() .filter(row -> ValidationUtil.validate(row).isEmpty()) .toList(); - // 物料名去重 - return list.stream() - .collect(Collectors.toMap(MaterialImportRowReq::getMaterialName, row -> row, (existing, - replacement) -> existing)) - .values() - .stream() - .toList(); } /** @@ -339,7 +373,7 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl codeUrlMap = new HashMap<>(); // 物料照片存储路径(自定义,比如按日期分目录) - String photoStoragePath = "/" + DateUtil.today() + "/"; + String photoStoragePath = "material/"; try (ZipInputStream zipInputStream = new ZipInputStream(zipFile.getInputStream())) { ZipEntry zipEntry; @@ -351,7 +385,7 @@ public class MaterialInfoServiceImpl extends BaseServiceImpl validateWeighing(WorkOrderReq req); } \ No newline at end of file diff --git a/wms-module-system/src/main/java/top/wms/admin/weighManage/service/impl/WorkOrderServiceImpl.java b/wms-module-system/src/main/java/top/wms/admin/weighManage/service/impl/WorkOrderServiceImpl.java index 77ba71b..a47f3fc 100644 --- a/wms-module-system/src/main/java/top/wms/admin/weighManage/service/impl/WorkOrderServiceImpl.java +++ b/wms-module-system/src/main/java/top/wms/admin/weighManage/service/impl/WorkOrderServiceImpl.java @@ -11,12 +11,15 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import top.continew.starter.core.validation.CheckUtils; import top.continew.starter.extension.crud.model.query.PageQuery; import top.continew.starter.extension.crud.model.resp.PageResp; import top.continew.starter.extension.crud.service.BaseServiceImpl; import top.wms.admin.common.context.UserContextHolder; import top.wms.admin.material.mapper.MaterialInfoMapper; import top.wms.admin.material.model.entity.MaterialInfoDO; +import top.wms.admin.materialType.mapper.MaterialTypeMapper; +import top.wms.admin.materialType.model.entity.MaterialTypeDO; import top.wms.admin.system.service.ConfigService; import top.wms.admin.weighManage.mapper.WorkOrderInfoMapper; import top.wms.admin.weighManage.mapper.WorkOrderMapper; @@ -31,7 +34,9 @@ import top.wms.admin.weighManage.service.WorkOrderService; import java.math.BigDecimal; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 任务工单信息业务实现 @@ -48,6 +53,8 @@ public class WorkOrderServiceImpl extends BaseServiceImpl validateWeighing(WorkOrderReq req) { + Map map = new HashMap<>(); + map.put("code", "200"); log.info("validateWeighing req:{}", req); - String configValue = configService.getConfigValue("weight_float_ratio"); - BigDecimal weightFloat = new BigDecimal("0.06"); - if (StrUtil.isNotBlank(configValue)) { - weightFloat = new BigDecimal(configValue); - } + MaterialInfoDO materialInfoDO = materialInfoMapper.selectById(req.getMaterialId()); + CheckUtils.throwIf((materialInfoDO == null || null == materialInfoDO.getMaterialTypeId()), "该物料信息不全,请先维护!"); + MaterialTypeDO materialTypeDO = materialTypeMapper.selectById(materialInfoDO.getMaterialTypeId()); + CheckUtils.throwIf((materialTypeDO == null || null == materialTypeDO.getDownFloatRatio() || null == materialTypeDO.getUpFloatRatio()), "该物料品类信息不全,请先维护!"); + + //下行浮动范围 + BigDecimal downFloatRatio = materialTypeDO.getDownFloatRatio(); + //上行浮动范围 + BigDecimal upFloatRatio = materialTypeDO.getUpFloatRatio(); //计算标准重量 BigDecimal standardWeight = new BigDecimal(req.getCalculatedWeight()); + //电子秤重量 BigDecimal electronicWeight = new BigDecimal(req.getAhDeviceWeight()); - // 检查 electronicWeight 是否大于 standardWeight - if (electronicWeight.compareTo(standardWeight) <= 0) { - log.error("电子秤重量必须大于标准重量"); - return 500; // 电子秤重量必须大于标准重量 - } - - // 计算比值:(electronicWeight - standardWeight) / standardWeight + // 计算比值:(实重 - 标重) / 标重 BigDecimal weightDifference = electronicWeight.subtract(standardWeight); - BigDecimal ratio = weightDifference.divide(standardWeight, 4, BigDecimal.ROUND_HALF_UP); + BigDecimal ratio = weightDifference.divide(standardWeight, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)); + log.info("ratio当前比值:{}%", ratio); - // 检查比值是否超过 6% - if (ratio.compareTo(weightFloat) > 0) { - log.error("比值超过 6%,当前比值: {}", ratio); - return 500; // 比值超过 6% + // 检查比值是否超过上行浮动范围 + if (ratio.compareTo(upFloatRatio) > 0) { + log.info("比值超过 {}%", upFloatRatio); + map.put("code", "502"); + map.put("msg", "数量不足"); + return map; } - return 200; // 验证通过 + // 检查比值是否超过下行浮动范围 + if (ratio.compareTo(downFloatRatio) < 0) { + log.info("比值超过下限 {}%", downFloatRatio); + map.put("code", "501"); + map.put("msg", "数量过多"); + return map; + } + + return map; } } \ No newline at end of file diff --git a/wms-module-system/src/main/resources/mapper/MeterialInfoMapper.xml b/wms-module-system/src/main/resources/mapper/MeterialInfoMapper.xml index d7c2b5e..f77ce8e 100644 --- a/wms-module-system/src/main/resources/mapper/MeterialInfoMapper.xml +++ b/wms-module-system/src/main/resources/mapper/MeterialInfoMapper.xml @@ -6,22 +6,21 @@ UPDATE sys_material_info - SET - - encoding = #{item.encoding}, - - - unit_weight = #{item.unitWeight}, - - - material_spec = #{item.materialSpec}, - - - update_time = NOW(), - - - update_user = #{item.updateUser} - + + + encoding = #{item.encoding}, + + + unit_weight = #{item.unitWeight}, + + + material_spec = #{item.materialSpec}, + + + update_user = #{item.updateUser}, + + update_time = NOW() + WHERE material_name = #{item.materialName} @@ -29,22 +28,21 @@ UPDATE sys_material_info - SET - - material_name = #{item.materialName}, - - - unit_weight = #{item.unitWeight}, - - - material_spec = #{item.materialSpec}, - - - update_time = NOW(), - - - update_user = #{item.updateUser} - + + + material_name = #{item.materialName}, + + + unit_weight = #{item.unitWeight}, + + + material_spec = #{item.materialSpec}, + + + update_user = #{item.updateUser}, + + update_time = NOW() + WHERE encoding = #{item.encoding} @@ -60,5 +58,16 @@ left join sys_material_process mp on mi.material_process_id = mp.id ${ew.customSqlSegment} + diff --git a/wms-webapi/src/main/java/top/wms/admin/controller/meterial/MaterialInfoController.java b/wms-webapi/src/main/java/top/wms/admin/controller/meterial/MaterialInfoController.java index 4b22a31..a4619da 100644 --- a/wms-webapi/src/main/java/top/wms/admin/controller/meterial/MaterialInfoController.java +++ b/wms-webapi/src/main/java/top/wms/admin/controller/meterial/MaterialInfoController.java @@ -1,6 +1,8 @@ package top.wms.admin.controller.meterial; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import io.swagger.v3.oas.annotations.Operation; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.NotNull; @@ -29,6 +31,8 @@ import top.wms.admin.material.model.resp.MaterialInfoResp; import top.wms.admin.material.service.MaterialInfoService; import java.io.IOException; +import java.util.Arrays; +import java.util.List; /** * 物料信息管理 API @@ -44,10 +48,15 @@ import java.io.IOException; public class MaterialInfoController extends BaseController { @GetMapping("/code/{code}") - public MaterialInfoDO getMaterialInfoByCode(@PathVariable String code) { - MaterialInfoDO materialInfoDO = baseService.getMaterialInfoByCode(code); - CheckUtils.throwIfEmpty(materialInfoDO, "未查询到相关物料信息"); - return materialInfoDO; + public MaterialInfoResp getMaterialInfoByCode(@PathVariable String code) { + List list = Arrays.asList(code.split(",")); + if (CollUtil.isNotEmpty(list) && list.size() > 1) { + code = list.get(1); + } + + MaterialInfoResp materialInfoResp = baseService.getMaterialInfoByCode(code); + CheckUtils.throwIfEmpty(materialInfoResp, "未查询到相关物料信息"); + return materialInfoResp; } @Operation(summary = "下载导入模板", description = "下载导入模板") diff --git a/wms-webapi/src/main/java/top/wms/admin/controller/weighManage/WorkOrderController.java b/wms-webapi/src/main/java/top/wms/admin/controller/weighManage/WorkOrderController.java index 7b5e083..e7e3845 100644 --- a/wms-webapi/src/main/java/top/wms/admin/controller/weighManage/WorkOrderController.java +++ b/wms-webapi/src/main/java/top/wms/admin/controller/weighManage/WorkOrderController.java @@ -21,6 +21,7 @@ import top.wms.admin.weighManage.model.resp.WorkOrderResp; import top.wms.admin.weighManage.service.WorkOrderService; import java.util.List; +import java.util.Map; /** * 任务工单信息管理 API @@ -71,12 +72,12 @@ public class WorkOrderController extends BaseController validateResult = baseService.validateWeighing(req); + return R.ok(validateResult); } } \ No newline at end of file diff --git a/wms-webapi/src/main/resources/config/application-dev.yml b/wms-webapi/src/main/resources/config/application-dev.yml index c72f42c..8cad03b 100644 --- a/wms-webapi/src/main/resources/config/application-dev.yml +++ b/wms-webapi/src/main/resources/config/application-dev.yml @@ -18,7 +18,7 @@ spring: spring.datasource: type: com.zaxxer.hikari.HikariDataSource # 请务必提前创建好名为 wms_admin 的数据库,如果使用其他数据库名请注意同步修改 DB_NAME 配置 - url: jdbc:p6spy:mysql://127.0.0.1:3306/wms?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:p6spy:mysql://127.0.0.1:3306/wms?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&allowMultiQueries=true username: root password: root # PostgreSQL 配置 @@ -54,12 +54,12 @@ spring.data: ## Redis 配置(单机模式) redis: # 地址 -# host: ${REDIS_HOST:192.168.2.30} - host: ${REDIS_HOST:127.0.0.1} + host: ${REDIS_HOST:192.168.2.30} +# host: ${REDIS_HOST:127.0.0.1} # 端口(默认 6379) port: ${REDIS_PORT:6379} # 密码(未设置密码时请注释掉) -# password: ${REDIS_PWD:redis2025} + password: ${REDIS_PWD:redis2025} # 数据库索引 database: ${REDIS_DB:0} # 连接超时时间 @@ -138,11 +138,13 @@ captcha: continew-starter.log: # 是否打印日志,开启后可打印访问日志(类似于 Nginx access log) is-print: true + # 忽略的路径,多个路径用逗号分隔 + exclude-patterns: ["/file/**", "/sdk/**"] ## 项目日志配置(配置重叠部分,优先级高于 logback-spring.xml 中的配置) logging: level: - top.continew.admin: DEBUG - top.continew.starter: DEBUG + top.continew.admin: WARN + top.continew.starter: WARN file: path: ./logs diff --git a/wms-webapi/src/main/resources/config/application-prod.yml b/wms-webapi/src/main/resources/config/application-prod.yml index 0006678..2e6ca15 100644 --- a/wms-webapi/src/main/resources/config/application-prod.yml +++ b/wms-webapi/src/main/resources/config/application-prod.yml @@ -14,7 +14,7 @@ server: spring.datasource: type: com.zaxxer.hikari.HikariDataSource # 请务必提前创建好名为 wms_admin 的数据库,如果使用其他数据库名请注意同步修改 DB_NAME 配置 - url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wms_admin}?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wms_admin}?serverTimezone=Asia/Shanghai&useSSL=true&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&autoReconnect=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&allowMultiQueries=true username: ${DB_USER:root} password: ${DB_PWD:123456} driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/wms-webapi/src/main/resources/templates/import/materialInfo.xlsx b/wms-webapi/src/main/resources/templates/import/materialInfo.xlsx index d9215c4dc3ab81dee437a6314ff87f7f6ac52d0b..bbdbffa3f6866682f67ca80a3c9736bef52a3b57 100644 GIT binary patch literal 10102 zcmeHN^;cY3vu)hnA-KB)hX8?wpb730G`MsVoIvm(!QEX0!6mpm1PRh;kS0KIm+*Sz zy~$+e{RQ85ez^DcI(OIVd)BVnb*hf45&|M202zP^003wK#h81Z)^Gp-77_qJ06>K| zka2Q!wRChf(e!k-1RHUAIM~zVA;Pod0N`Qo|9AWcuRuk@h+{VouIy#v4Nh#Mmf22T z85?|rL=va^H6#8|IT{?KBY84_N-y8wkYg0_FW zv5ipG!oYrE>no%Q{fZe-p1SpHaM|gJX&ce+8XY4G? z{USKhT)mI3zQ1%HD0D}Buei%U?{S70rAyA1HTUiKivnU`g~t-HTSeMC+{mPWIE{AD zE>7VRUfE2l-N#utr#P&BZ?xs{2Y;hg19Fua^zhQKGdBC0uDKAu>!z!-H)@o`-(0?> z%PFZEb2+3*1=9wo&cnwDXc@D!*FkP2Iw$%DPx)Fu#va_)9N|$XvFmq) z%FiE1v2EqfpG$;Se9a5uVtnu?ef>njF2aB)q343D5O$lGvehmR7lSrQv@83(YuOSklsBN$kWa(Wa#?%X82p!@GYG= z0u{6VefG|w-Dh=mImX~Lgv{;hePN`!)&f~Df!|W9oDYSpjw(X87HuhuFe8IGt1|}O`HUD!O%Mj=dUQsGS`Cr zX z6a#w+@(mlbelaKU8?7^AVr`L|hT0dvaW6(?GBKfuCHec}#F(>Ezyb!oFb3Kx_8n?S z|LQ(sZrcaNEXCYjAT?ZFBVAi@_RHv)OhS$eursMTBz`|No!n7xXq;K^b%SoE5Klly zq+F-|7j{~P!+7hir1a?L@0nX)y0hU#_+puZT6z3>L^Hu5*=W=28Wwfav4#uiH zvG#yd>sUQU*vz#5?!#&dsDDtiW@0Z}P}L-_Xej!jWuUij%GKFBPISBMJhZm&A1sAk z$B*?bzNJ9aom>xSO)9a(rh0XRF}`s^Yh_y`dw(?U<+=)eFqKFn|4y}IMfnJ5uBnnBlc{MEUzyiA9@ynd9V-2-jp|IN4@~RRK62r3aN8Sk+lxR z8x*X=znZrSjlFyy*GBs`?R(~M%gy3a8o&W+AJ^5FyCC!au~|fuCugCo7c1rTLa=YZ zeY;*4@r|+#B=D2)Bn4s{oa4D~V`faRL%f6=O5k${*4F|eR|WA$NDUI(Avh$+E+<2Q zkkfrgcxpEh_Va5_=le34*8}OU8 z#oEtf8@^_Cr#kgigoxNnMI0;J)aRSOdBZ;?=B-3R@+oYl1tu}%08}`bzx<&xKYPvp zDh?bh6@S;L1(6ueFDRI#kCBVWNHf=4_RMt;I<9 zixM}2Q;6r`*nr!m0QOe|g7Yr+l5l)PF9Q2RF(jw4(=h~8v+p0M0-hle;P3D5m4C;; zP6HD(OT-OwWDyE)U$HQfh2|I00neJJLilaRd0z9`f+s15RrFRy>Nfpvf;9F&1k^P) z(xkCkZ9O#0KrWE813alepOT>|h+}yIKJU!XvR`${UZ9?|-dU-5j@xzR-(YS%Dp#T^ z6L{hi;z|=b_>9_*H4eO$m-6lkc4)OZG%)+`SqXW5h-f#AF4M>W z04a+8-H=8lF{aQ%N=O+r*e^# zI$ApBL_!XkXyyF9*#Vr9d`+Adi&2jp8rKj-^E9OXw4@5A#bhjkj~en?1PE2Op|A5v zhbT)coe2@qD$z(vv~)`vtq1eg5*!$o=af^lfz{!pM<&UwpWF0RR_SyI&ObU;mQ+y0 z%%6m(KVuGWP2)Onmu9Q^Ky#o$O0b(r=tF;{;`P|k*P?V=Q-Kp>BaqM0mnt;-D zOVoy6yfUeIANCUQ5eHG*M4_{&wd||vA+f%=r=vwmoEPE~ldCzmhFy;qX@zm_R|xbu z!PrC%YM$XlWG!eUjd?P0^dlb*CQFc><~RxjqB)4|653TZ*dinDxGT*xv+eWuDceqbW< zP!XZBS37PP{ffs+pwR)jI3hz|(!f#pv&AI43$izi6EE-Nkg zoyh{6!%Wgu7q&@e_6AQGLhn$ThVO{n!+Hj!4X$3cYV)&SbJ7^BCtN-^n*htW?PI8k zanBtB-+Aw9ZRudi{rmNI%J1vFh^7!A?4UoUlmizlxSba32^f6eenHX# z(O#}AdG@M5)n$V$+Wu8zbM8f0P!LNP2EGtBYRQbE;c&4YO90(D`_X>t=sZQJ!-zIp z$q?hlbsH3VndLVz(d>F{EZs&wiezdt;bd5HOZ6OqIF5h!y0JeWhwCOQh6M}HlJ(#k zgX3-la@gUH<}gIcJdbd#X`h=#t(598YfI;E%E0vzv-rqy*du^J{G@~!W-Ej#%{VzaEpgt9X7?cLiBK|WH}U?< zf_F6t`^ujf=M!wTtR+O=&OyK?|G9haW* zk5BBAZ}`^GP|sLx+!jibnI7bN~?nBat!^zNRs5| zT@l2_fgqoe_4skQ4x4oWmVri{qs*J}oQ3Kmazc%`aqY=-ZSUF+LkF}}z7}YZyTO>+ zt9(`CTpEhueRU0GJ+`?m{eS~L33z{abq0mqA=!{(7XQ2N^omRw9=8nPg=xqRrWUOe zq43pw1y*OkP6a0KAJ51FDAjCykIzC$UQl~;XGw@QKWuLPm|(`C%2;|}owGzc$mQol z%J#dwHd*!gdVhTdf#P(yZUn!3_&)H$?|utI2=_wG@^ft!)%}l6*iG_w<2Drg3i}xW zfdms8@rr=Y{;~yHg^E~z!=o2h3*iB{IeB$C+#j)NX2_Y9DJWQQ4R&o7I7c#togt9AG zOh!itR)@Ifm@ZP^7M)j_=Fu+~fX)~x)BL51xaU^ml+~>PscqCGuHhf8$Y|UmstDq; z6jlzcz4gZ2gk2o7+B7WMurH|#cHq*Ag?RSEXYtS9=dSYBJ#@UWR_VU|q z?}v%ip~a2M1XV8<62e0aUw9H#|86|Y-7iv?p_XDveMhyz`vy&6^qd&!;)Ul2i$p9xmxb z8wvz#O*jdhI#Mk%0bNSICJ0@O?3Ar#*cHr)#HW#|hAKtTA(Y9xCw{O?F4j&iUQ_}u z@^#A#K~U+j%n85JiH+?=pGLlJL@%|>0`-A}G_72@+TZE2SI5{<} zIkHRXO=L@7VoSzjf}WMcbLQb0zCntEQv7(G!nh%g9TNr)wVN7RprOSFN5>UF%eRsj zq%_887aRJKak~xd3`wlF93Eo_IHHifC>D;fnvcTsrOb!xJQC3nUbQ`*Lt$4C40WdN zU#}L*1-~J98eT7owbdDe+Vs_Ca|IJ^Nihkiy|r4}tvOlg$yowsp?=06p{Ay$%r~)~ z22=u{X|!7#ZFRm)!q|uA;XbF+din5r_Q@wr_6f2Ay;WH)PcouNwci0jt%taGqOCE zhjBo~wc12sTg~cD2=@cQ*Ek62OGqcAokj;4im|IJD}e@&gwM7byBHm;KY#ClCAj~L z{dVyrQw4TTdz3e5s4+61 zmxXacs*3UURQJHj&D_;B2J0GBiH%{a^lKC>b-|9I%GYjM=;TPufLLXB@hse%N z_VLS}m}TK5VY}Y;PYGo7+drL}m3la!<%2gGK~y9Ot0BZWdoq4T(o@y3`^xOa@jbbD zE?fjZ#f}}VpnFkjpIt`Ieu#rJdItyDix~fB?R>RZ1JSiON_^i z%J{v0i;j^gj1&xm8LD&_;mMVZ$IByH!@_AA{w=jegmz*O==+9^BW@0)Qj_-25ej{@ z&O#PMedz&pp0%~>-p!oeAY${DScRHuu|>X^Z|&nsZkdvuhxjO&4t8z_O$~Q>Pj#7^ z&WFy>@w}k-m<&I}xy52gB&>OPKptKh=+*am#jSNj$RaW>7+9V52stsoPQ@I-wnQ{J8_ z)Jch1_QF$+rG*d%#a<4si%h6RGiUmu)$BwQkl#>dOfWm zoKMqLJe$u#)*$7GcAvH$<7SAZV7=nN-rmvo<-^Nd@Tx8MBkWnvCp#;6G|QL7=vnKh$h) zkcF?tG`F^2oD&|NYleob6=zfGk*-jqDXCY3uiZJkkiX<>PL_zC;7#TTxlE`fo^Yyh z^ui?|YEQ5I5as#K#fdu7f>w?747Nt*6CMAS)uD7FPZH~@mItD!&ADvp9#6cns_thk zVoKLl21lULsg=y8+?K{qnXYM->{46#*UN={c#;MkcKUY_0KMQdJpy;bB*{RUL)UgT zgzRxol3PoZ>=6)@q+;jJKfAL1j`|BV2t!z}R8l?5kLs`{O#mL;)xfh-PCg!}S@pHb zR{N8z-Wcmdq6EFcb{?l>C#Z(m&kJdnBeW*;pfc1b^8)VUd+l4@++;+%+Q~1z%P2@5 zW7|9UtehB)cC;vMWiC#ULUl;Sd7MNzv(X4`KYm~h@C5AN3x`{3U}M=oy~pyjkgg`* zIls(UEG_AWeFw>cB>>16(kgkzRb+jNqL1hf#~n;=PMfjpQrgUaaC#d}mk-T| zcy;AGmZZ_?DFSaQbw7sFD0hI@*ujsnRUZGIv*Qs+4z3Re051dLu__Bo(oc|@vJOUi zI#xWoTcN&BHEz?k>rJ;+A#=x0GLk8XA=I)OJ(*`d=KQJia>5h~pJ%Y)o%n2P538GJ zHm}X>N_p=d3wT1dC9x1B)hx;(r4E;n>sYaRQIin!B(CQUdv4O-Xd%rr)UADGtp&40 zV3%T{hL%m_56(ayqgH9Ka_u5BgkR6$hUznCt15fX);#r?TsXyrDf$IlU@V)Dt-*7e zcccA{>#oEiaxbG0dcK=Zptcdq`5z^X9PqNW|O%|?jnVJ{M-r{7&+5{UiquX?gY)Tc)Wn<<6uqY3}i z6KhkDrG_~wMLCBhbKazSF3R2$l$1_YS$uPx z_t=+T8s6HV^PsB-cL&B!PF^M_8-94Vpf^Ls0KDdciYfz%cd~|&^esxlIcU;}dFMQ7 z1LT>dRg+Gz1{S{R(ctNpC^F!<`6seOEAd{9`|2pIGOlJk8SNLE9_e3FF?`-WBDv=< z+8R0La4#h2P`PTHeyKr0!hXDaSX5TluIOpj7K@34E~qJg8;g?OX`NuuQ-X|6f&%}; zyo2&k?jw)8R{8*xOL|fKgU0>zmkfss&Gg&TgR*ULBTbiE+aIvn?!RdCdyH5*9oU+h z!PXQHR?4z)GFJsTIfJ>)oj{g@!^jG9Xe%fMZ(t|4Fms{@bV0qEy@F{ONhj2wJ7EII= zshV&SP-gC@tx-wYtZGe=zBWEz9YSEy^|9KpW;Yuah7s#z17JfWjvq~fY*DuyKN1V# zpTp#g{jFE45UKv4Y))700yyVSFU_RuUznjEPLWfEOt%}GfhB)lF+$u)7J`o`Z|6)J zbTwf26yp>cs7)p!YwA8cHZwq3E3((y)h5vQvSLrPWJ54yg!*gf^|^ysnaQA)4yI}r zD2WGaMq5-8Jnh(Nuw+>1q3Nitt8NZ;gp|WyU2{F$d7QVetZ3XBfI0>Jo*^AH0~M0} zs+I;wl1Ipf>G4&3@NYLQ6uuUSY*v5sIcis!CjzcMQ1^!M_l7YXTL703P6RL4s|No) zV=VuCpdJNd<2{UxxIeSe)Y$oY6>Gj~xXXxVMm$XkrEB-v%5^o)!2TLl!GN_@1Q+BoG=~c1F!dSX zvZwht3jCLZ5J4qJ%^+lE^LlhS5rzt@4|a=-+IWFJex6?5zE>VT#2IIfUy|-;-#EB! zeKg83^R4FH5ti3w&LFSD<&LOEzd||sh_l4!+C({CfY^C3Dq-SnF8VF>ve~8axGe3) zJot!c`9@V)k%*?aPUmwa^4Capj0Rp2w#4+OKk82ntf_8VZpT1PLh|nFUOg+yM~8mw zlK(1FrQX^8aZyLw*XVufeWP4*zBG|8f`rsEadr5y(U6zp8SFQ*bzm;o1$) zu~E}|mGik-XF8!KR!Ye_m8<{35!(B$yuWceBfe_2xi=!Y^7Vz;WKKF}my;>&3Z@u%K&}#ZB9eZE2n^&#GnYK`r4g^N>t^LJCGSx4 zdi#27mCjKagMLJ)@GNXrY?+TlJ}J1ZCSp!xlK(u=D0n3S@Q}zpgYByS*mJ|dbHehW ze?Oq~*J}Uq^e@MiRF(d2;O_@0em0N`EAjqxoZ?sDuWjVNpfj*4z%NbZU%`Lxsr>~7 z01(lC2me1EwqNc1+GzR9k`U(q{fU3HU4FIlYuWlQE8MV_Ana3qEn@#_;Mdy6Uk2ET zemC$}CFED=uW9aIP;ZJqpuZ-)zgqZvQuh}g0GN0L0Q@7x`xX9o75*7+MEw)|Pfh+6 l{r3R)Gn$6(C$#zhg+o;(Bp5w@JFJ5N=z>MfY=+-{{SU+}7E1sC literal 9819 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 F{{a4sDN+Cc