diff --git a/src/main/java/com/zg/project/information/domain/PcdeDetail.java b/src/main/java/com/zg/project/information/domain/PcdeDetail.java index cc6a463..c802b2d 100644 --- a/src/main/java/com/zg/project/information/domain/PcdeDetail.java +++ b/src/main/java/com/zg/project/information/domain/PcdeDetail.java @@ -24,10 +24,11 @@ public class PcdeDetail extends BaseEntity { private String pcode; /** 所属场景 */ - @Excel(name = "所属场景名称") + @Excel(name = "所属场景编号") private String scene; /** 所属场景名称 */ + @Excel(name = "所属场景名称") private String sceneName; /** 所属仓库 */ diff --git a/src/main/java/com/zg/project/information/domain/SceneMapping.java b/src/main/java/com/zg/project/information/domain/SceneMapping.java index 8a892f0..08b4e61 100644 --- a/src/main/java/com/zg/project/information/domain/SceneMapping.java +++ b/src/main/java/com/zg/project/information/domain/SceneMapping.java @@ -7,7 +7,7 @@ import com.zg.framework.web.domain.BaseEntity; /** * 场景编号对象 scene_mapping - * + * * @author zg * @date 2025-05-24 */ @@ -26,42 +26,73 @@ public class SceneMapping extends BaseEntity @Excel(name = "场景名称") private String sceneName; - public void setId(Long id) + /** 所属仓库编码 */ + @Excel(name = "所属仓库编码") + private String warehouseCode; + + /** 所属仓库名称(查询时通过关联 warehouse_info 返回) */ + @Excel(name = "所属仓库名称") + private String warehouseName; + + public void setId(Long id) { this.id = id; } - public Long getId() + public Long getId() { return id; } - public void setSceneCode(String sceneCode) + public void setSceneCode(String sceneCode) { this.sceneCode = sceneCode; } - public String getSceneCode() + public String getSceneCode() { return sceneCode; } - public void setSceneName(String sceneName) + public void setSceneName(String sceneName) { this.sceneName = sceneName; } - public String getSceneName() + public String getSceneName() { return sceneName; } + public void setWarehouseCode(String warehouseCode) + { + this.warehouseCode = warehouseCode; + } + + public String getWarehouseCode() + { + return warehouseCode; + } + + public void setWarehouseName(String warehouseName) + { + this.warehouseName = warehouseName; + } + + public String getWarehouseName() + { + return warehouseName; + } + @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("sceneCode", getSceneCode()) - .append("sceneName", getSceneName()) - .toString(); + public String toString() + { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("sceneCode", getSceneCode()) + .append("sceneName", getSceneName()) + .append("warehouseCode", getWarehouseCode()) + .append("warehouseName", getWarehouseName()) + .toString(); } } diff --git a/src/main/java/com/zg/project/information/domain/WarehouseInfo.java b/src/main/java/com/zg/project/information/domain/WarehouseInfo.java index 40332c6..f1a08e7 100644 --- a/src/main/java/com/zg/project/information/domain/WarehouseInfo.java +++ b/src/main/java/com/zg/project/information/domain/WarehouseInfo.java @@ -9,7 +9,7 @@ import com.zg.framework.web.domain.BaseEntity; /** * 仓库信息对象 warehouse_info - * + * * @author zg * @date 2025-05-24 */ @@ -32,8 +32,16 @@ public class WarehouseInfo extends BaseEntity @Excel(name = "仓库地址") private String address; + /** 所属大仓编码 */ + @Excel(name = "所属大仓编码") + private String parentWarehouseCode; + + /** 所属大仓名称 */ + @Excel(name = "所属大仓名称") + private String parentWarehouseName; + /** 状态(1=启用,0=禁用) */ - @Excel(name = "状态", readConverterExp = "1==启用,0=禁用") + @Excel(name = "状态", readConverterExp = "1=启用,0=禁用") private Long status; /** 排序值 */ @@ -50,98 +58,123 @@ public class WarehouseInfo extends BaseEntity @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") private Date updatedAt; - public void setId(Long id) + // ===================== Getter / Setter ===================== + + public void setId(Long id) { this.id = id; } - public Long getId() + public Long getId() { return id; } - public void setWarehouseCode(String warehouseCode) + public void setWarehouseCode(String warehouseCode) { this.warehouseCode = warehouseCode; } - public String getWarehouseCode() + public String getWarehouseCode() { return warehouseCode; } - public void setWarehouseName(String warehouseName) + public void setWarehouseName(String warehouseName) { this.warehouseName = warehouseName; } - public String getWarehouseName() + public String getWarehouseName() { return warehouseName; } - public void setAddress(String address) + public void setAddress(String address) { this.address = address; } - public String getAddress() + public String getAddress() { return address; } - public void setStatus(Long status) + public void setParentWarehouseCode(String parentWarehouseCode) + { + this.parentWarehouseCode = parentWarehouseCode; + } + + public String getParentWarehouseCode() + { + return parentWarehouseCode; + } + + public void setParentWarehouseName(String parentWarehouseName) + { + this.parentWarehouseName = parentWarehouseName; + } + + public String getParentWarehouseName() + { + return parentWarehouseName; + } + + public void setStatus(Long status) { this.status = status; } - public Long getStatus() + public Long getStatus() { return status; } - public void setSort(Long sort) + public void setSort(Long sort) { this.sort = sort; } - public Long getSort() + public Long getSort() { return sort; } - public void setCreatedAt(Date createdAt) + public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } - public Date getCreatedAt() + public Date getCreatedAt() { return createdAt; } - public void setUpdatedAt(Date updatedAt) + public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } - public Date getUpdatedAt() + public Date getUpdatedAt() { return updatedAt; } @Override - public String toString() { - return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) - .append("id", getId()) - .append("warehouseCode", getWarehouseCode()) - .append("warehouseName", getWarehouseName()) - .append("address", getAddress()) - .append("status", getStatus()) - .append("sort", getSort()) - .append("remark", getRemark()) - .append("createdAt", getCreatedAt()) - .append("updatedAt", getUpdatedAt()) - .toString(); + public String toString() + { + return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("warehouseCode", getWarehouseCode()) + .append("warehouseName", getWarehouseName()) + .append("address", getAddress()) + .append("parentWarehouseCode", getParentWarehouseCode()) + .append("parentWarehouseName", getParentWarehouseName()) + .append("status", getStatus()) + .append("sort", getSort()) + .append("remark", getRemark()) + .append("createdAt", getCreatedAt()) + .append("updatedAt", getUpdatedAt()) + .toString(); } } diff --git a/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java b/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java index 7c3a282..86faf8d 100644 --- a/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java +++ b/src/main/java/com/zg/project/information/mapper/PcdeDetailMapper.java @@ -74,4 +74,11 @@ public interface PcdeDetailMapper * @return */ String selectEncodedIdByPcode(@Param("pcode") String pcode);; + + /** + * 批量插入(忽略已存在的) + * @param slice + * @return + */ + int batchInsertIgnore(List slice); } diff --git a/src/main/java/com/zg/project/information/service/impl/PcdeDetailServiceImpl.java b/src/main/java/com/zg/project/information/service/impl/PcdeDetailServiceImpl.java index 13794ce..f6a15af 100644 --- a/src/main/java/com/zg/project/information/service/impl/PcdeDetailServiceImpl.java +++ b/src/main/java/com/zg/project/information/service/impl/PcdeDetailServiceImpl.java @@ -1,15 +1,13 @@ package com.zg.project.information.service.impl; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.TimerTask; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.zg.common.exception.ServiceException; import com.zg.common.utils.DateUtils; +import com.zg.common.utils.StringUtils; import com.zg.framework.manager.AsyncManager; import com.zg.project.wisdom.mapper.RkInfoMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -157,55 +155,62 @@ public class PcdeDetailServiceImpl implements IPcdeDetailService throw new ServiceException("导入数据不能为空!"); } - AtomicInteger successNum = new AtomicInteger(0); - AtomicInteger failureNum = new AtomicInteger(0); - List failureMsgs = Collections.synchronizedList(new ArrayList<>()); + final Date now = DateUtils.getNowDate(); - for (PcdeDetail detail : pcdeList) { - TimerTask task = new TimerTask() { - @Override - public void run() { - try { - PcdeDetail exist = pcdeDetailMapper.selectByPcode(detail.getPcode()); - if (exist == null) { - detail.setCreateBy(operName); - detail.setCreateTime(DateUtils.getNowDate()); - pcdeDetailMapper.insertPcdeDetail(detail); - successNum.incrementAndGet(); - } else { - failureNum.incrementAndGet(); - failureMsgs.add("库位编号 = " + detail.getPcode() + " 已存在"); - } - } catch (Exception e) { - failureNum.incrementAndGet(); - failureMsgs.add("库位编号 = " + detail.getPcode() + " 导入失败:" + e.getMessage()); - } - } - }; - - // ✅ 使用自定义线程池工具类提交任务 - AsyncManager.me().execute(task); - } - - // ❗此处无法精确等待全部线程完成,只做简单延时(如需精确等待建议用 CountDownLatch) - try { - Thread.sleep(2000); // 根据量级可调,比如 100 条记录等 1~2 秒 - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - if (failureNum.get() > 0) { - StringBuilder msg = new StringBuilder(); - msg.append("很抱歉,导入失败!共 ").append(failureNum.get()).append(" 条数据有误,错误如下:"); - for (String fail : failureMsgs) { - msg.append("
").append(fail); + // 1) 清洗 + 本地生成 encodedId(逐字符→Unicode→HEX大写→拼接) + List cleaned = new ArrayList<>(pcdeList.size()); + for (PcdeDetail d : pcdeList) { + if (d == null) continue; + String p = d.getPcode() == null ? null : d.getPcode().trim(); + if (StringUtils.isEmpty(p)) { + // 跳过空 pcode + continue; } - throw new ServiceException(msg.toString()); - } else { - return "恭喜您,数据已全部导入成功!共 " + successNum.get() + " 条。"; + d.setPcode(p); + d.setEncodedId(toHexStringFromPcode(p)); + + // 审计字段(与你实体保持一致:createdBy/createdAt/updatedBy/updatedAt) + d.setCreatedBy(operName); + d.setCreatedAt(now); + d.setUpdatedBy(operName); + d.setUpdatedAt(now); + + // 业务兜底 + if (d.getIsDelete() == null) d.setIsDelete("0"); + + cleaned.add(d); } + + if (cleaned.isEmpty()) { + throw new ServiceException("有效的库位编号为空,请检查导入文件!"); + } + + // 2) 批量写库(分片,避免 SQL 过大;配合 uk_pcode + INSERT IGNORE 实现幂等忽略) + final int batchSize = 1000; + int totalTried = cleaned.size(); + int totalInserted = 0; + + for (int i = 0; i < cleaned.size(); i += batchSize) { + int end = Math.min(i + batchSize, cleaned.size()); + List slice = cleaned.subList(i, end); + int affected = pcdeDetailMapper.batchInsertIgnore(slice); + totalInserted += affected; + } + + int skipped = totalTried - totalInserted; + return String.format("导入完成:共读取 %d 条,成功导入 %d 条,跳过(可能重复) %d 条。", + totalTried, totalInserted, skipped); } + /** 将 pcode 按字符转大写十六进制(与新增接口保持一致) */ + private String toHexStringFromPcode(String pcode) { + StringBuilder hex = new StringBuilder(pcode.length() * 2); + for (int i = 0; i < pcode.length(); i++) { + char c = pcode.charAt(i); + hex.append(Integer.toHexString(c).toUpperCase()); + } + return hex.toString(); + } /** * 获取未被入库单据使用的库位列表 diff --git a/src/main/resources/application-druid.yml b/src/main/resources/application-druid.yml index 150e0ad..88d57ed 100644 --- a/src/main/resources/application-druid.yml +++ b/src/main/resources/application-druid.yml @@ -7,9 +7,9 @@ spring: # 主库数据源 master: # url: jdbc:mysql://101.132.133.142:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 -# url: jdbc:mysql://192.168.1.20:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:mysql://192.168.1.20:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://192.168.1.192:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 - url: jdbc:mysql://192.168.1.251:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# url: jdbc:mysql://192.168.1.251:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://localhost:3306/wisdom?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: shzg diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9f6d16c..3644ec4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -69,8 +69,8 @@ spring: redis: # 地址 # host: 101.132.133.142 -# host: 192.168.1.20 - host: 192.168.1.251 + host: 192.168.1.20 +# host: 192.168.1.251 # host: localhost # 端口,默认为6379 port: 6379 diff --git a/src/main/resources/mybatis/information/PcdeDetailMapper.xml b/src/main/resources/mybatis/information/PcdeDetailMapper.xml index 37c8e58..b9503c0 100644 --- a/src/main/resources/mybatis/information/PcdeDetailMapper.xml +++ b/src/main/resources/mybatis/information/PcdeDetailMapper.xml @@ -131,6 +131,32 @@ where id = #{id} + + INSERT IGNORE INTO pcde_detail + (pcode, scene, scene_name, warehouse, warehouse_name, + encoded_id, tag, remark, is_delete, + created_by, created_at, updated_by, updated_at) + VALUES + + ( + #{item.pcode}, + #{item.scene}, + #{item.sceneName}, + #{item.warehouse}, + #{item.warehouseName}, + #{item.encodedId}, + #{item.tag}, + #{item.remark}, + #{item.isDelete}, + #{item.createdBy}, + #{item.createdAt}, + #{item.updatedBy}, + #{item.updatedAt} + ) + + + + delete from pcde_detail where id = #{id} diff --git a/src/main/resources/mybatis/information/SceneMappingMapper.xml b/src/main/resources/mybatis/information/SceneMappingMapper.xml index b2da7cc..9c6a398 100644 --- a/src/main/resources/mybatis/information/SceneMappingMapper.xml +++ b/src/main/resources/mybatis/information/SceneMappingMapper.xml @@ -1,61 +1,103 @@ + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - + + + + + + + + + - select id, scene_code, scene_name from scene_mapping + SELECT + sm.id, + sm.scene_code, + sm.scene_name, + sm.warehouse_code, + wi.warehouse_name AS warehouse_name + FROM scene_mapping sm + LEFT JOIN warehouse_info wi + ON wi.warehouse_code = sm.warehouse_code + - + + + - insert into scene_mapping + INSERT INTO scene_mapping scene_code, scene_name, - - + warehouse_code, + warehouse_name, + + #{sceneCode}, #{sceneName}, - + #{warehouseCode}, + #{warehouseName}, + + - update scene_mapping + UPDATE scene_mapping - scene_code = #{sceneCode}, - scene_name = #{sceneName}, + + scene_code = #{sceneCode}, + + + scene_name = #{sceneName}, + + + warehouse_code = #{warehouseCode}, + + + warehouse_name = #{warehouseName}, + - where id = #{id} + WHERE id = #{id} + - delete from scene_mapping where id = #{id} + DELETE FROM scene_mapping WHERE id = #{id} - delete from scene_mapping where id in + DELETE FROM scene_mapping WHERE id IN #{id} - \ No newline at end of file + + diff --git a/src/main/resources/mybatis/information/WarehouseInfoMapper.xml b/src/main/resources/mybatis/information/WarehouseInfoMapper.xml index 984aeb3..4cc4356 100644 --- a/src/main/resources/mybatis/information/WarehouseInfoMapper.xml +++ b/src/main/resources/mybatis/information/WarehouseInfoMapper.xml @@ -1,90 +1,152 @@ + PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - select id, warehouse_code, warehouse_name, address, status, sort, remark, created_at, updated_at from warehouse_info + SELECT + id, + warehouse_code, + warehouse_name, + address, + parent_warehouse_code, + parent_warehouse_name, + status, + sort, + remark, + created_at, + updated_at + FROM warehouse_info + - + + + - insert into warehouse_info + INSERT INTO warehouse_info warehouse_code, warehouse_name, address, + + + parent_warehouse_code, + parent_warehouse_name, + status, sort, remark, created_at, updated_at, - - + + #{warehouseCode}, #{warehouseName}, #{address}, + + + #{parentWarehouseCode}, + #{parentWarehouseName}, + #{status}, #{sort}, #{remark}, #{createdAt}, #{updatedAt}, - + + - update warehouse_info + UPDATE warehouse_info warehouse_code = #{warehouseCode}, warehouse_name = #{warehouseName}, address = #{address}, + + + parent_warehouse_code = #{parentWarehouseCode}, + parent_warehouse_name = #{parentWarehouseName}, + status = #{status}, sort = #{sort}, remark = #{remark}, created_at = #{createdAt}, updated_at = #{updatedAt}, - where id = #{id} + WHERE id = #{id} + - delete from warehouse_info where id = #{id} + DELETE FROM warehouse_info WHERE id = #{id} - delete from warehouse_info where id in + DELETE FROM warehouse_info WHERE id IN #{id} - \ No newline at end of file +