feat(core): 添加出库申请定时任务和二维码生成功能

- 新增 OutboundApplicationJob 定时任务处理出货单据二维码生成
- 添加 ScmgiplanEntity 和 ScmGiPlanItemEntity 实体类定义
- 创建 ScmgiplanQrEntity 和 ScmgiPlanSyncLogEntity 二维码相关实体
- 实现 ScmgiPlanService 服务接口及 ScmgiPlanServiceImpl 实现类
- 添加 ScmgiPlanItemMapper、ScmgiPlanMapper、ScmgiPlanQrMapper 等数据访问层
- 集成二维码生成工具类 QrCodeUtil 支持数据压缩功能
- 创建 QrOutboundApplicationController 提供出库申请相关接口
- 修改数据库配置将 schema 从 ERPCS 和 ERP 统一为 GSSERVER
This commit is contained in:
Gjm
2026-05-19 12:22:24 +08:00
parent 5e1bbc3905
commit 09d56134fe
15 changed files with 232 additions and 89 deletions

View File

@@ -36,6 +36,10 @@
<groupId>com.lideeyunji</groupId>
<artifactId>lidee-module-biz</artifactId>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>

View File

@@ -7,54 +7,54 @@ spring:
dynamic: # 多数据源配置
primary: master
datasource:
master:
# 达梦数据库 主库,业务库
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://127.0.0.1:5236?schema=GSSERVER&compatible_mode=mysql
username: sysdba
password: Gao1048783178
lideeyunji: # 从库,框架库
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://127.0.0.1:5236?schema=ERPCS&compatible_mode=mysql
username: sysdba
password: Gao1048783178
slave: # 日志库单独
lazy: true # 开启懒加载,保证启动速度
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://127.0.0.1:5236?schema=ERPCS&compatible_mode=mysql
username: sysdba
password: Gao1048783178
erp_dev: # erp
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://127.0.0.1:5236?schema=GSSERVER&compatible_mode=mysql
username: sysdba
password: Gao1048783178
sjzt: # 数据中台
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://127.0.0.1:5236?schema=DATAMIDDLEPLATFORM&compatible_mode=mysql
username: sysdba
password: Gao1048783178
mes_dev: # 数据中台
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://127.0.0.1:5236?schema=DATAMIDDLEPLATFORM&compatible_mode=mysql
username: sysdba
password: Gao1048783178
# master:
# # 达梦数据库 主库,业务库
# driver-class-name: dm.jdbc.driver.DmDriver
# url: jdbc:dm://192.168.107.5:5238?schema=GSSERVER&compatible_mode=mysql
# username: GSSERVER
# password: HGgs123456
# url: jdbc:dm://127.0.0.1:5236?schema=GSSERVER&compatible_mode=mysql
# username: sysdba
# password: Gao1048783178
# lideeyunji: # 从库,框架库
# driver-class-name: dm.jdbc.driver.DmDriver
# url: jdbc:dm://127.0.0.1:5236?schema=ERPCS&compatible_mode=mysql
# username: sysdba
# password: Gao1048783178
# slave: # 日志库单独
# lazy: true # 开启懒加载,保证启动速度
# driver-class-name: dm.jdbc.driver.DmDriver
# url: jdbc:dm://127.0.0.1:5236?schema=ERPCS&compatible_mode=mysql
# username: sysdba
# password: Gao1048783178
# erp_dev: # erp
# driver-class-name: dm.jdbc.driver.DmDriver
# url: jdbc:dm://192.168.107.5:5238?schema=GSSERVER&compatible_mode=mysql
# username: GSSERVER
# password: HGgs123456
# sales_dev: # 数据中台
# url: jdbc:dm://127.0.0.1:5236?schema=GSSERVER&compatible_mode=mysql
# username: sysdba
# password: Gao1048783178
# sjzt: # 数据中台
# driver-class-name: dm.jdbc.driver.DmDriver
# url: jdbc:dm://192.168.107.5:5237?schema=HGGS&compatible_mode=oracle
# username: HGGS
# password: HGgs123456!
# url: jdbc:dm://127.0.0.1:5236?schema=DATAMIDDLEPLATFORM&compatible_mode=mysql
# username: sysdba
# password: Gao1048783178
# mes_dev: # 数据中台
# driver-class-name: dm.jdbc.driver.DmDriver
# url: jdbc:dm://127.0.0.1:5236?schema=DATAMIDDLEPLATFORM&compatible_mode=mysql
# username: sysdba
# password: Gao1048783178
master:
# 达梦数据库 主库,业务库
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://192.168.107.5:5238?schema=GSSERVER&compatible_mode=mysql
username: GSSERVER
password: HGgs123456
erp_dev: # erp
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://192.168.107.5:5238?schema=GSSERVER&compatible_mode=mysql
username: GSSERVER
password: HGgs123456
sales_dev: # 数据中台
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://192.168.107.5:5237?schema=HGGS&compatible_mode=oracle
username: HGGS
password: HGgs123456!
redis:

View File

@@ -16,6 +16,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -183,6 +184,7 @@ public class BomBasicDataInformationJob implements JobHandler {
} else {
CappIntegrationPbomTable newLog = new CappIntegrationPbomTable();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
newLog.setId(UUID.randomUUID().toString());
newLog.setSendNo(sdf.format(new Date()));
newLog.setChangeType(type);
newLog.setLastUpdateTime(String.valueOf(now));

View File

@@ -52,7 +52,7 @@ public class OutboundApplicationJob implements JobHandler {
Date lastSyncTime = getLastSyncTime(SYNC_LOG_TYPE_OUT);
ScmgiplanEntity scmgiplanEntity = new ScmgiplanEntity();
scmgiplanEntity.setPlanStatus("2");
scmgiplanEntity.setPlanStatus("3");
if (lastSyncTime != null)
scmgiplanEntity.setTimestampLastchangedon(lastSyncTime);
scmgiPlanService.selectList(scmgiplanEntity);

View File

@@ -69,4 +69,6 @@ public class CappIntegrationPbomTable {
*/
@TableField("ISREAD")
private Integer isRead;
@TableField("ID")
private String id;
}

View File

@@ -20,7 +20,7 @@ public class CopyJsbomEntity {
* 产品名称
*/
@TableField("NAME_CHS")
private String name;
private String nameChs;
/**
* BOM类型ID

View File

@@ -19,8 +19,8 @@ public class JsbomzxBackUpEntity {
/**
* 物料名称
*/
@TableField("NAME")
private String name;
@TableField("NAME_CHS")
private String nameChs;
/**
* 外协供料

View File

@@ -29,6 +29,7 @@ public interface ErpBfPartnerBankAccountsMapper extends BaseMapper<ErpBfPartnerB
}
return this.selectList(new LambdaQueryWrapper<ErpBfPartnerBankAccountsEntity>().eq(ErpBfPartnerBankAccountsEntity::getAccountCode, accountCodes.getAccountCode())
.eq(ErpBfPartnerBankAccountsEntity::getPartnerId, accountCodes.getPartnerId())
.eq(ErpBfPartnerBankAccountsEntity::getStateIsEnabled, "1")
);
}

View File

@@ -30,6 +30,7 @@ public interface ErpBfPartnerHeadExtMapper extends BaseMapper<ErpBfPartnerHeadEx
}
return this.selectList(new LambdaQueryWrapper<ErpBfPartnerHeadExtEntity>().eq(ErpBfPartnerHeadExtEntity::getVersion, versions.getVersion())
.eq(ErpBfPartnerHeadExtEntity::getPartnerId, versions.getPartnerId())
.last("LIMIT 1")
);
}

View File

@@ -34,6 +34,7 @@ import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@Service
@Slf4j
@@ -141,10 +142,28 @@ public class BomMaterialServiceImpl extends ServiceImpl<BomMaterialMapper, Jsbom
return 0;
}
BomDataDTO bomDataDTO = JSON.parseObject(table.getMessageContext(), BomDataDTO.class);
//主表list
List<BomMaterialEntity> partObjList = bomDataDTO.getPartObjList();
if (!CollectionUtils.isEmpty(partObjList)) {
List<String> ccodeList = partObjList != null ? partObjList.stream()
.map(BomMaterialEntity::getCcode)
.filter(Objects::nonNull)
.collect(Collectors.toList()) : new ArrayList<>();
}
//关联表list
List<BomMaterialLinkEntity> bomLinkList = bomDataDTO.getBomLinkList();
if (!CollectionUtils.isEmpty(bomLinkList)) {
List<String> parentCodeList = bomLinkList != null ? bomLinkList.stream()
.map(BomMaterialLinkEntity::getCparentcode)
.filter(Objects::nonNull)
.collect(Collectors.toList()) : new ArrayList<>();
List<String> childCodeList = bomLinkList != null ? bomLinkList.stream()
.map(BomMaterialLinkEntity::getCchildcode)
.filter(Objects::nonNull)
.collect(Collectors.toList()) : new ArrayList<>();
}
int partCount = 0;
int linkCount = 0;
@@ -304,24 +323,35 @@ public class BomMaterialServiceImpl extends ServiceImpl<BomMaterialMapper, Jsbom
if (data == null || data.getCcode() == null) {
return 0;
}
ErpMaterialEntity existData = erpMaterialMapper.selectOne(
new LambdaQueryWrapper<ErpMaterialEntity>()
.eq(ErpMaterialEntity::getCode, data.getCcode())
.eq(ErpMaterialEntity::getStateIsEnabled, "1")
);
// ErpMaterialEntity existData = erpMaterialMapper.selectOne(
// new LambdaQueryWrapper<ErpMaterialEntity>()
// .eq(ErpMaterialEntity::getCode, data.getCcode())
// .eq(ErpMaterialEntity::getStateIsEnabled, "1")
// );
JsbomEntity jsbom = baseMapper.selectOne(
new LambdaQueryWrapper<JsbomEntity>()
.eq(JsbomEntity::getJsbomCpbh, data.getCcode())
.eq(JsbomEntity::getJsbomBombb, data.getCversion())
.eq(JsbomEntity::getJsbomSfty, "0")
);
CopyJsbomEntity copyJsbomEntity = new CopyJsbomEntity();
try {
if (jsbom != null) {
JsbomBackUpEntity jsbomBackUpEntity = new JsbomBackUpEntity();
JsbomEntity newJsbom = new JsbomEntity();
BeanUtils.copyProperties(jsbom, newJsbom);
BeanUtils.copyProperties(jsbom, jsbomBackUpEntity);
updateBomMain(jsbom, data, copyJsbomEntity);
jsbom.setJsbomCpid(existData != null ? existData.getId() : null);
updateBomMain(newJsbom, data, copyJsbomEntity);
// jsbom.setJsbomCpid(existData != null ? existData.getId() : null);
jsbom.setJsbomSfty("1");
jsbom.setJsbomFbsj(new Date());
if (newJsbom.getJsbomBombb() != null ) {
String newVersion = incrementVersion(jsbom.getJsbomBombb());
newJsbom.setJsbomBombb(newVersion);
}
newJsbom.setJsbomFbsj(new Date());
newJsbom.setId(UUID.randomUUID().toString());
baseMapper.updateById(jsbom);
baseMapper.insert(newJsbom);
copyBomMaterialMapper.updateById(copyJsbomEntity);
int i = bomMaterialBackUpMapper.updateById(jsbomBackUpEntity);
if (i == 0)
@@ -330,7 +360,8 @@ public class BomMaterialServiceImpl extends ServiceImpl<BomMaterialMapper, Jsbom
return 2;
} else {
JsbomEntity newJsbom = createBomMain(data);
newJsbom.setJsbomCpid(existData != null ? existData.getId() : null);
newJsbom.setJsbomFbsj(new Date());
// newJsbom.setJsbomCpid(existData != null ? existData.getId() : null);
baseMapper.insert(newJsbom);
BeanUtils.copyProperties(newJsbom, copyJsbomEntity);
copyBomMaterialMapper.insert(copyJsbomEntity);
@@ -343,6 +374,40 @@ public class BomMaterialServiceImpl extends ServiceImpl<BomMaterialMapper, Jsbom
}
}
private String incrementVersion(String version) {
if (version == null || version.isEmpty()) {
return version;
}
// 查找最后一位数字的位置
int lastDigitIndex = -1;
for (int i = version.length() - 1; i >= 0; i--) {
if (Character.isDigit(version.charAt(i))) {
lastDigitIndex = i;
} else {
break;
}
}
// 如果没有数字,直接返回原版本
if (lastDigitIndex == -1) {
return version + "1";
}
// 提取前缀和数字部分
String prefix = version.substring(0, lastDigitIndex);
String numberPart = version.substring(lastDigitIndex);
try {
int number = Integer.parseInt(numberPart);
return prefix + (number + 1);
} catch (NumberFormatException e) {
log.warn("版本号数字转换失败: {}", version);
return version;
}
}
/**
* 创建BOM主表实体
*/
@@ -371,27 +436,64 @@ public class BomMaterialServiceImpl extends ServiceImpl<BomMaterialMapper, Jsbom
* 填充BOM主表字段
*/
private void fillBomMainFields(JsbomEntity jsbom, BomMaterialEntity data) {
jsbom.setJsbomCpbh(data.getCcode());
jsbom.setNameChs(data.getCname());
jsbom.setJsbomBombb(data.getCversion());
jsbom.setJsbomCpth(data.getFlbjth());
jsbom.setJsbomCpxh(data.getFcpxh());
jsbom.setJsbomCpmc(data.getFcpmc());
jsbom.setJsbomMjmc(data.getClevel());
jsbom.setJsbomBz(data.getCremark());
jsbom.setJsbomCjr(data.getCreator());
jsbom.setJsbomCjrxm(data.getCreator());
if (data.getCcode() != null) {
jsbom.setJsbomCpbh(data.getCcode());
}
if (data.getCname() != null) {
jsbom.setNameChs(data.getCname());
}
if (data.getCversion() != null) {
jsbom.setJsbomBombb(data.getCversion());
}
if (data.getFlbjth() != null) {
jsbom.setJsbomCpth(data.getFlbjth());
}
if (data.getFcpxh() != null) {
jsbom.setJsbomCpxh(data.getFcpxh());
}
if (data.getFcpmc() != null) {
jsbom.setJsbomCpmc(data.getFcpmc());
}
if (data.getClevel() != null) {
jsbom.setJsbomMjmc(data.getClevel());
}
if (data.getCremark() != null) {
jsbom.setJsbomBz(data.getCremark());
}
if (data.getCreator() != null) {
jsbom.setJsbomCjr(data.getCreator());
jsbom.setJsbomCjrxm(data.getCreator());
}
//拓展
jsbom.setJsbomC0(data.getFclmc());
jsbom.setJsbomC1(data.getFclph());
jsbom.setJsbomC3(data.getFclgg());
jsbom.setJsbomC4(data.getFcpdh());
jsbom.setJsbomC7(data.getFrcl());
jsbom.setJsbomC8(data.getFbmcl());
jsbom.setJsbomC9(data.getFmpcc());
jsbom.setJsbomC5(data.getFjdbj());
jsbom.setJsbomC6(data.getProcessRoute());
if (data.getFclmc() != null) {
jsbom.setJsbomC0(data.getFclmc());
}
if (data.getFclph() != null) {
jsbom.setJsbomC1(data.getFclph());
}
if (data.getFclgg() != null) {
jsbom.setJsbomC3(data.getFclgg());
}
if (data.getFcpdh() != null) {
jsbom.setJsbomC4(data.getFcpdh());
}
if (data.getFrcl() != null) {
jsbom.setJsbomC7(data.getFrcl());
}
if (data.getFbmcl() != null) {
jsbom.setJsbomC8(data.getFbmcl());
}
if (data.getFmpcc() != null) {
jsbom.setJsbomC9(data.getFmpcc());
}
if (data.getFjdbj() != null) {
jsbom.setJsbomC5(data.getFjdbj());
}
if (data.getProcessRoute() != null) {
jsbom.setJsbomC6(data.getProcessRoute());
}
jsbom.setJsbomSfty("0");
// jsbom.setJsbomC13(data.getFsfyxwx());
// jsbom.setJsbomC14(data.getFgyzt());
// jsbom.setJsbomC15(data.getFjsbzh());
@@ -437,49 +539,75 @@ public class BomMaterialServiceImpl extends ServiceImpl<BomMaterialMapper, Jsbom
return 0;
}
// 一次查询获取未停用的BOM主表
JsbomEntity jsbom = baseMapper.selectOne(
new LambdaQueryWrapper<JsbomEntity>()
.eq(JsbomEntity::getJsbomCpbh, data.getCparentcode())
.eq(JsbomEntity::getJsbomBombb, data.getCparentversion())
.eq(JsbomEntity::getJsbomSfty, "0")
);
if (jsbom == null) {
log.warn("未找到父件BOM产品编号: {}, 版本: {}", data.getCparentcode(), data.getCparentversion());
log.warn("未找到未发布的父件BOM产品编号: {}", data.getCparentcode());
return 0;
}
JsbomzxEntity jsbomzxEntity = jsbomzxMapper.selectOne(
new LambdaQueryWrapper<JsbomzxEntity>()
.eq(JsbomzxEntity::getJsbomzxBomid, jsbom.getId())
.eq(JsbomzxEntity::getJsbomzxZxhh, data.getCindex())
);
// 查询物料信息(提前查询,避免重复)
ErpMaterialEntity existMaterialData = null;
if (data.getCchildcode() != null) {
existMaterialData = erpMaterialMapper.selectOne(
new LambdaQueryWrapper<ErpMaterialEntity>()
.eq(ErpMaterialEntity::getCode, data.getCchildcode())
);
}
// 查询子件是否存在
JsbomzxEntity jsbomzxEntity = null;
if (jsbom != null) {
jsbomzxEntity = jsbomzxMapper.selectOne(
new LambdaQueryWrapper<JsbomzxEntity>()
.eq(JsbomzxEntity::getJsbomzxBomid, jsbom.getId())
.eq(JsbomzxEntity::getJsbomzxWlbh, data.getCchildcode())
);
}
CopyJsbomzxEntity copyJsbomzxEntity = new CopyJsbomzxEntity();
try {
if (jsbomzxEntity != null) {
// 更新子件
JsbomzxBackUpEntity jsbomzxBackUpEntity = new JsbomzxBackUpEntity();
BeanUtils.copyProperties(jsbomzxEntity, jsbomzxBackUpEntity);
updateBomLinkFields(jsbomzxEntity, data);
jsbomzxEntity.setJsbomzxWlid(existMaterialData != null ? existMaterialData.getId() : null);
BeanUtils.copyProperties(jsbomzxEntity, copyJsbomzxEntity);
jsbomzxMapper.updateById(jsbomzxEntity);
copyJsbomzxMapper.updateById(copyJsbomzxEntity);
int i = jsbomzxBackUpMapper.updateById(jsbomzxBackUpEntity);
if (i == 0) {
jsbomzxBackUpMapper.insert(jsbomzxBackUpEntity);
}
log.debug("更新BOM子件BOM ID: {}, 序号: {}", jsbom.getId(), data.getCindex());
log.debug("更新BOM子件BOM ID: {}, 物料编号: {}", jsbom.getId(), data.getCchildcode());
return 2;
} else {
// 新增子件
JsbomzxEntity newJsbomzx = createBomLink(jsbom.getId(), data);
newJsbomzx.setJsbomzxWlid(existMaterialData != null ? existMaterialData.getId() : null);
BeanUtils.copyProperties(newJsbomzx, copyJsbomzxEntity);
copyJsbomzxMapper.insert(copyJsbomzxEntity);
jsbomzxMapper.insert(newJsbomzx);
log.debug("新增BOM子件BOM ID: {}, 序号: {}", jsbom.getId(), data.getCindex());
copyJsbomzxMapper.insert(copyJsbomzxEntity);
log.debug("新增BOM子件BOM ID: {}, 物料编号: {}", jsbom.getId(), data.getCchildcode());
return 1;
}
} catch (Exception e) {
log.error("同步BOM子件失败BOM ID: {}, 号: {}", jsbom.getId(), data.getCindex(), e);
log.error("同步BOM子件失败BOM ID: {}, 物料编号: {}", jsbom.getId(), data.getCchildcode(), e);
return 0;
}
}

View File

@@ -1783,6 +1783,8 @@ public class ErpBfPartnerServiceImpl extends ServiceImpl<ErpBfPartnerMapper, Erp
return 0;
}
if(data.getStateIsEnabled().equals("0"))
return 0;
log.debug("开始同步往来单位,编码: {}", data.getCode());
ErpBfPartner targetData = baseMapper.selectOne(
@@ -2147,7 +2149,7 @@ public class ErpBfPartnerServiceImpl extends ServiceImpl<ErpBfPartnerMapper, Erp
}
ErpBfPartner dcEntity = this.getPartnerEntity(partnerId);
if (dcEntity == null) {
if (dcEntity == null&&dcEntity.getStateIsEnabled().equals("0")) {
log.warn("未找到DC中的往来单位partnerId: {}", partnerId);
return null;
}

View File

@@ -205,6 +205,8 @@ public class ErpMaterialServiceImpl extends ServiceImpl<ErpMaterialMapper, ErpMa
@Override
public Integer syncDCPartnerByTimestamp(ErpMaterialEntity sourceData, Map<String, String> unitMap, Date time) {
if ("0".equals(sourceData.getStateIsEnabled()))
return 0;
String dcId = sourceData.getId();
log.info("开始处理DC物料信息数据,id {}", dcId);
Integer i = this.handleMaterials(sourceData);
@@ -1777,7 +1779,6 @@ public class ErpMaterialServiceImpl extends ServiceImpl<ErpMaterialMapper, ErpMa
if (targetData == null) {
String dcId = sourceData.getId();
sourceData.setId(String.valueOf(UUID.randomUUID()));
sourceData.setTimeStampLastChangedOn(new Date());
int insertResult = baseMapper.insert(sourceData);

View File

@@ -142,7 +142,7 @@ public class ScmgiPlanServiceImpl extends ServiceImpl<ScmgiPlanMapper, Scmgiplan
}
List<ScmgiplanEntity> scmgiplanEntities = baseMapper.selectList(new LambdaQueryWrapper<ScmgiplanEntity>()
.eq(ScmgiplanEntity::getPlanStatus, "2")
.eq(ScmgiplanEntity::getPlanStatus, "3")
.in(ScmgiplanEntity::getId, idList)
);
return scmgiplanEntities;

View File

@@ -17,6 +17,7 @@
select ID, CODE, DCID, UPDATETIME
from BFPARTNERSYNCID
where DCID = #{id}
limit 1
</select>
<insert id="saveBatchData">

View File

@@ -55,6 +55,7 @@ public class QrQrOutboundApplicationServiceImpl extends ServiceImpl<QrOutboundAp
ScmgiplanEntity dbEntity = scmgiPlanMapper.selectOne(new LambdaQueryWrapper<ScmgiplanEntity>()
.eq(ScmgiplanEntity::getPlanCode, scmgiplanEntity.getPlanCode())
.eq(ScmgiplanEntity::getPlanStatus, "3")
.eq(ScmgiplanEntity::getIsStop, "0"));
if (dbEntity == null) {