Browse Source
# Conflicts: # blade-service/logpm-patch/src/main/java/com/logpm/patch/jobhandle/SyncOrderInfoToPlatform.javamaster
134 changed files with 4620 additions and 881 deletions
@ -0,0 +1,112 @@
|
||||
package com.logpm.factorydata.mwh.mq; |
||||
|
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.EnumUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import cn.hutool.http.HttpUtil; |
||||
import cn.hutool.json.JSONObject; |
||||
import cn.hutool.json.JSONUtil; |
||||
import com.logpm.factorydata.feign.IFactoryDataClient; |
||||
import com.logpm.factorydata.mwh.enums.FactoryNodeEnums; |
||||
import com.logpm.factorydata.mwh.enums.NodeMappingEnums; |
||||
import com.logpm.factorydata.mwh.enums.NodeNeedEnums; |
||||
import com.logpm.factorydata.mwh.pros.OldProperties; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springblade.common.constant.WorkNodeEnums; |
||||
import org.springblade.common.constant.factorydata.FactoryDataConstants; |
||||
import org.springframework.amqp.core.ExchangeTypes; |
||||
import org.springframework.amqp.rabbit.annotation.Exchange; |
||||
import org.springframework.amqp.rabbit.annotation.Queue; |
||||
import org.springframework.amqp.rabbit.annotation.QueueBinding; |
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 监听业务系统推送给节点数据 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-18 0:02 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
@AllArgsConstructor |
||||
public class NodeDataPushListener { |
||||
|
||||
private final IFactoryDataClient factoryDataClient; |
||||
private final OldProperties oldProperties; |
||||
|
||||
@RabbitListener(bindings = @QueueBinding( |
||||
value = @Queue(name = FactoryDataConstants.Mq.Queues.MWH_NODE_DATA_PUSH, durable = "true"), |
||||
exchange = @Exchange(name = FactoryDataConstants.Mq.Exchanges.NODE_DATA_PUSH, type = ExchangeTypes.TOPIC), |
||||
key = FactoryDataConstants.Mq.RoutingKeys.MWH_NODE_DATA_PUSH |
||||
)) |
||||
@Transactional(rollbackFor = Exception.class) |
||||
public void nodeDataPush(String msg) { |
||||
log.info("接收到节点数据推送:{}", msg); |
||||
if (checkData(msg)) { |
||||
return; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
// 节点
|
||||
String node = entries.getStr("node"); |
||||
JSONObject main = entries.getJSONObject("main"); |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
FactoryNodeEnums factoryNode = NodeMappingEnums.getFactoryByNodeAndStatus(workNodeEnums); |
||||
// 2 获取业务数据
|
||||
// List<PushData> content = entries.getBeanList("content", PushData.class);
|
||||
String mwhOrderCode = main.getStr("mwhOrderCode"); |
||||
String totalCount = main.getStr("totalCount"); |
||||
String totalPrice = main.getStr("totalPrice"); |
||||
String waybillNo = main.getStr("waybillNo"); |
||||
JSONObject js = new JSONObject(); |
||||
JSONObject detail = new JSONObject(); |
||||
js.set("mhjOrderNo", mwhOrderCode); |
||||
detail.set("totalCount", totalCount); |
||||
detail.set("totalPrice", totalPrice); |
||||
detail.set("waybillNo", waybillNo); |
||||
js.set("waybillInfo", detail); |
||||
if (oldProperties.getEnable()) { |
||||
try { |
||||
log.info("推送节点数据:{}", JSONUtil.toJsonStr(js)); |
||||
String post = HttpUtil.post(oldProperties.getOldSystemHost() + oldProperties.getOldOpenOrderUrl(), JSONUtil.toJsonStr(js)); |
||||
log.info("推送结果:{}", post); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
log.error("推送节点数据错误:{}", e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private boolean checkData(String msg) { |
||||
if (StrUtil.isEmpty(msg)) { |
||||
return true; |
||||
} |
||||
if (!msg.contains("brand") || !msg.contains("content") || !msg.contains("node")) { |
||||
return true; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
String node = entries.getStr("node"); |
||||
if (StrUtil.isEmpty(node)) { |
||||
return true; |
||||
} |
||||
// 不是志邦需要的节点数据直接不处理
|
||||
if (!EnumUtil.contains(NodeNeedEnums.class, node)) { |
||||
return true; |
||||
} |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
if (ObjectUtil.isEmpty(workNodeEnums)) { |
||||
return true; |
||||
} |
||||
List<JSONObject> content = entries.getBeanList("content", JSONObject.class); |
||||
if (CollUtil.isEmpty(content)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,58 @@
|
||||
package com.logpm.factorydata.mwh.pros; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* 老系统配置 |
||||
* @author zhaoqiaobo |
||||
* @Date 2024/5/29 |
||||
**/ |
||||
@Data |
||||
@Component |
||||
@ConfigurationProperties(prefix = "mwh") |
||||
public class OldProperties { |
||||
/** |
||||
* 金牌工厂推送节点数据url |
||||
*/ |
||||
private String pushNodeUrl; |
||||
/** |
||||
* 是否推送工厂 |
||||
*/ |
||||
private Boolean enable = true; |
||||
/** |
||||
* 金牌工厂主机地址 |
||||
*/ |
||||
private String host; |
||||
/** |
||||
* 承运商编码 |
||||
*/ |
||||
private String carrierCode; |
||||
|
||||
/** |
||||
* 补节点数据时的延时时间(分钟) |
||||
*/ |
||||
private Integer delayedTime = 30; |
||||
|
||||
/** |
||||
* 生成老系统暂存单 |
||||
*/ |
||||
private Boolean oldAdvance = false; |
||||
|
||||
/** |
||||
* 生成新系统暂存单 |
||||
*/ |
||||
private Boolean newAdvance = false; |
||||
|
||||
/** |
||||
* 老系统host |
||||
*/ |
||||
private String oldSystemHost; |
||||
|
||||
/** |
||||
* 老系统回传开单url |
||||
*/ |
||||
private String oldOpenOrderUrl; |
||||
|
||||
} |
@ -0,0 +1,36 @@
|
||||
package com.logpm.factorydata.mwh.vo; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
import io.swagger.annotations.ApiModel; |
||||
import io.swagger.annotations.ApiModelProperty; |
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 曼好家订单状态 实体类 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-04-26 |
||||
*/ |
||||
@Data |
||||
@ApiModel(value = "曼好家订单状态", description = "曼好家订单状态") |
||||
public class OrderStatusVO implements Serializable { |
||||
|
||||
@ApiModelProperty(value = "状态") |
||||
@JsonProperty("STATUS") |
||||
private String status; |
||||
@ApiModelProperty(value = "时间") |
||||
@JsonProperty("TIME") |
||||
private String time; |
||||
@ApiModelProperty(value = "内容") |
||||
@JsonProperty("CONTENT") |
||||
private String content; |
||||
@ApiModelProperty(value = "订单号") |
||||
@JsonProperty("ORDER_NO") |
||||
private String orderNo; |
||||
@ApiModelProperty(value = "服务号") |
||||
@JsonProperty("DELIVERY_NO") |
||||
private String deliveryNo; |
||||
|
||||
} |
@ -0,0 +1,14 @@
|
||||
FROM 192.168.2.110:7777/hwy/hwy_base:v1.0 |
||||
|
||||
MAINTAINER h5u@163.com |
||||
|
||||
RUN mkdir -p /logpm/logpm-factory-data-oupai |
||||
|
||||
WORKDIR /logpm/logpm-factory-data-oupai |
||||
|
||||
EXPOSE 18970 |
||||
|
||||
ADD ./target/logpm-factory-data-oupai.jar ./app.jar |
||||
|
||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar","-Xms128m","-Xmx512m", "app.jar"] |
||||
CMD ["--spring.profiles.active=test"] |
@ -0,0 +1,89 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-factory-data</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
</parent> |
||||
<artifactId>logpm-factory-data-oupai</artifactId> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>8</maven.compiler.source> |
||||
<maven.compiler.target>8</maven.compiler.target> |
||||
</properties> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-core-boot</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-core-auto</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-amqp</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-factory-data-api</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-starter-swagger</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-trunkline-api</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-factory-data-base-api</artifactId> |
||||
<version>${bladex.project.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-starter-oss</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>io.minio</groupId> |
||||
<artifactId>minio</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-resource-api</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
<scope>compile</scope> |
||||
</dependency> |
||||
|
||||
</dependencies> |
||||
|
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>com.spotify</groupId> |
||||
<artifactId>dockerfile-maven-plugin</artifactId> |
||||
<configuration> |
||||
<username>${docker.username}</username> |
||||
<password>${docker.password}</password> |
||||
<repository>${docker.registry.url}/${docker.namespace}/${project.artifactId}</repository> |
||||
<tag>${project.version}</tag> |
||||
<useMavenSettingsForAuth>true</useMavenSettingsForAuth> |
||||
<buildArgs> |
||||
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> |
||||
</buildArgs> |
||||
<skip>false</skip> |
||||
</configuration> |
||||
</plugin> |
||||
<plugin> |
||||
<groupId>org.apache.maven.plugins</groupId> |
||||
<artifactId>maven-antrun-plugin</artifactId> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
</project> |
@ -0,0 +1,20 @@
|
||||
package com.logpm.factorydata; |
||||
|
||||
import org.springblade.common.constant.ModuleNameConstant; |
||||
import org.springblade.core.cloud.client.BladeCloudApplication; |
||||
import org.springblade.core.launch.BladeApplication; |
||||
|
||||
/** |
||||
* 欧派工厂数据启动类 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-4-26 |
||||
*/ |
||||
@BladeCloudApplication |
||||
public class FactoryDataOuPaiApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
BladeApplication.run(ModuleNameConstant.LOGPM_FACTORY_DATA_OUPAI_NAME, FactoryDataOuPaiApplication.class, args); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,50 @@
|
||||
package com.logpm.factorydata.oupai.aspect; |
||||
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.reflect.MethodSignature; |
||||
import org.springblade.common.annotations.LogpmAsync; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.lang.reflect.Method; |
||||
|
||||
@Aspect |
||||
@Component |
||||
@Slf4j |
||||
@Order(-1) |
||||
public class AsyncAnnotationAspect { |
||||
|
||||
/** |
||||
* 定义一个切点,匹配所有带有@LogpmAsync("asyncExecutor")注解的方法。 |
||||
* 注意:实际上Spring Framework自带对@LogpmAsync("asyncExecutor")的处理,直接这样配置可能会导致预期之外的行为。 |
||||
*/ |
||||
//@Around("@annotation(org.springblade.common.annotations.LogpmAsync)")
|
||||
public Object logAroundAsyncMethods(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
||||
Method method = signature.getMethod(); |
||||
|
||||
LogpmAsync myAsync = method.getAnnotation(LogpmAsync.class); |
||||
String annotationValue = myAsync.value(); |
||||
log.info(">>>>>>>>>>>>>>>>>> annotationValue={}",annotationValue); |
||||
|
||||
log.info("@LogpmAsync注解的值为asyncExecutor,进行数据源切换 "); |
||||
|
||||
// 在方法执行前的操作
|
||||
String tenantId = AuthUtil.getTenantId(); |
||||
log.info(">> tenandId {} ",tenantId); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
|
||||
// 执行原方法
|
||||
Object result = joinPoint.proceed(); |
||||
|
||||
// 在方法执行后的操作
|
||||
DynamicDataSourceContextHolder.poll(); |
||||
return result; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.logpm.factorydata.oupai.aspect; |
||||
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Around; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Aspect |
||||
@Component |
||||
@Slf4j |
||||
public class RabbitAnnotationAspect { |
||||
|
||||
|
||||
/** |
||||
* 该方法为一个切面,用于对标记了@RabbitListener注解的方法进行增强,主要增加了日志记录和数据源上下文处理的功能。 |
||||
* |
||||
* @param joinPoint 切面的连接点,表示当前被拦截的方法。 |
||||
* @return 返回被拦截方法的执行结果。 |
||||
* @throws Throwable 如果执行过程中发生异常,则抛出。 |
||||
*/ |
||||
@Around("@annotation(org.springframework.amqp.rabbit.annotation.RabbitListener)") |
||||
public Object rabbitMethods(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
// 在方法执行前,获取当前租户ID并设置到数据源上下文中
|
||||
String tenantId = AuthUtil.getTenantId(); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
// 执行原方法
|
||||
Object result = joinPoint.proceed(); |
||||
// 在方法执行后,从数据源上下文中移除租户ID
|
||||
DynamicDataSourceContextHolder.poll(); |
||||
return result; |
||||
} |
||||
|
||||
@Around("@annotation(org.springframework.amqp.rabbit.annotation.RabbitHandler)") |
||||
public Object rabbitHandlerMethods(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
// 在方法执行前,获取当前租户ID并设置到数据源上下文中
|
||||
String tenantId = AuthUtil.getTenantId(); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
// 执行原方法
|
||||
Object result = joinPoint.proceed(); |
||||
// 在方法执行后,从数据源上下文中移除租户ID
|
||||
DynamicDataSourceContextHolder.poll(); |
||||
return result; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,161 @@
|
||||
package com.logpm.factorydata.oupai.config; |
||||
|
||||
import cn.hutool.core.util.StrUtil; |
||||
import cn.hutool.json.JSONUtil; |
||||
import org.springblade.core.secure.BladeUser; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springblade.core.tool.utils.ThreadLocalUtil; |
||||
import org.springframework.amqp.core.Message; |
||||
import org.springframework.amqp.core.MessageProperties; |
||||
import org.springframework.amqp.support.converter.AllowedListDeserializingMessageConverter; |
||||
import org.springframework.amqp.support.converter.MessageConversionException; |
||||
import org.springframework.amqp.utils.SerializationUtils; |
||||
import org.springframework.beans.factory.BeanClassLoaderAware; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.remoting.rmi.CodebaseAwareObjectInputStream; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.util.ClassUtils; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectStreamClass; |
||||
import java.io.Serializable; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author zhaoqiaobo |
||||
* @create 2024-05-08 |
||||
*/ |
||||
@Component |
||||
public class CustomMessageConverter extends AllowedListDeserializingMessageConverter implements BeanClassLoaderAware { |
||||
|
||||
private volatile String defaultCharset = "UTF-8"; |
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); |
||||
private String codebaseUrl; |
||||
|
||||
@Deprecated |
||||
public void setCodebaseUrl(String codebaseUrl) { |
||||
this.codebaseUrl = codebaseUrl; |
||||
} |
||||
|
||||
@Override |
||||
public Object fromMessage(Message message) throws MessageConversionException { |
||||
Object content = null; |
||||
MessageProperties properties = message.getMessageProperties(); |
||||
if (properties != null) { |
||||
String contentType = properties.getContentType(); |
||||
if (contentType != null && contentType.startsWith("text")) { |
||||
String encoding = properties.getContentEncoding(); |
||||
if (encoding == null) { |
||||
encoding = "UTF-8"; |
||||
} |
||||
|
||||
try { |
||||
content = new String(message.getBody(), encoding); |
||||
} catch (UnsupportedEncodingException var8) { |
||||
throw new MessageConversionException("failed to convert text-based Message content", var8); |
||||
} |
||||
} else if (contentType != null && contentType.equals("application/x-java-serialized-object")) { |
||||
try { |
||||
content = SerializationUtils.deserialize(this.createObjectInputStream(new ByteArrayInputStream(message.getBody()), this.codebaseUrl)); |
||||
} catch (IllegalArgumentException | IllegalStateException | IOException var7) { |
||||
throw new MessageConversionException("failed to convert serialized Message content", var7); |
||||
} |
||||
} |
||||
} |
||||
Map<String, Object> headers = properties.getHeaders(); |
||||
HttpHeaders httpHeaders = new HttpHeaders(); |
||||
for (Map.Entry<String, Object> entry : headers.entrySet()) { |
||||
if (StrUtil.equals("Blade-Auth", entry.getKey()) |
||||
|| StrUtil.equals("Authorization", entry.getKey()) |
||||
|| StrUtil.equals("blade-auth", entry.getKey()) |
||||
|| StrUtil.equals("authorization", entry.getKey())) { |
||||
List value = (List) entry.getValue(); |
||||
for (Object o : value) { |
||||
httpHeaders.add(entry.getKey(), String.valueOf(o)); |
||||
} |
||||
} |
||||
} |
||||
ThreadLocalUtil.put("bladeContext", httpHeaders); |
||||
Object bladeUser = headers.get("bladeUser"); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(); |
||||
BladeUser bladeUser1 = JSONUtil.toBean(bladeUser.toString(), BladeUser.class); |
||||
request.setAttribute("_BLADE_USER_REQUEST_ATTR_", bladeUser1); |
||||
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); |
||||
if (content == null) { |
||||
content = message.getBody(); |
||||
} |
||||
return content; |
||||
} |
||||
|
||||
@Override |
||||
protected Message createMessage(Object object, MessageProperties messageProperties) throws MessageConversionException { |
||||
byte[] bytes = null; |
||||
if (object instanceof byte[]) { |
||||
bytes = (byte[]) object; |
||||
messageProperties.setContentType("application/octet-stream"); |
||||
} else if (object instanceof String) { |
||||
try { |
||||
bytes = ((String) object).getBytes(this.defaultCharset); |
||||
} catch (UnsupportedEncodingException var6) { |
||||
throw new MessageConversionException("failed to convert to Message content", var6); |
||||
} |
||||
|
||||
messageProperties.setContentType("text/plain"); |
||||
messageProperties.setContentEncoding(this.defaultCharset); |
||||
} else if (object instanceof Serializable) { |
||||
try { |
||||
bytes = SerializationUtils.serialize(object); |
||||
} catch (IllegalArgumentException var5) { |
||||
throw new MessageConversionException("failed to convert to serialized Message content", var5); |
||||
} |
||||
|
||||
messageProperties.setContentType("application/x-java-serialized-object"); |
||||
} |
||||
HttpHeaders headers = (HttpHeaders) ThreadLocalUtil.get("bladeContext"); |
||||
if (headers != null && !headers.isEmpty()) { |
||||
headers.forEach((key, values) -> { |
||||
values.forEach((value) -> { |
||||
messageProperties.setHeader(key, new String[]{value}); |
||||
}); |
||||
}); |
||||
} |
||||
BladeUser user = AuthUtil.getUser(); |
||||
BladeUser bladeUser = new BladeUser(); |
||||
bladeUser.setTenantId(user.getTenantId()); |
||||
bladeUser.setUserId(user.getUserId()); |
||||
bladeUser.setAccount(user.getAccount()); |
||||
bladeUser.setRoleId(user.getRoleId()); |
||||
messageProperties.setHeader("bladeUser", JSONUtil.toJsonStr(bladeUser)); |
||||
|
||||
if (bytes != null) { |
||||
messageProperties.setContentLength((long) bytes.length); |
||||
return new Message(bytes, messageProperties); |
||||
} else { |
||||
throw new IllegalArgumentException(this.getClass().getSimpleName() + " only supports String, byte[] and Serializable payloads, received: " + object.getClass().getName()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setBeanClassLoader(ClassLoader classLoader) { |
||||
this.beanClassLoader = beanClassLoader; |
||||
} |
||||
|
||||
protected ObjectInputStream createObjectInputStream(InputStream is, String codebaseUrl) throws IOException { |
||||
return new CodebaseAwareObjectInputStream(is, this.beanClassLoader, codebaseUrl) { |
||||
@Override |
||||
protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { |
||||
Class<?> clazz = super.resolveClass(classDesc); |
||||
CustomMessageConverter.this.checkAllowedList(clazz); |
||||
return clazz; |
||||
} |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,85 @@
|
||||
package com.logpm.factorydata.oupai.config; |
||||
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.slf4j.MDC; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springblade.core.tool.utils.ThreadLocalUtil; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.core.task.TaskDecorator; |
||||
import org.springframework.scheduling.annotation.EnableAsync; |
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
import org.springframework.web.context.request.RequestAttributes; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
|
||||
import javax.annotation.Nonnull; |
||||
import java.util.Map; |
||||
import java.util.concurrent.Executor; |
||||
import java.util.concurrent.ThreadPoolExecutor; |
||||
|
||||
@Configuration |
||||
@Slf4j |
||||
@EnableAsync |
||||
public class ExecutorConfig { |
||||
|
||||
@Bean |
||||
public Executor asyncExecutor() { |
||||
log.info("start async executor"); |
||||
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); |
||||
// 配置核心线程数
|
||||
threadPoolTaskExecutor.setCorePoolSize(10); |
||||
// 配置最大线程数
|
||||
threadPoolTaskExecutor.setMaxPoolSize(20); |
||||
// 配置队列大小
|
||||
threadPoolTaskExecutor.setQueueCapacity(50); |
||||
// 配置线程池中线程的名称前缀
|
||||
threadPoolTaskExecutor.setThreadNamePrefix("ASYNC_THREAD_"); |
||||
// HelloWorldServiceImpl rejection-policy: 当pool已经达到max size时,如何处理新任务:
|
||||
// CallerRunsPolicy: 不在新线程中执行任务,而是由调用者所在的线程来执行;
|
||||
// AbortPolicy: 拒绝执行新任务,并抛出RejectedExecutionException异常;
|
||||
// DiscardPolicy:丢弃当前将要加入队列的任务;
|
||||
// DiscardOldestPolicy:丢弃任务队列中最旧的任务;
|
||||
threadPoolTaskExecutor.setRejectedExecutionHandler( |
||||
new ThreadPoolExecutor.CallerRunsPolicy() |
||||
); |
||||
threadPoolTaskExecutor.setTaskDecorator(new ContextCopyingDecorator()); |
||||
threadPoolTaskExecutor.initialize(); |
||||
return threadPoolTaskExecutor; |
||||
} |
||||
|
||||
|
||||
static class ContextCopyingDecorator implements TaskDecorator { |
||||
@Nonnull |
||||
@Override |
||||
public Runnable decorate(@Nonnull Runnable runnable) { |
||||
RequestAttributes context = RequestContextHolder.currentRequestAttributes(); |
||||
String tenantId = AuthUtil.getTenantId(); |
||||
Map<String, Object> all = ThreadLocalUtil.getAll(); |
||||
Map<String, String> mdcMap = MDC.getCopyOfContextMap(); |
||||
return () -> { |
||||
try { |
||||
all.keySet().forEach(key -> ThreadLocalUtil.put(key, all.get(key))); |
||||
if (mdcMap != null && !mdcMap.isEmpty()) { |
||||
MDC.setContextMap(mdcMap); |
||||
} |
||||
RequestContextHolder.setRequestAttributes(context); |
||||
// 未当前的异步线程绑定租户ID 和切换数据源
|
||||
log.info(">>>> 异步线程创建,绑定租户数据源 {}",tenantId); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
runnable.run(); |
||||
} finally { |
||||
RequestContextHolder.resetRequestAttributes(); |
||||
all.clear(); |
||||
if (mdcMap != null) { |
||||
mdcMap.clear(); |
||||
} |
||||
ThreadLocalUtil.clear(); |
||||
MDC.clear(); |
||||
DynamicDataSourceContextHolder.poll(); |
||||
} |
||||
}; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package com.logpm.factorydata.oupai.config; |
||||
|
||||
|
||||
import com.logpm.factorydata.oupai.pros.FactoryDataProperties; |
||||
import org.mybatis.spring.annotation.MapperScan; |
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.cloud.openfeign.EnableFeignClients; |
||||
import org.springframework.context.annotation.ComponentScan; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* 配置feign、mybatis包名、properties |
||||
* |
||||
* @author chaos |
||||
*/ |
||||
@Configuration(proxyBeanMethods = false) |
||||
@ComponentScan({"org.springblade", "com.logpm"}) |
||||
@EnableFeignClients({"org.springblade", "com.logpm"}) |
||||
@MapperScan({"org.springblade.**.mapper.**", "com.logpm.**.mapper.**"}) |
||||
@EnableConfigurationProperties(FactoryDataProperties.class) |
||||
public class FactoryDataOloConfiguration { |
||||
|
||||
|
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.logpm.factorydata.oupai.config; |
||||
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory; |
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
@Configuration |
||||
public class RabbitConfig { |
||||
|
||||
@Bean |
||||
public RabbitTemplate rabbitTemplate(ConnectionFactory factory, CustomMessageConverter converter) { |
||||
RabbitTemplate template = new RabbitTemplate(factory); |
||||
template.setMessageConverter(converter); |
||||
return template; |
||||
} |
||||
} |
@ -0,0 +1,130 @@
|
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package com.logpm.factorydata.oupai.dto; |
||||
|
||||
import lombok.Data; |
||||
import org.springblade.core.tool.utils.StringUtil; |
||||
|
||||
import javax.validation.constraints.NotEmpty; |
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* OrderStatus |
||||
* |
||||
* @author zhy |
||||
* @since 2023-06-12 |
||||
*/ |
||||
@Data |
||||
public class OrderStatusDTO implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
@NotEmpty(message = "派车单号不能为空") |
||||
private String dispatchNumber;//派车单号
|
||||
|
||||
@NotEmpty(message = "客户订单号不能为空") |
||||
private String orderNo;//客户订单号
|
||||
|
||||
@NotEmpty(message = "工厂ID不能为空") |
||||
private String plantId;//工厂ID
|
||||
|
||||
@NotEmpty(message = "物流单号不能为空") |
||||
private String logiBillNo;//物流单号
|
||||
|
||||
@NotEmpty(message = "包件码不能为空") |
||||
private String unitNo;//包件码
|
||||
|
||||
@NotEmpty(message = "操作时间不能为空") |
||||
private String operationTime;//操作时间
|
||||
|
||||
@NotEmpty(message = "当前仓库不能为空") |
||||
private String currentWarehouse;//当前仓库
|
||||
|
||||
@NotEmpty(message = "目的仓库不能为空") |
||||
private String destinationWarehouse;//目的仓库
|
||||
|
||||
|
||||
@NotEmpty(message = "当前仓库不能为空") |
||||
//当前仓库名称
|
||||
private String currentWarehouseName; |
||||
|
||||
@NotEmpty(message = "目的仓库不能为空") |
||||
//目的仓库名称
|
||||
private String destinationWarehouseName; |
||||
|
||||
|
||||
@NotEmpty(message = "状态不能为空") |
||||
private String status;//状态
|
||||
|
||||
@NotEmpty(message = "送货任务ID不能为空") |
||||
private String distributionContactId; |
||||
|
||||
@NotEmpty(message = "托盘id") |
||||
private Integer trayId; |
||||
|
||||
@NotEmpty(message = "托盘编码") |
||||
private String trayNo; |
||||
|
||||
@NotEmpty(message = "操作人名称") |
||||
private String username; |
||||
|
||||
@NotEmpty(message = "品牌") |
||||
private String brandName; |
||||
|
||||
@NotEmpty(message = "来源 汇通 桃源 世平") |
||||
private String sourceName; |
||||
|
||||
|
||||
/** |
||||
* 验证参数是否都存在 |
||||
* @return |
||||
*/ |
||||
public boolean verifyData(){ |
||||
if(StringUtil.isBlank(dispatchNumber)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(orderNo)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(plantId)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(logiBillNo)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(unitNo)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(operationTime)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(currentWarehouse)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(destinationWarehouse)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(status)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(distributionContactId)){ |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,50 @@
|
||||
package com.logpm.factorydata.oupai.enums; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 工厂节点枚举 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-20 15:19 |
||||
*/ |
||||
@Getter |
||||
public enum FactoryNodeEnums { |
||||
|
||||
/** |
||||
* 始发仓入库 |
||||
*/ |
||||
INITIAL_WAREHOUSE_ENTRY(101020, "1", 1), |
||||
/** 卸车入库 */ |
||||
UNLOAD_INCOMING_WAREHOUSE(105040, "4", 1), |
||||
; |
||||
|
||||
private Integer code; |
||||
private String text; |
||||
private Integer mustPush; |
||||
|
||||
FactoryNodeEnums(Integer code, String text, Integer mustPush) { |
||||
this.code = code; |
||||
this.text = text; |
||||
this.mustPush = mustPush; |
||||
} |
||||
|
||||
/** |
||||
* 获取所有必推节点的编码 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static List<Integer> getMustPushCode() { |
||||
List<Integer> list = new ArrayList<>(); |
||||
for (FactoryNodeEnums value : FactoryNodeEnums.values()) { |
||||
if (value.getMustPush() == 1) { |
||||
list.add(value.getCode()); |
||||
} |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,62 @@
|
||||
package com.logpm.factorydata.oupai.enums; |
||||
|
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import lombok.Getter; |
||||
import org.springblade.common.constant.WorkNodeEnums; |
||||
|
||||
/** |
||||
* 系统和工厂节点映射枚举 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-20 15:19 |
||||
*/ |
||||
@Getter |
||||
public enum NodeMappingEnums { |
||||
|
||||
/** |
||||
* 始发仓入库 |
||||
*/ |
||||
INITIAL_WAREHOUSE_ENTRY(FactoryNodeEnums.INITIAL_WAREHOUSE_ENTRY, WorkNodeEnums.INITIAL_WAREHOUSE_ENTRY, 1), |
||||
/** |
||||
* 卸车入库 |
||||
*/ |
||||
UNLOAD_INCOMING_WAREHOUSE(FactoryNodeEnums.UNLOAD_INCOMING_WAREHOUSE, WorkNodeEnums.UNLOAD_INCOMING_WAREHOUSE, 1); |
||||
|
||||
/** |
||||
* 系统作业节点 |
||||
*/ |
||||
private WorkNodeEnums workNodeEnums; |
||||
/** |
||||
* 工厂作业节点 |
||||
*/ |
||||
private FactoryNodeEnums factoryNodeEnums; |
||||
/** |
||||
* 状态码 |
||||
* 存在我们系统同一个作业节点对应工厂多个节点的情况,通过状态码区分 |
||||
*/ |
||||
private Integer status; |
||||
|
||||
NodeMappingEnums(FactoryNodeEnums factoryNodeEnums, WorkNodeEnums workNodeEnums, Integer status) { |
||||
this.workNodeEnums = workNodeEnums; |
||||
this.factoryNodeEnums = factoryNodeEnums; |
||||
this.status = status; |
||||
} |
||||
|
||||
public static FactoryNodeEnums getFactoryByNodeAndStatus(WorkNodeEnums workNodeEnums) { |
||||
return getFactoryByNodeAndStatus(workNodeEnums, 1); |
||||
} |
||||
|
||||
public static FactoryNodeEnums getFactoryByNodeAndStatus(WorkNodeEnums workNodeEnums, Integer status) { |
||||
NodeMappingEnums[] values = values(); |
||||
for (NodeMappingEnums value : values) { |
||||
WorkNodeEnums workNodeEnums1 = value.getWorkNodeEnums(); |
||||
Integer status1 = value.getStatus(); |
||||
FactoryNodeEnums factoryNodeEnums = value.getFactoryNodeEnums(); |
||||
if (ObjectUtil.equal(workNodeEnums1, workNodeEnums) && ObjectUtil.equal(status1, status)) { |
||||
return factoryNodeEnums; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,34 @@
|
||||
package com.logpm.factorydata.oupai.enums; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 作业节点枚举 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-20 15:19 |
||||
*/ |
||||
@Getter |
||||
public enum NodeNeedEnums implements Serializable { |
||||
|
||||
/** |
||||
* 始发仓入库 |
||||
*/ |
||||
INITIAL_WAREHOUSE_ENTRY(101020, "始发仓入库"), |
||||
/** |
||||
* 卸车入库 |
||||
*/ |
||||
UNLOAD_INCOMING_WAREHOUSE(105040, "卸车入库"), |
||||
; |
||||
|
||||
private Integer code; |
||||
private String value; |
||||
|
||||
NodeNeedEnums(Integer code, String value) { |
||||
this.code = code; |
||||
this.value = value; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,99 @@
|
||||
package com.logpm.factorydata.oupai.interceptor; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.extern.log4j.Log4j2; |
||||
import org.springblade.common.cache.CacheNames; |
||||
import org.springblade.common.component.MockLoginService; |
||||
import org.springblade.common.exception.CustomerException; |
||||
import org.springblade.common.wrapper.CustomHttpServletRequestWrapper; |
||||
import org.springblade.core.redis.cache.BladeRedis; |
||||
import org.springblade.core.redis.lock.LockType; |
||||
import org.springblade.core.redis.lock.RedisLockClient; |
||||
import org.springblade.core.tool.api.R; |
||||
import org.springblade.core.tool.utils.ThreadLocalUtil; |
||||
import org.springframework.core.env.Environment; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.io.PrintWriter; |
||||
import java.util.Objects; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
@Log4j2 |
||||
@AllArgsConstructor |
||||
public class LocalServerLoginAccountsInterceptor extends HandlerInterceptorAdapter { |
||||
|
||||
private final BladeRedis bladeRedis; |
||||
private final Environment environment; |
||||
private final RedisLockClient redisLockClient; |
||||
private final MockLoginService mockLoginService; |
||||
@Override |
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws CustomerException { |
||||
|
||||
|
||||
try { |
||||
CustomHttpServletRequestWrapper wrappedRequest = new CustomHttpServletRequestWrapper(request); |
||||
String account ="shujutongbu"; |
||||
String tenantId ="627683"; |
||||
String key =CacheNames.LOCAL_SERVER_USER+tenantId+":"+account; |
||||
String lockKey =key+":lock"; |
||||
JSONObject data =bladeRedis.get(key); |
||||
if(Objects.isNull(data)){ |
||||
boolean flag = redisLockClient.tryLock(lockKey, LockType.FAIR, 5000, 10000, TimeUnit.MILLISECONDS); |
||||
if(flag){ |
||||
data =bladeRedis.get(key); |
||||
if(Objects.isNull(data)){ |
||||
data = mockLoginService.mockToken(tenantId,account); |
||||
bladeRedis.setEx(key,data,2591990L); |
||||
redisLockClient.unLock(lockKey, LockType.FAIR); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 修改或添加header
|
||||
|
||||
// 发送登录请求
|
||||
log.info("##########preHandle: request={}", request); |
||||
|
||||
wrappedRequest.addHeader("Blade-Auth", "bearer "+data.getString("access_token")); |
||||
HttpHeaders httpHeaders = new HttpHeaders(); |
||||
httpHeaders.add("Blade-Auth","bearer "+data.get("access_token") ); |
||||
httpHeaders.add( "Authorization", "Basic bG9jYWw6bG9jYWxfc2VjcmV0"); |
||||
ThreadLocalUtil.put("bladeContext", httpHeaders); |
||||
|
||||
|
||||
// 用包装后的request替换原始request
|
||||
request = wrappedRequest; |
||||
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); |
||||
return true; |
||||
} catch (Exception e) { |
||||
returnJson(response, JSONObject.toJSONString(R.fail(500, "服务异常,请联系管理员"))); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private void returnJson(HttpServletResponse response, String json) { |
||||
PrintWriter writer = null; |
||||
response.setCharacterEncoding("UTF-8"); |
||||
response.setContentType("application/json"); |
||||
try { |
||||
writer = response.getWriter(); |
||||
writer.print(json); |
||||
|
||||
} catch (IOException e) { |
||||
System.out.println(e.getMessage()); |
||||
} finally { |
||||
if (writer != null) { |
||||
writer.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,60 @@
|
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package com.logpm.factorydata.oupai.launcher; |
||||
|
||||
import org.springblade.core.auto.service.AutoService; |
||||
import org.springblade.core.launch.constant.NacosConstant; |
||||
import org.springblade.core.launch.service.LauncherService; |
||||
import org.springblade.core.launch.utils.PropsUtil; |
||||
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
/** |
||||
* 启动参数拓展 |
||||
* |
||||
* @author Chill |
||||
*/ |
||||
@AutoService(LauncherService.class) |
||||
public class FactoryDataBaseLauncherServiceImpl implements LauncherService { |
||||
|
||||
@Override |
||||
public void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev) { |
||||
Properties props = System.getProperties(); |
||||
// 开启多数据源
|
||||
PropsUtil.setProperty(props, "spring.datasource.dynamic.enabled", "true"); |
||||
// 指定注册配置信息
|
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].data-id", NacosConstant.dataId(appName, profile)); |
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].group", NacosConstant.NACOS_CONFIG_GROUP); |
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].refresh", NacosConstant.NACOS_CONFIG_REFRESH); |
||||
// 指定注册IP
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.ip", "127.0.0.1");
|
||||
// 指定注册端口
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.port", "8200");
|
||||
// 自定义命名空间
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.config.namespace", LauncherConstant.NACOS_NAMESPACE);
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.namespace", LauncherConstant.NACOS_NAMESPACE);
|
||||
// 自定义分组
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.config.group", NacosConstant.NACOS_CONFIG_GROUP);
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.group", NacosConstant.NACOS_CONFIG_GROUP);
|
||||
} |
||||
|
||||
@Override |
||||
public int getOrder() { |
||||
return 20; |
||||
} |
||||
} |
@ -0,0 +1,129 @@
|
||||
package com.logpm.factorydata.oupai.mq; |
||||
|
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.EnumUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import cn.hutool.http.HttpUtil; |
||||
import cn.hutool.json.JSONObject; |
||||
import cn.hutool.json.JSONUtil; |
||||
import com.logpm.factorydata.feign.IFactoryDataClient; |
||||
import com.logpm.factorydata.oupai.dto.OrderStatusDTO; |
||||
import com.logpm.factorydata.oupai.enums.FactoryNodeEnums; |
||||
import com.logpm.factorydata.oupai.enums.NodeMappingEnums; |
||||
import com.logpm.factorydata.oupai.enums.NodeNeedEnums; |
||||
import com.logpm.factorydata.oupai.pros.OupaiProperties; |
||||
import com.logpm.factorydata.vo.PushData; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springblade.common.constant.WorkNodeEnums; |
||||
import org.springblade.common.constant.factorydata.FactoryDataConstants; |
||||
import org.springframework.amqp.core.ExchangeTypes; |
||||
import org.springframework.amqp.rabbit.annotation.Exchange; |
||||
import org.springframework.amqp.rabbit.annotation.Queue; |
||||
import org.springframework.amqp.rabbit.annotation.QueueBinding; |
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 监听业务系统推送给志邦的节点数据 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-18 0:02 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
@AllArgsConstructor |
||||
public class NodeDataPushListener { |
||||
|
||||
private final IFactoryDataClient factoryDataClient; |
||||
private final OupaiProperties oupaiProperties; |
||||
|
||||
@RabbitListener(bindings = @QueueBinding( |
||||
value = @Queue(name = FactoryDataConstants.Mq.Queues.OPPEIN_NODE_DATA_PUSH, durable = "true"), |
||||
exchange = @Exchange(name = FactoryDataConstants.Mq.Exchanges.NODE_DATA_PUSH_DELAYED, type = ExchangeTypes.TOPIC |
||||
, delayed = FactoryDataConstants.Mq.DELAYED), |
||||
key = FactoryDataConstants.Mq.RoutingKeys.OPPEIN_NODE_DATA_PUSH |
||||
)) |
||||
public void nodeDataPushDelayed(String msg) { |
||||
// 直接调用nodeDataPush方法处理接收到的消息
|
||||
nodeDataPush(msg); |
||||
} |
||||
|
||||
@RabbitListener(bindings = @QueueBinding( |
||||
value = @Queue(name = FactoryDataConstants.Mq.Queues.OPPEIN_NODE_DATA_PUSH, durable = "true"), |
||||
exchange = @Exchange(name = FactoryDataConstants.Mq.Exchanges.NODE_DATA_PUSH, type = ExchangeTypes.TOPIC), |
||||
key = FactoryDataConstants.Mq.RoutingKeys.OPPEIN_NODE_DATA_PUSH |
||||
)) |
||||
@Transactional(rollbackFor = Exception.class) |
||||
public void nodeDataPush(String msg) { |
||||
// {"brand":"ZBOM","node":"TRANSFER_WAREHOUSE_DEPART","operator":"","operatorTime":"","content":[{"packageCode":"1423090693445"}]}
|
||||
log.info("接收到节点数据推送:{}", msg); |
||||
// 1 校验数据
|
||||
if (checkData(msg)) { |
||||
return; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
// 节点
|
||||
String node = entries.getStr("node"); |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
FactoryNodeEnums factoryNodeEnums = NodeMappingEnums.getFactoryByNodeAndStatus(workNodeEnums); |
||||
// 2 获取业务数据
|
||||
List<PushData> content = entries.getBeanList("content", PushData.class); |
||||
// 数据按订单分组
|
||||
// 3 拿到所有必推节点的code
|
||||
List<Integer> mustPushCode = FactoryNodeEnums.getMustPushCode(); |
||||
if (CollUtil.isNotEmpty(content)) { |
||||
for (PushData pushData : content) { |
||||
OrderStatusDTO orderStatusDTO = new OrderStatusDTO(); |
||||
orderStatusDTO.setUnitNo(pushData.getPackageCode()); //包条
|
||||
orderStatusDTO.setUsername(entries.getStr("operator")); //操作人名称
|
||||
orderStatusDTO.setStatus(factoryNodeEnums.getText()); |
||||
orderStatusDTO.setBrandName("欧派"); |
||||
orderStatusDTO.setOperationTime(entries.getStr("operatorTime")); //时间
|
||||
// 发送消息
|
||||
log.info("推送工厂:{}", orderStatusDTO); |
||||
String url = oupaiProperties.getHost() + oupaiProperties.getPushNodeUrl(); |
||||
try { |
||||
if (oupaiProperties.getEnable()) { |
||||
String result = HttpUtil.post(url, JSONUtil.toJsonStr(orderStatusDTO)); |
||||
log.info("推送工厂结果:{}", result); |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("推送工厂失败:{}", e); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private boolean checkData(String msg) { |
||||
if (StrUtil.isEmpty(msg)) { |
||||
return true; |
||||
} |
||||
if (!msg.contains("brand") || !msg.contains("content") || !msg.contains("node")) { |
||||
return true; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
String node = entries.getStr("node"); |
||||
if (StrUtil.isEmpty(node)) { |
||||
return true; |
||||
} |
||||
// 不是志邦需要的节点数据直接不处理
|
||||
if (!EnumUtil.contains(NodeNeedEnums.class, node)) { |
||||
return true; |
||||
} |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
if (ObjectUtil.isEmpty(workNodeEnums)) { |
||||
return true; |
||||
} |
||||
List<JSONObject> content = entries.getBeanList("content", JSONObject.class); |
||||
if (CollUtil.isEmpty(content)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,20 @@
|
||||
package com.logpm.factorydata.oupai.pros; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
||||
/** |
||||
* FactoryProperties |
||||
* |
||||
* @author pref |
||||
*/ |
||||
@Data |
||||
@ConfigurationProperties(prefix = "logpm") |
||||
public class FactoryDataProperties { |
||||
/** |
||||
* 名称 |
||||
*/ |
||||
private String name; |
||||
|
||||
|
||||
} |
@ -0,0 +1,45 @@
|
||||
package com.logpm.factorydata.oupai.pros; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* FactoryProperties |
||||
* |
||||
* @author pref |
||||
*/ |
||||
@Data |
||||
@ConfigurationProperties(prefix = "oupai") |
||||
@Component |
||||
public class OupaiProperties { |
||||
|
||||
/** |
||||
* factory厂推送节点数据url |
||||
*/ |
||||
private String pushNodeUrl; |
||||
/** |
||||
* 是否推送工厂 |
||||
*/ |
||||
private Boolean enable = true; |
||||
/** |
||||
* factory工厂主机地址 |
||||
*/ |
||||
private String host; |
||||
/** |
||||
* 承运商编码 |
||||
*/ |
||||
private String carrierCode; |
||||
|
||||
/** |
||||
* 补节点数据时的延时时间(分钟) |
||||
*/ |
||||
private Integer delayedTime = 30; |
||||
|
||||
/** 生成老系统暂存单 */ |
||||
private Boolean oldAdvance = false; |
||||
|
||||
/** 生成新系统暂存单 */ |
||||
private Boolean newAdvance = false; |
||||
|
||||
} |
@ -0,0 +1,73 @@
|
||||
#服务器端口 |
||||
server: |
||||
port: 18970 |
||||
|
||||
#数据源配置 |
||||
#spring: |
||||
# datasource: |
||||
# url: ${blade.datasource.dev.url} |
||||
# username: ${blade.datasource.dev.username} |
||||
# password: ${blade.datasource.dev.password} |
||||
|
||||
spring: |
||||
#rabbitmq配置 |
||||
rabbitmq: |
||||
host: 192.168.2.46 |
||||
port: 5672 |
||||
username: admin |
||||
password: admin |
||||
#虚拟host 可以不设置,使用server默认host |
||||
virtual-host: / |
||||
#确认消息已发送到队列(Queue) |
||||
publisher-returns: true |
||||
publisher-confirm-type: correlated |
||||
# 手动提交消息 |
||||
listener: |
||||
simple: |
||||
acknowledge-mode: auto |
||||
default-requeue-rejected: false |
||||
retry: |
||||
enabled: true # 开启消费者失败重试 |
||||
initial-interval: 1000 # 初识的失败等待时长为1秒 |
||||
multiplier: 1 # 失败的等待时长倍数,下次等待时长 = multiplier * last-interval |
||||
max-attempts: 3 # 最大重试次数 |
||||
stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false |
||||
direct: |
||||
acknowledge-mode: manual |
||||
template: |
||||
mandatory: true |
||||
#排除DruidDataSourceAutoConfigure |
||||
autoconfigure: |
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure |
||||
datasource: |
||||
dynamic: |
||||
druid: |
||||
#通用校验配置 |
||||
validation-query: select 1 |
||||
#启用sql日志拦截器 |
||||
proxy-filters: |
||||
- sqlLogInterceptor |
||||
#设置默认的数据源或者数据源组,默认值即为master |
||||
primary: master |
||||
datasource: |
||||
master: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-oupai.master.url} |
||||
username: ${blade.datasource.factorydata-oupai.master.username} |
||||
password: ${blade.datasource.factorydata-oupai.master.password} |
||||
627683: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-oupai.627683.url} |
||||
username: ${blade.datasource.factorydata-oupai.627683.username} |
||||
password: ${blade.datasource.factorydata-oupai.627683.password} |
||||
blade: |
||||
data-scope: |
||||
enabled: false |
@ -0,0 +1,47 @@
|
||||
#服务器端口 |
||||
server: |
||||
port: 18970 |
||||
|
||||
#数据源配置 |
||||
#spring: |
||||
# datasource: |
||||
# url: ${blade.datasource.dev.url} |
||||
# username: ${blade.datasource.dev.username} |
||||
# password: ${blade.datasource.dev.password} |
||||
|
||||
spring: |
||||
#排除DruidDataSourceAutoConfigure |
||||
autoconfigure: |
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure |
||||
datasource: |
||||
dynamic: |
||||
druid: |
||||
#通用校验配置 |
||||
validation-query: select 1 |
||||
#启用sql日志拦截器 |
||||
proxy-filters: |
||||
- sqlLogInterceptor |
||||
#设置默认的数据源或者数据源组,默认值即为master |
||||
primary: master |
||||
datasource: |
||||
master: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-oupai.master.url} |
||||
username: ${blade.datasource.factorydata-oupai.master.username} |
||||
password: ${blade.datasource.factorydata-oupai.master.password} |
||||
627683: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-oupai.627683.url} |
||||
username: ${blade.datasource.factorydata-oupai.627683.username} |
||||
password: ${blade.datasource.factorydata-oupai.627683.password} |
||||
blade: |
||||
data-scope: |
||||
enabled: false |
@ -0,0 +1,73 @@
|
||||
#服务器端口 |
||||
server: |
||||
port: 18970 |
||||
|
||||
#数据源配置 |
||||
#spring: |
||||
# datasource: |
||||
# url: ${blade.datasource.dev.url} |
||||
# username: ${blade.datasource.dev.username} |
||||
# password: ${blade.datasource.dev.password} |
||||
|
||||
spring: |
||||
#rabbitmq配置 |
||||
rabbitmq: |
||||
host: 192.168.2.110 |
||||
port: 5672 |
||||
username: admin |
||||
password: Slwk@123654 |
||||
#虚拟host 可以不设置,使用server默认host |
||||
virtual-host: / |
||||
#确认消息已发送到队列(Queue) |
||||
publisher-returns: true |
||||
publisher-confirm-type: correlated |
||||
# 手动提交消息 |
||||
listener: |
||||
simple: |
||||
acknowledge-mode: auto |
||||
default-requeue-rejected: false |
||||
retry: |
||||
enabled: true # 开启消费者失败重试 |
||||
initial-interval: 1000 # 初识的失败等待时长为1秒 |
||||
multiplier: 1 # 失败的等待时长倍数,下次等待时长 = multiplier * last-interval |
||||
max-attempts: 3 # 最大重试次数 |
||||
stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false |
||||
direct: |
||||
acknowledge-mode: manual |
||||
template: |
||||
mandatory: true |
||||
#排除DruidDataSourceAutoConfigure |
||||
autoconfigure: |
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure |
||||
datasource: |
||||
dynamic: |
||||
druid: |
||||
#通用校验配置 |
||||
validation-query: select 1 |
||||
#启用sql日志拦截器 |
||||
proxy-filters: |
||||
- sqlLogInterceptor |
||||
#设置默认的数据源或者数据源组,默认值即为master |
||||
primary: master |
||||
datasource: |
||||
master: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-oupai.master.url} |
||||
username: ${blade.datasource.factorydata-oupai.master.username} |
||||
password: ${blade.datasource.factorydata-oupai.master.password} |
||||
627683: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-oupai.627683.url} |
||||
username: ${blade.datasource.factorydata-oupai.627683.username} |
||||
password: ${blade.datasource.factorydata-oupai.627683.password} |
||||
blade: |
||||
data-scope: |
||||
enabled: false |
@ -0,0 +1,19 @@
|
||||
#mybatis-plus配置 |
||||
mybatis-plus: |
||||
mapper-locations: classpath:com/logpm/**/mapper/*Mapper.xml |
||||
#实体扫描,多个package用逗号或者分号分隔 |
||||
typeAliasesPackage: com.logpm.**.entity |
||||
|
||||
#swagger扫描路径配置 |
||||
swagger: |
||||
base-packages: |
||||
- org.springblade |
||||
- com.logpm |
||||
|
||||
logging: |
||||
config: classpath:logback.xml |
||||
|
||||
spring: |
||||
main: |
||||
allow-circular-references: true |
||||
|
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<configuration scan="false" debug="false"> |
||||
|
||||
<contextName>logback</contextName> |
||||
<property name="log.path" value="./data/logpm-basic/logs/logs.log"/> |
||||
|
||||
<!-- 彩色日志依赖的渲染类 --> |
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> |
||||
<conversionRule conversionWord="wex" |
||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> |
||||
<conversionRule conversionWord="wEx" |
||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> |
||||
<!-- 彩色日志格式 --> |
||||
<property name="CONSOLE_LOG_PATTERN" |
||||
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> |
||||
<!-- 控制台输出 --> |
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern> |
||||
<charset>utf8</charset> |
||||
</encoder> |
||||
</appender> |
||||
|
||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
<file>${log.path}</file> |
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
||||
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern> |
||||
</rollingPolicy> |
||||
<encoder> |
||||
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n |
||||
</pattern> |
||||
</encoder> |
||||
</appender> |
||||
|
||||
<root level="info"> |
||||
<appender-ref ref="console"/> |
||||
<appender-ref ref="file"/> |
||||
</root> |
||||
|
||||
</configuration> |
@ -0,0 +1,14 @@
|
||||
FROM 192.168.2.110:7777/hwy/hwy_base:v1.0 |
||||
|
||||
MAINTAINER h5u@163.com |
||||
|
||||
RUN mkdir -p /logpm/logpm-factory-data-pan |
||||
|
||||
WORKDIR /logpm/logpm-factory-data-pan |
||||
|
||||
EXPOSE 18990 |
||||
|
||||
ADD ./target/logpm-factory-data-pan.jar ./app.jar |
||||
|
||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar","-Xms128m","-Xmx512m", "app.jar"] |
||||
CMD ["--spring.profiles.active=test"] |
@ -0,0 +1,89 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-factory-data</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
</parent> |
||||
<artifactId>logpm-factory-data-pan</artifactId> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>8</maven.compiler.source> |
||||
<maven.compiler.target>8</maven.compiler.target> |
||||
</properties> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-core-boot</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-core-auto</artifactId> |
||||
<scope>provided</scope> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-amqp</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-factory-data-api</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-starter-swagger</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-trunkline-api</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>logpm-factory-data-base-api</artifactId> |
||||
<version>${bladex.project.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-starter-oss</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>io.minio</groupId> |
||||
<artifactId>minio</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springblade</groupId> |
||||
<artifactId>blade-resource-api</artifactId> |
||||
<version>3.2.0.RELEASE</version> |
||||
<scope>compile</scope> |
||||
</dependency> |
||||
|
||||
</dependencies> |
||||
|
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>com.spotify</groupId> |
||||
<artifactId>dockerfile-maven-plugin</artifactId> |
||||
<configuration> |
||||
<username>${docker.username}</username> |
||||
<password>${docker.password}</password> |
||||
<repository>${docker.registry.url}/${docker.namespace}/${project.artifactId}</repository> |
||||
<tag>${project.version}</tag> |
||||
<useMavenSettingsForAuth>true</useMavenSettingsForAuth> |
||||
<buildArgs> |
||||
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> |
||||
</buildArgs> |
||||
<skip>false</skip> |
||||
</configuration> |
||||
</plugin> |
||||
<plugin> |
||||
<groupId>org.apache.maven.plugins</groupId> |
||||
<artifactId>maven-antrun-plugin</artifactId> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
</project> |
@ -0,0 +1,20 @@
|
||||
package com.logpm.factorydata; |
||||
|
||||
import org.springblade.common.constant.ModuleNameConstant; |
||||
import org.springblade.core.cloud.client.BladeCloudApplication; |
||||
import org.springblade.core.launch.BladeApplication; |
||||
|
||||
/** |
||||
* 皮阿诺工厂数据启动类 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-4-26 |
||||
*/ |
||||
@BladeCloudApplication |
||||
public class FactoryDataPanApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
BladeApplication.run(ModuleNameConstant.LOGPM_FACTORY_DATA_PAN_NAME, FactoryDataPanApplication.class, args); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,50 @@
|
||||
package com.logpm.factorydata.pan.aspect; |
||||
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.reflect.MethodSignature; |
||||
import org.springblade.common.annotations.LogpmAsync; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springframework.core.annotation.Order; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.lang.reflect.Method; |
||||
|
||||
@Aspect |
||||
@Component |
||||
@Slf4j |
||||
@Order(-1) |
||||
public class AsyncAnnotationAspect { |
||||
|
||||
/** |
||||
* 定义一个切点,匹配所有带有@LogpmAsync("asyncExecutor")注解的方法。 |
||||
* 注意:实际上Spring Framework自带对@LogpmAsync("asyncExecutor")的处理,直接这样配置可能会导致预期之外的行为。 |
||||
*/ |
||||
//@Around("@annotation(org.springblade.common.annotations.LogpmAsync)")
|
||||
public Object logAroundAsyncMethods(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
||||
Method method = signature.getMethod(); |
||||
|
||||
LogpmAsync myAsync = method.getAnnotation(LogpmAsync.class); |
||||
String annotationValue = myAsync.value(); |
||||
log.info(">>>>>>>>>>>>>>>>>> annotationValue={}",annotationValue); |
||||
|
||||
log.info("@LogpmAsync注解的值为asyncExecutor,进行数据源切换 "); |
||||
|
||||
// 在方法执行前的操作
|
||||
String tenantId = AuthUtil.getTenantId(); |
||||
log.info(">> tenandId {} ",tenantId); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
|
||||
// 执行原方法
|
||||
Object result = joinPoint.proceed(); |
||||
|
||||
// 在方法执行后的操作
|
||||
DynamicDataSourceContextHolder.poll(); |
||||
return result; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,48 @@
|
||||
package com.logpm.factorydata.pan.aspect; |
||||
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.Around; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Aspect |
||||
@Component |
||||
@Slf4j |
||||
public class RabbitAnnotationAspect { |
||||
|
||||
|
||||
/** |
||||
* 该方法为一个切面,用于对标记了@RabbitListener注解的方法进行增强,主要增加了日志记录和数据源上下文处理的功能。 |
||||
* |
||||
* @param joinPoint 切面的连接点,表示当前被拦截的方法。 |
||||
* @return 返回被拦截方法的执行结果。 |
||||
* @throws Throwable 如果执行过程中发生异常,则抛出。 |
||||
*/ |
||||
@Around("@annotation(org.springframework.amqp.rabbit.annotation.RabbitListener)") |
||||
public Object rabbitMethods(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
// 在方法执行前,获取当前租户ID并设置到数据源上下文中
|
||||
String tenantId = AuthUtil.getTenantId(); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
// 执行原方法
|
||||
Object result = joinPoint.proceed(); |
||||
// 在方法执行后,从数据源上下文中移除租户ID
|
||||
DynamicDataSourceContextHolder.poll(); |
||||
return result; |
||||
} |
||||
|
||||
@Around("@annotation(org.springframework.amqp.rabbit.annotation.RabbitHandler)") |
||||
public Object rabbitHandlerMethods(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
// 在方法执行前,获取当前租户ID并设置到数据源上下文中
|
||||
String tenantId = AuthUtil.getTenantId(); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
// 执行原方法
|
||||
Object result = joinPoint.proceed(); |
||||
// 在方法执行后,从数据源上下文中移除租户ID
|
||||
DynamicDataSourceContextHolder.poll(); |
||||
return result; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,161 @@
|
||||
package com.logpm.factorydata.pan.config; |
||||
|
||||
import cn.hutool.core.util.StrUtil; |
||||
import cn.hutool.json.JSONUtil; |
||||
import org.springblade.core.secure.BladeUser; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springblade.core.tool.utils.ThreadLocalUtil; |
||||
import org.springframework.amqp.core.Message; |
||||
import org.springframework.amqp.core.MessageProperties; |
||||
import org.springframework.amqp.support.converter.AllowedListDeserializingMessageConverter; |
||||
import org.springframework.amqp.support.converter.MessageConversionException; |
||||
import org.springframework.amqp.utils.SerializationUtils; |
||||
import org.springframework.beans.factory.BeanClassLoaderAware; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.remoting.rmi.CodebaseAwareObjectInputStream; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.util.ClassUtils; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectStreamClass; |
||||
import java.io.Serializable; |
||||
import java.io.UnsupportedEncodingException; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @author zhaoqiaobo |
||||
* @create 2024-05-08 |
||||
*/ |
||||
@Component |
||||
public class CustomMessageConverter extends AllowedListDeserializingMessageConverter implements BeanClassLoaderAware { |
||||
|
||||
private volatile String defaultCharset = "UTF-8"; |
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); |
||||
private String codebaseUrl; |
||||
|
||||
@Deprecated |
||||
public void setCodebaseUrl(String codebaseUrl) { |
||||
this.codebaseUrl = codebaseUrl; |
||||
} |
||||
|
||||
@Override |
||||
public Object fromMessage(Message message) throws MessageConversionException { |
||||
Object content = null; |
||||
MessageProperties properties = message.getMessageProperties(); |
||||
if (properties != null) { |
||||
String contentType = properties.getContentType(); |
||||
if (contentType != null && contentType.startsWith("text")) { |
||||
String encoding = properties.getContentEncoding(); |
||||
if (encoding == null) { |
||||
encoding = "UTF-8"; |
||||
} |
||||
|
||||
try { |
||||
content = new String(message.getBody(), encoding); |
||||
} catch (UnsupportedEncodingException var8) { |
||||
throw new MessageConversionException("failed to convert text-based Message content", var8); |
||||
} |
||||
} else if (contentType != null && contentType.equals("application/x-java-serialized-object")) { |
||||
try { |
||||
content = SerializationUtils.deserialize(this.createObjectInputStream(new ByteArrayInputStream(message.getBody()), this.codebaseUrl)); |
||||
} catch (IllegalArgumentException | IllegalStateException | IOException var7) { |
||||
throw new MessageConversionException("failed to convert serialized Message content", var7); |
||||
} |
||||
} |
||||
} |
||||
Map<String, Object> headers = properties.getHeaders(); |
||||
HttpHeaders httpHeaders = new HttpHeaders(); |
||||
for (Map.Entry<String, Object> entry : headers.entrySet()) { |
||||
if (StrUtil.equals("Blade-Auth", entry.getKey()) |
||||
|| StrUtil.equals("Authorization", entry.getKey()) |
||||
|| StrUtil.equals("blade-auth", entry.getKey()) |
||||
|| StrUtil.equals("authorization", entry.getKey())) { |
||||
List value = (List) entry.getValue(); |
||||
for (Object o : value) { |
||||
httpHeaders.add(entry.getKey(), String.valueOf(o)); |
||||
} |
||||
} |
||||
} |
||||
ThreadLocalUtil.put("bladeContext", httpHeaders); |
||||
Object bladeUser = headers.get("bladeUser"); |
||||
MockHttpServletRequest request = new MockHttpServletRequest(); |
||||
BladeUser bladeUser1 = JSONUtil.toBean(bladeUser.toString(), BladeUser.class); |
||||
request.setAttribute("_BLADE_USER_REQUEST_ATTR_", bladeUser1); |
||||
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); |
||||
if (content == null) { |
||||
content = message.getBody(); |
||||
} |
||||
return content; |
||||
} |
||||
|
||||
@Override |
||||
protected Message createMessage(Object object, MessageProperties messageProperties) throws MessageConversionException { |
||||
byte[] bytes = null; |
||||
if (object instanceof byte[]) { |
||||
bytes = (byte[]) object; |
||||
messageProperties.setContentType("application/octet-stream"); |
||||
} else if (object instanceof String) { |
||||
try { |
||||
bytes = ((String) object).getBytes(this.defaultCharset); |
||||
} catch (UnsupportedEncodingException var6) { |
||||
throw new MessageConversionException("failed to convert to Message content", var6); |
||||
} |
||||
|
||||
messageProperties.setContentType("text/plain"); |
||||
messageProperties.setContentEncoding(this.defaultCharset); |
||||
} else if (object instanceof Serializable) { |
||||
try { |
||||
bytes = SerializationUtils.serialize(object); |
||||
} catch (IllegalArgumentException var5) { |
||||
throw new MessageConversionException("failed to convert to serialized Message content", var5); |
||||
} |
||||
|
||||
messageProperties.setContentType("application/x-java-serialized-object"); |
||||
} |
||||
HttpHeaders headers = (HttpHeaders) ThreadLocalUtil.get("bladeContext"); |
||||
if (headers != null && !headers.isEmpty()) { |
||||
headers.forEach((key, values) -> { |
||||
values.forEach((value) -> { |
||||
messageProperties.setHeader(key, new String[]{value}); |
||||
}); |
||||
}); |
||||
} |
||||
BladeUser user = AuthUtil.getUser(); |
||||
BladeUser bladeUser = new BladeUser(); |
||||
bladeUser.setTenantId(user.getTenantId()); |
||||
bladeUser.setUserId(user.getUserId()); |
||||
bladeUser.setAccount(user.getAccount()); |
||||
bladeUser.setRoleId(user.getRoleId()); |
||||
messageProperties.setHeader("bladeUser", JSONUtil.toJsonStr(bladeUser)); |
||||
|
||||
if (bytes != null) { |
||||
messageProperties.setContentLength((long) bytes.length); |
||||
return new Message(bytes, messageProperties); |
||||
} else { |
||||
throw new IllegalArgumentException(this.getClass().getSimpleName() + " only supports String, byte[] and Serializable payloads, received: " + object.getClass().getName()); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void setBeanClassLoader(ClassLoader classLoader) { |
||||
this.beanClassLoader = beanClassLoader; |
||||
} |
||||
|
||||
protected ObjectInputStream createObjectInputStream(InputStream is, String codebaseUrl) throws IOException { |
||||
return new CodebaseAwareObjectInputStream(is, this.beanClassLoader, codebaseUrl) { |
||||
@Override |
||||
protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { |
||||
Class<?> clazz = super.resolveClass(classDesc); |
||||
CustomMessageConverter.this.checkAllowedList(clazz); |
||||
return clazz; |
||||
} |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,85 @@
|
||||
package com.logpm.factorydata.pan.config; |
||||
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.slf4j.MDC; |
||||
import org.springblade.core.secure.utils.AuthUtil; |
||||
import org.springblade.core.tool.utils.ThreadLocalUtil; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.core.task.TaskDecorator; |
||||
import org.springframework.scheduling.annotation.EnableAsync; |
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; |
||||
import org.springframework.web.context.request.RequestAttributes; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
|
||||
import javax.annotation.Nonnull; |
||||
import java.util.Map; |
||||
import java.util.concurrent.Executor; |
||||
import java.util.concurrent.ThreadPoolExecutor; |
||||
|
||||
@Configuration |
||||
@Slf4j |
||||
@EnableAsync |
||||
public class ExecutorConfig { |
||||
|
||||
@Bean |
||||
public Executor asyncExecutor() { |
||||
log.info("start async executor"); |
||||
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); |
||||
// 配置核心线程数
|
||||
threadPoolTaskExecutor.setCorePoolSize(10); |
||||
// 配置最大线程数
|
||||
threadPoolTaskExecutor.setMaxPoolSize(20); |
||||
// 配置队列大小
|
||||
threadPoolTaskExecutor.setQueueCapacity(50); |
||||
// 配置线程池中线程的名称前缀
|
||||
threadPoolTaskExecutor.setThreadNamePrefix("ASYNC_THREAD_"); |
||||
// HelloWorldServiceImpl rejection-policy: 当pool已经达到max size时,如何处理新任务:
|
||||
// CallerRunsPolicy: 不在新线程中执行任务,而是由调用者所在的线程来执行;
|
||||
// AbortPolicy: 拒绝执行新任务,并抛出RejectedExecutionException异常;
|
||||
// DiscardPolicy:丢弃当前将要加入队列的任务;
|
||||
// DiscardOldestPolicy:丢弃任务队列中最旧的任务;
|
||||
threadPoolTaskExecutor.setRejectedExecutionHandler( |
||||
new ThreadPoolExecutor.CallerRunsPolicy() |
||||
); |
||||
threadPoolTaskExecutor.setTaskDecorator(new ContextCopyingDecorator()); |
||||
threadPoolTaskExecutor.initialize(); |
||||
return threadPoolTaskExecutor; |
||||
} |
||||
|
||||
|
||||
static class ContextCopyingDecorator implements TaskDecorator { |
||||
@Nonnull |
||||
@Override |
||||
public Runnable decorate(@Nonnull Runnable runnable) { |
||||
RequestAttributes context = RequestContextHolder.currentRequestAttributes(); |
||||
String tenantId = AuthUtil.getTenantId(); |
||||
Map<String, Object> all = ThreadLocalUtil.getAll(); |
||||
Map<String, String> mdcMap = MDC.getCopyOfContextMap(); |
||||
return () -> { |
||||
try { |
||||
all.keySet().forEach(key -> ThreadLocalUtil.put(key, all.get(key))); |
||||
if (mdcMap != null && !mdcMap.isEmpty()) { |
||||
MDC.setContextMap(mdcMap); |
||||
} |
||||
RequestContextHolder.setRequestAttributes(context); |
||||
// 未当前的异步线程绑定租户ID 和切换数据源
|
||||
log.info(">>>> 异步线程创建,绑定租户数据源 {}",tenantId); |
||||
DynamicDataSourceContextHolder.push(tenantId); |
||||
runnable.run(); |
||||
} finally { |
||||
RequestContextHolder.resetRequestAttributes(); |
||||
all.clear(); |
||||
if (mdcMap != null) { |
||||
mdcMap.clear(); |
||||
} |
||||
ThreadLocalUtil.clear(); |
||||
MDC.clear(); |
||||
DynamicDataSourceContextHolder.poll(); |
||||
} |
||||
}; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package com.logpm.factorydata.pan.config; |
||||
|
||||
|
||||
import com.logpm.factorydata.pan.pros.FactoryDataProperties; |
||||
import org.mybatis.spring.annotation.MapperScan; |
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
||||
import org.springframework.cloud.openfeign.EnableFeignClients; |
||||
import org.springframework.context.annotation.ComponentScan; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* 配置feign、mybatis包名、properties |
||||
* |
||||
* @author chaos |
||||
*/ |
||||
@Configuration(proxyBeanMethods = false) |
||||
@ComponentScan({"org.springblade", "com.logpm"}) |
||||
@EnableFeignClients({"org.springblade", "com.logpm"}) |
||||
@MapperScan({"org.springblade.**.mapper.**", "com.logpm.**.mapper.**"}) |
||||
@EnableConfigurationProperties(FactoryDataProperties.class) |
||||
public class FactoryDataOloConfiguration { |
||||
|
||||
|
||||
} |
@ -0,0 +1,17 @@
|
||||
package com.logpm.factorydata.pan.config; |
||||
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory; |
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
@Configuration |
||||
public class RabbitConfig { |
||||
|
||||
@Bean |
||||
public RabbitTemplate rabbitTemplate(ConnectionFactory factory, CustomMessageConverter converter) { |
||||
RabbitTemplate template = new RabbitTemplate(factory); |
||||
template.setMessageConverter(converter); |
||||
return template; |
||||
} |
||||
} |
@ -0,0 +1,130 @@
|
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package com.logpm.factorydata.pan.dto; |
||||
|
||||
import lombok.Data; |
||||
import org.springblade.core.tool.utils.StringUtil; |
||||
|
||||
import javax.validation.constraints.NotEmpty; |
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* OrderStatus |
||||
* |
||||
* @author zhy |
||||
* @since 2023-06-12 |
||||
*/ |
||||
@Data |
||||
public class OrderStatusDTO implements Serializable { |
||||
private static final long serialVersionUID = 1L; |
||||
|
||||
@NotEmpty(message = "派车单号不能为空") |
||||
private String dispatchNumber;//派车单号
|
||||
|
||||
@NotEmpty(message = "客户订单号不能为空") |
||||
private String orderNo;//客户订单号
|
||||
|
||||
@NotEmpty(message = "工厂ID不能为空") |
||||
private String plantId;//工厂ID
|
||||
|
||||
@NotEmpty(message = "物流单号不能为空") |
||||
private String logiBillNo;//物流单号
|
||||
|
||||
@NotEmpty(message = "包件码不能为空") |
||||
private String unitNo;//包件码
|
||||
|
||||
@NotEmpty(message = "操作时间不能为空") |
||||
private String operationTime;//操作时间
|
||||
|
||||
@NotEmpty(message = "当前仓库不能为空") |
||||
private String currentWarehouse;//当前仓库
|
||||
|
||||
@NotEmpty(message = "目的仓库不能为空") |
||||
private String destinationWarehouse;//目的仓库
|
||||
|
||||
|
||||
@NotEmpty(message = "当前仓库不能为空") |
||||
//当前仓库名称
|
||||
private String currentWarehouseName; |
||||
|
||||
@NotEmpty(message = "目的仓库不能为空") |
||||
//目的仓库名称
|
||||
private String destinationWarehouseName; |
||||
|
||||
|
||||
@NotEmpty(message = "状态不能为空") |
||||
private String status;//状态
|
||||
|
||||
@NotEmpty(message = "送货任务ID不能为空") |
||||
private String distributionContactId; |
||||
|
||||
@NotEmpty(message = "托盘id") |
||||
private Integer trayId; |
||||
|
||||
@NotEmpty(message = "托盘编码") |
||||
private String trayNo; |
||||
|
||||
@NotEmpty(message = "操作人名称") |
||||
private String username; |
||||
|
||||
@NotEmpty(message = "品牌") |
||||
private String brandName; |
||||
|
||||
@NotEmpty(message = "来源 汇通 桃源 世平") |
||||
private String sourceName; |
||||
|
||||
|
||||
/** |
||||
* 验证参数是否都存在 |
||||
* @return |
||||
*/ |
||||
public boolean verifyData(){ |
||||
if(StringUtil.isBlank(dispatchNumber)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(orderNo)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(plantId)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(logiBillNo)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(unitNo)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(operationTime)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(currentWarehouse)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(destinationWarehouse)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(status)){ |
||||
return false; |
||||
} |
||||
if(StringUtil.isBlank(distributionContactId)){ |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,49 @@
|
||||
package com.logpm.factorydata.pan.enums; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 工厂节点枚举 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-20 15:19 |
||||
*/ |
||||
@Getter |
||||
public enum FactoryNodeEnums { |
||||
|
||||
/** 卸车入库 */ |
||||
UNLOAD_INCOMING_WAREHOUSE(105040, "4", 1), |
||||
/** 干线装车 */ |
||||
INITIAL_WAREHOUSE_LOADING(105040, "3", 1), |
||||
CLERK_REVIEW(303010, "7", 1), |
||||
; |
||||
|
||||
private Integer code; |
||||
private String text; |
||||
private Integer mustPush; |
||||
|
||||
FactoryNodeEnums(Integer code, String text, Integer mustPush) { |
||||
this.code = code; |
||||
this.text = text; |
||||
this.mustPush = mustPush; |
||||
} |
||||
|
||||
/** |
||||
* 获取所有必推节点的编码 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static List<Integer> getMustPushCode() { |
||||
List<Integer> list = new ArrayList<>(); |
||||
for (FactoryNodeEnums value : FactoryNodeEnums.values()) { |
||||
if (value.getMustPush() == 1) { |
||||
list.add(value.getCode()); |
||||
} |
||||
} |
||||
return list; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,63 @@
|
||||
package com.logpm.factorydata.pan.enums; |
||||
|
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import lombok.Getter; |
||||
import org.springblade.common.constant.WorkNodeEnums; |
||||
|
||||
/** |
||||
* 系统和工厂节点映射枚举 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-20 15:19 |
||||
*/ |
||||
@Getter |
||||
public enum NodeMappingEnums { |
||||
|
||||
/** |
||||
* 卸车入库 |
||||
*/ |
||||
UNLOAD_INCOMING_WAREHOUSE(FactoryNodeEnums.UNLOAD_INCOMING_WAREHOUSE, WorkNodeEnums.UNLOAD_INCOMING_WAREHOUSE, 1), |
||||
CLERK_REVIEW(FactoryNodeEnums.CLERK_REVIEW, WorkNodeEnums.CLERK_REVIEW, 1), |
||||
/** 干线装车 */ |
||||
INITIAL_WAREHOUSE_LOADING(FactoryNodeEnums.INITIAL_WAREHOUSE_LOADING, WorkNodeEnums.INITIAL_WAREHOUSE_LOADING, 1) |
||||
|
||||
; |
||||
|
||||
/** |
||||
* 系统作业节点 |
||||
*/ |
||||
private WorkNodeEnums workNodeEnums; |
||||
/** |
||||
* 工厂作业节点 |
||||
*/ |
||||
private FactoryNodeEnums factoryNodeEnums; |
||||
/** |
||||
* 状态码 |
||||
* 存在我们系统同一个作业节点对应工厂多个节点的情况,通过状态码区分 |
||||
*/ |
||||
private Integer status; |
||||
|
||||
NodeMappingEnums(FactoryNodeEnums factoryNodeEnums, WorkNodeEnums workNodeEnums, Integer status) { |
||||
this.workNodeEnums = workNodeEnums; |
||||
this.factoryNodeEnums = factoryNodeEnums; |
||||
this.status = status; |
||||
} |
||||
|
||||
public static FactoryNodeEnums getFactoryByNodeAndStatus(WorkNodeEnums workNodeEnums) { |
||||
return getFactoryByNodeAndStatus(workNodeEnums, 1); |
||||
} |
||||
|
||||
public static FactoryNodeEnums getFactoryByNodeAndStatus(WorkNodeEnums workNodeEnums, Integer status) { |
||||
NodeMappingEnums[] values = values(); |
||||
for (NodeMappingEnums value : values) { |
||||
WorkNodeEnums workNodeEnums1 = value.getWorkNodeEnums(); |
||||
Integer status1 = value.getStatus(); |
||||
FactoryNodeEnums factoryNodeEnums = value.getFactoryNodeEnums(); |
||||
if (ObjectUtil.equal(workNodeEnums1, workNodeEnums) && ObjectUtil.equal(status1, status)) { |
||||
return factoryNodeEnums; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,33 @@
|
||||
package com.logpm.factorydata.pan.enums; |
||||
|
||||
import lombok.Getter; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 作业节点枚举 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-20 15:19 |
||||
*/ |
||||
@Getter |
||||
public enum NodeNeedEnums implements Serializable { |
||||
|
||||
/** |
||||
* 卸车入库 |
||||
*/ |
||||
UNLOAD_INCOMING_WAREHOUSE(105040, "卸车入库"), |
||||
/** 干线装车 */ |
||||
INITIAL_WAREHOUSE_LOADING(103020, "装车"), |
||||
CLERK_REVIEW(303010, "文员复核"), |
||||
; |
||||
|
||||
private Integer code; |
||||
private String value; |
||||
|
||||
NodeNeedEnums(Integer code, String value) { |
||||
this.code = code; |
||||
this.value = value; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,99 @@
|
||||
package com.logpm.factorydata.pan.interceptor; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.extern.log4j.Log4j2; |
||||
import org.springblade.common.cache.CacheNames; |
||||
import org.springblade.common.component.MockLoginService; |
||||
import org.springblade.common.exception.CustomerException; |
||||
import org.springblade.common.wrapper.CustomHttpServletRequestWrapper; |
||||
import org.springblade.core.redis.cache.BladeRedis; |
||||
import org.springblade.core.redis.lock.LockType; |
||||
import org.springblade.core.redis.lock.RedisLockClient; |
||||
import org.springblade.core.tool.api.R; |
||||
import org.springblade.core.tool.utils.ThreadLocalUtil; |
||||
import org.springframework.core.env.Environment; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.io.PrintWriter; |
||||
import java.util.Objects; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
@Log4j2 |
||||
@AllArgsConstructor |
||||
public class LocalServerLoginAccountsInterceptor extends HandlerInterceptorAdapter { |
||||
|
||||
private final BladeRedis bladeRedis; |
||||
private final Environment environment; |
||||
private final RedisLockClient redisLockClient; |
||||
private final MockLoginService mockLoginService; |
||||
@Override |
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws CustomerException { |
||||
|
||||
|
||||
try { |
||||
CustomHttpServletRequestWrapper wrappedRequest = new CustomHttpServletRequestWrapper(request); |
||||
String account ="shujutongbu"; |
||||
String tenantId ="627683"; |
||||
String key =CacheNames.LOCAL_SERVER_USER+tenantId+":"+account; |
||||
String lockKey =key+":lock"; |
||||
JSONObject data =bladeRedis.get(key); |
||||
if(Objects.isNull(data)){ |
||||
boolean flag = redisLockClient.tryLock(lockKey, LockType.FAIR, 5000, 10000, TimeUnit.MILLISECONDS); |
||||
if(flag){ |
||||
data =bladeRedis.get(key); |
||||
if(Objects.isNull(data)){ |
||||
data = mockLoginService.mockToken(tenantId,account); |
||||
bladeRedis.setEx(key,data,2591990L); |
||||
redisLockClient.unLock(lockKey, LockType.FAIR); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 修改或添加header
|
||||
|
||||
// 发送登录请求
|
||||
log.info("##########preHandle: request={}", request); |
||||
|
||||
wrappedRequest.addHeader("Blade-Auth", "bearer "+data.getString("access_token")); |
||||
HttpHeaders httpHeaders = new HttpHeaders(); |
||||
httpHeaders.add("Blade-Auth","bearer "+data.get("access_token") ); |
||||
httpHeaders.add( "Authorization", "Basic bG9jYWw6bG9jYWxfc2VjcmV0"); |
||||
ThreadLocalUtil.put("bladeContext", httpHeaders); |
||||
|
||||
|
||||
// 用包装后的request替换原始request
|
||||
request = wrappedRequest; |
||||
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); |
||||
return true; |
||||
} catch (Exception e) { |
||||
returnJson(response, JSONObject.toJSONString(R.fail(500, "服务异常,请联系管理员"))); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private void returnJson(HttpServletResponse response, String json) { |
||||
PrintWriter writer = null; |
||||
response.setCharacterEncoding("UTF-8"); |
||||
response.setContentType("application/json"); |
||||
try { |
||||
writer = response.getWriter(); |
||||
writer.print(json); |
||||
|
||||
} catch (IOException e) { |
||||
System.out.println(e.getMessage()); |
||||
} finally { |
||||
if (writer != null) { |
||||
writer.close(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,60 @@
|
||||
/* |
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* |
||||
* Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* Neither the name of the dreamlu.net developer nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* Author: Chill 庄骞 (smallchill@163.com) |
||||
*/ |
||||
package com.logpm.factorydata.pan.launcher; |
||||
|
||||
import org.springblade.core.auto.service.AutoService; |
||||
import org.springblade.core.launch.constant.NacosConstant; |
||||
import org.springblade.core.launch.service.LauncherService; |
||||
import org.springblade.core.launch.utils.PropsUtil; |
||||
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||
|
||||
import java.util.Properties; |
||||
|
||||
/** |
||||
* 启动参数拓展 |
||||
* |
||||
* @author Chill |
||||
*/ |
||||
@AutoService(LauncherService.class) |
||||
public class FactoryDataBaseLauncherServiceImpl implements LauncherService { |
||||
|
||||
@Override |
||||
public void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev) { |
||||
Properties props = System.getProperties(); |
||||
// 开启多数据源
|
||||
PropsUtil.setProperty(props, "spring.datasource.dynamic.enabled", "true"); |
||||
// 指定注册配置信息
|
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].data-id", NacosConstant.dataId(appName, profile)); |
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].group", NacosConstant.NACOS_CONFIG_GROUP); |
||||
PropsUtil.setProperty(props, "spring.cloud.nacos.config.extension-configs[0].refresh", NacosConstant.NACOS_CONFIG_REFRESH); |
||||
// 指定注册IP
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.ip", "127.0.0.1");
|
||||
// 指定注册端口
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.port", "8200");
|
||||
// 自定义命名空间
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.config.namespace", LauncherConstant.NACOS_NAMESPACE);
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.namespace", LauncherConstant.NACOS_NAMESPACE);
|
||||
// 自定义分组
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.config.group", NacosConstant.NACOS_CONFIG_GROUP);
|
||||
// PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.group", NacosConstant.NACOS_CONFIG_GROUP);
|
||||
} |
||||
|
||||
@Override |
||||
public int getOrder() { |
||||
return 20; |
||||
} |
||||
} |
@ -0,0 +1,146 @@
|
||||
package com.logpm.factorydata.pan.mq; |
||||
|
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.util.EnumUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import cn.hutool.http.HttpUtil; |
||||
import cn.hutool.json.JSONObject; |
||||
import cn.hutool.json.JSONUtil; |
||||
import com.logpm.factorydata.feign.IFactoryDataClient; |
||||
import com.logpm.factorydata.pan.dto.OrderStatusDTO; |
||||
import com.logpm.factorydata.pan.enums.FactoryNodeEnums; |
||||
import com.logpm.factorydata.pan.enums.NodeMappingEnums; |
||||
import com.logpm.factorydata.pan.enums.NodeNeedEnums; |
||||
import com.logpm.factorydata.pan.pros.PanProperties; |
||||
import com.logpm.factorydata.vo.PushData; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springblade.common.constant.WorkNodeEnums; |
||||
import org.springblade.common.constant.factorydata.FactoryDataConstants; |
||||
import org.springframework.amqp.core.ExchangeTypes; |
||||
import org.springframework.amqp.rabbit.annotation.Exchange; |
||||
import org.springframework.amqp.rabbit.annotation.Queue; |
||||
import org.springframework.amqp.rabbit.annotation.QueueBinding; |
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener; |
||||
import org.springframework.stereotype.Component; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* 监听业务系统推送给志邦的节点数据 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-18 0:02 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
@AllArgsConstructor |
||||
public class NodeDataPushListener { |
||||
|
||||
private final IFactoryDataClient factoryDataClient; |
||||
private final PanProperties panProperties; |
||||
|
||||
@RabbitListener(bindings = @QueueBinding( |
||||
value = @Queue(name = FactoryDataConstants.Mq.Queues.PIANO_NODE_DATA_PUSH, durable = "true"), |
||||
exchange = @Exchange(name = FactoryDataConstants.Mq.Exchanges.NODE_DATA_PUSH_DELAYED, type = ExchangeTypes.TOPIC |
||||
, delayed = FactoryDataConstants.Mq.DELAYED), |
||||
key = FactoryDataConstants.Mq.RoutingKeys.PIANO_NODE_DATA_PUSH |
||||
)) |
||||
public void nodeDataPushDelayed(String msg) { |
||||
// 直接调用nodeDataPush方法处理接收到的消息
|
||||
nodeDataPush(msg); |
||||
} |
||||
|
||||
@RabbitListener(bindings = @QueueBinding( |
||||
value = @Queue(name = FactoryDataConstants.Mq.Queues.PIANO_NODE_DATA_PUSH, durable = "true"), |
||||
exchange = @Exchange(name = FactoryDataConstants.Mq.Exchanges.NODE_DATA_PUSH, type = ExchangeTypes.TOPIC), |
||||
key = FactoryDataConstants.Mq.RoutingKeys.PIANO_NODE_DATA_PUSH |
||||
)) |
||||
@Transactional(rollbackFor = Exception.class) |
||||
public void nodeDataPush(String msg) { |
||||
// {"brand":"PAN","node":"INITIAL_WAREHOUSE_LOADING","operator":"admin","operatorTime":"2024-10-18 15:02:20","address":"在【广州仓】出库","main":"{\"waybillNumber\":\"GZ20241000001\",\"trainNumber\":\"GZGX20241000001\"}","content":[{"packageCode":"PXB240929000976","orderCode":"2090032408030LQZI04","warehouseName":"广州仓","destinationWarehouse":"龙泉仓"}]}
|
||||
log.info("接收到节点数据推送:{}", msg); |
||||
// 1 校验数据
|
||||
if (checkData(msg)) { |
||||
return; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
// 节点
|
||||
String node = entries.getStr("node"); |
||||
String main = entries.getStr("main"); |
||||
JSONObject mainJson = new JSONObject(); |
||||
if(StrUtil.isNotEmpty(main)){ |
||||
mainJson = JSONUtil.parseObj(main); |
||||
} |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
FactoryNodeEnums factoryNodeEnums = NodeMappingEnums.getFactoryByNodeAndStatus(workNodeEnums); |
||||
// 2 获取业务数据
|
||||
List<PushData> content = entries.getBeanList("content", PushData.class); |
||||
// 数据按订单分组
|
||||
// 3 拿到所有必推节点的code
|
||||
List<Integer> mustPushCode = FactoryNodeEnums.getMustPushCode(); |
||||
if (CollUtil.isNotEmpty(content)) { |
||||
for (PushData pushData : content) { |
||||
OrderStatusDTO orderStatusDTO = new OrderStatusDTO(); |
||||
// 通过包件id 查询包件
|
||||
orderStatusDTO.setUnitNo(pushData.getPackageCode()); |
||||
orderStatusDTO.setOrderNo(pushData.getOrderCode()); |
||||
orderStatusDTO.setStatus(factoryNodeEnums.getText()); |
||||
orderStatusDTO.setOperationTime(entries.getStr("operatorTime")); |
||||
orderStatusDTO.setCurrentWarehouseName(pushData.getWarehouseName()); |
||||
orderStatusDTO.setUsername(entries.getStr("operator")); |
||||
orderStatusDTO.setBrandName("皮阿诺"); |
||||
// dispatchNumber 车次号
|
||||
orderStatusDTO.setDispatchNumber(mainJson.getStr("trainNumber")); |
||||
// 配送单号
|
||||
orderStatusDTO.setDistributionContactId(mainJson.getStr("distributionContactId")); |
||||
// logiBillNo 运单号
|
||||
orderStatusDTO.setLogiBillNo(mainJson.getStr("waybillNumber")); |
||||
// destinationWarehouseName 目的仓
|
||||
orderStatusDTO.setDestinationWarehouseName(pushData.getDestinationWarehouse()); |
||||
|
||||
// 发送消息
|
||||
log.info("推送工厂:{}", orderStatusDTO); |
||||
String url = panProperties.getHost() + panProperties.getPushNodeUrl(); |
||||
try { |
||||
if (panProperties.getEnable()) { |
||||
String result = HttpUtil.post(url, JSONUtil.toJsonStr(orderStatusDTO)); |
||||
log.info("推送工厂结果:{}", result); |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("推送工厂失败:{}", e); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private boolean checkData(String msg) { |
||||
if (StrUtil.isEmpty(msg)) { |
||||
return true; |
||||
} |
||||
if (!msg.contains("brand") || !msg.contains("content") || !msg.contains("node")) { |
||||
return true; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
String node = entries.getStr("node"); |
||||
if (StrUtil.isEmpty(node)) { |
||||
return true; |
||||
} |
||||
// 不是志邦需要的节点数据直接不处理
|
||||
if (!EnumUtil.contains(NodeNeedEnums.class, node)) { |
||||
return true; |
||||
} |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
if (ObjectUtil.isEmpty(workNodeEnums)) { |
||||
return true; |
||||
} |
||||
List<JSONObject> content = entries.getBeanList("content", JSONObject.class); |
||||
if (CollUtil.isEmpty(content)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,20 @@
|
||||
package com.logpm.factorydata.pan.pros; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
||||
/** |
||||
* FactoryProperties |
||||
* |
||||
* @author pref |
||||
*/ |
||||
@Data |
||||
@ConfigurationProperties(prefix = "logpm") |
||||
public class FactoryDataProperties { |
||||
/** |
||||
* 名称 |
||||
*/ |
||||
private String name; |
||||
|
||||
|
||||
} |
@ -0,0 +1,45 @@
|
||||
package com.logpm.factorydata.pan.pros; |
||||
|
||||
import lombok.Data; |
||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* FactoryProperties |
||||
* |
||||
* @author pref |
||||
*/ |
||||
@Data |
||||
@ConfigurationProperties(prefix = "pan") |
||||
@Component |
||||
public class PanProperties { |
||||
|
||||
/** |
||||
* factory厂推送节点数据url |
||||
*/ |
||||
private String pushNodeUrl; |
||||
/** |
||||
* 是否推送工厂 |
||||
*/ |
||||
private Boolean enable = true; |
||||
/** |
||||
* factory工厂主机地址 |
||||
*/ |
||||
private String host; |
||||
/** |
||||
* 承运商编码 |
||||
*/ |
||||
private String carrierCode; |
||||
|
||||
/** |
||||
* 补节点数据时的延时时间(分钟) |
||||
*/ |
||||
private Integer delayedTime = 30; |
||||
|
||||
/** 生成老系统暂存单 */ |
||||
private Boolean oldAdvance = false; |
||||
|
||||
/** 生成新系统暂存单 */ |
||||
private Boolean newAdvance = false; |
||||
|
||||
} |
@ -0,0 +1,73 @@
|
||||
#服务器端口 |
||||
server: |
||||
port: 18990 |
||||
|
||||
#数据源配置 |
||||
#spring: |
||||
# datasource: |
||||
# url: ${blade.datasource.dev.url} |
||||
# username: ${blade.datasource.dev.username} |
||||
# password: ${blade.datasource.dev.password} |
||||
|
||||
spring: |
||||
#rabbitmq配置 |
||||
rabbitmq: |
||||
host: 192.168.2.46 |
||||
port: 5672 |
||||
username: admin |
||||
password: admin |
||||
#虚拟host 可以不设置,使用server默认host |
||||
virtual-host: / |
||||
#确认消息已发送到队列(Queue) |
||||
publisher-returns: true |
||||
publisher-confirm-type: correlated |
||||
# 手动提交消息 |
||||
listener: |
||||
simple: |
||||
acknowledge-mode: auto |
||||
default-requeue-rejected: false |
||||
retry: |
||||
enabled: true # 开启消费者失败重试 |
||||
initial-interval: 1000 # 初识的失败等待时长为1秒 |
||||
multiplier: 1 # 失败的等待时长倍数,下次等待时长 = multiplier * last-interval |
||||
max-attempts: 3 # 最大重试次数 |
||||
stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false |
||||
direct: |
||||
acknowledge-mode: manual |
||||
template: |
||||
mandatory: true |
||||
#排除DruidDataSourceAutoConfigure |
||||
autoconfigure: |
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure |
||||
datasource: |
||||
dynamic: |
||||
druid: |
||||
#通用校验配置 |
||||
validation-query: select 1 |
||||
#启用sql日志拦截器 |
||||
proxy-filters: |
||||
- sqlLogInterceptor |
||||
#设置默认的数据源或者数据源组,默认值即为master |
||||
primary: master |
||||
datasource: |
||||
master: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-pan.master.url} |
||||
username: ${blade.datasource.factorydata-pan.master.username} |
||||
password: ${blade.datasource.factorydata-pan.master.password} |
||||
627683: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-pan.627683.url} |
||||
username: ${blade.datasource.factorydata-pan.627683.username} |
||||
password: ${blade.datasource.factorydata-pan.627683.password} |
||||
blade: |
||||
data-scope: |
||||
enabled: false |
@ -0,0 +1,47 @@
|
||||
#服务器端口 |
||||
server: |
||||
port: 18990 |
||||
|
||||
#数据源配置 |
||||
#spring: |
||||
# datasource: |
||||
# url: ${blade.datasource.dev.url} |
||||
# username: ${blade.datasource.dev.username} |
||||
# password: ${blade.datasource.dev.password} |
||||
|
||||
spring: |
||||
#排除DruidDataSourceAutoConfigure |
||||
autoconfigure: |
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure |
||||
datasource: |
||||
dynamic: |
||||
druid: |
||||
#通用校验配置 |
||||
validation-query: select 1 |
||||
#启用sql日志拦截器 |
||||
proxy-filters: |
||||
- sqlLogInterceptor |
||||
#设置默认的数据源或者数据源组,默认值即为master |
||||
primary: master |
||||
datasource: |
||||
master: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-pan.master.url} |
||||
username: ${blade.datasource.factorydata-pan.master.username} |
||||
password: ${blade.datasource.factorydata-pan.master.password} |
||||
627683: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-pan.627683.url} |
||||
username: ${blade.datasource.factorydata-pan.627683.username} |
||||
password: ${blade.datasource.factorydata-pan.627683.password} |
||||
blade: |
||||
data-scope: |
||||
enabled: false |
@ -0,0 +1,73 @@
|
||||
#服务器端口 |
||||
server: |
||||
port: 18990 |
||||
|
||||
#数据源配置 |
||||
#spring: |
||||
# datasource: |
||||
# url: ${blade.datasource.dev.url} |
||||
# username: ${blade.datasource.dev.username} |
||||
# password: ${blade.datasource.dev.password} |
||||
|
||||
spring: |
||||
#rabbitmq配置 |
||||
rabbitmq: |
||||
host: 192.168.2.110 |
||||
port: 5672 |
||||
username: admin |
||||
password: Slwk@123654 |
||||
#虚拟host 可以不设置,使用server默认host |
||||
virtual-host: / |
||||
#确认消息已发送到队列(Queue) |
||||
publisher-returns: true |
||||
publisher-confirm-type: correlated |
||||
# 手动提交消息 |
||||
listener: |
||||
simple: |
||||
acknowledge-mode: auto |
||||
default-requeue-rejected: false |
||||
retry: |
||||
enabled: true # 开启消费者失败重试 |
||||
initial-interval: 1000 # 初识的失败等待时长为1秒 |
||||
multiplier: 1 # 失败的等待时长倍数,下次等待时长 = multiplier * last-interval |
||||
max-attempts: 3 # 最大重试次数 |
||||
stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false |
||||
direct: |
||||
acknowledge-mode: manual |
||||
template: |
||||
mandatory: true |
||||
#排除DruidDataSourceAutoConfigure |
||||
autoconfigure: |
||||
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure |
||||
datasource: |
||||
dynamic: |
||||
druid: |
||||
#通用校验配置 |
||||
validation-query: select 1 |
||||
#启用sql日志拦截器 |
||||
proxy-filters: |
||||
- sqlLogInterceptor |
||||
#设置默认的数据源或者数据源组,默认值即为master |
||||
primary: master |
||||
datasource: |
||||
master: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-pan.master.url} |
||||
username: ${blade.datasource.factorydata-pan.master.username} |
||||
password: ${blade.datasource.factorydata-pan.master.password} |
||||
627683: |
||||
druid: |
||||
#独立校验配置 |
||||
validation-query: select 1 |
||||
#oracle校验 |
||||
#validation-query: select 1 from dual |
||||
url: ${blade.datasource.factorydata-pan.627683.url} |
||||
username: ${blade.datasource.factorydata-pan.627683.username} |
||||
password: ${blade.datasource.factorydata-pan.627683.password} |
||||
blade: |
||||
data-scope: |
||||
enabled: false |
@ -0,0 +1,19 @@
|
||||
#mybatis-plus配置 |
||||
mybatis-plus: |
||||
mapper-locations: classpath:com/logpm/**/mapper/*Mapper.xml |
||||
#实体扫描,多个package用逗号或者分号分隔 |
||||
typeAliasesPackage: com.logpm.**.entity |
||||
|
||||
#swagger扫描路径配置 |
||||
swagger: |
||||
base-packages: |
||||
- org.springblade |
||||
- com.logpm |
||||
|
||||
logging: |
||||
config: classpath:logback.xml |
||||
|
||||
spring: |
||||
main: |
||||
allow-circular-references: true |
||||
|
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<configuration scan="false" debug="false"> |
||||
|
||||
<contextName>logback</contextName> |
||||
<property name="log.path" value="./data/logpm-basic/logs/logs.log"/> |
||||
|
||||
<!-- 彩色日志依赖的渲染类 --> |
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/> |
||||
<conversionRule conversionWord="wex" |
||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> |
||||
<conversionRule conversionWord="wEx" |
||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> |
||||
<!-- 彩色日志格式 --> |
||||
<property name="CONSOLE_LOG_PATTERN" |
||||
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> |
||||
<!-- 控制台输出 --> |
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> |
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> |
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern> |
||||
<charset>utf8</charset> |
||||
</encoder> |
||||
</appender> |
||||
|
||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
<file>${log.path}</file> |
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
||||
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern> |
||||
</rollingPolicy> |
||||
<encoder> |
||||
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n |
||||
</pattern> |
||||
</encoder> |
||||
</appender> |
||||
|
||||
<root level="info"> |
||||
<appender-ref ref="console"/> |
||||
<appender-ref ref="file"/> |
||||
</root> |
||||
|
||||
</configuration> |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue