diff --git a/cf-dependencies/pom.xml b/cf-dependencies/pom.xml
index 78ac4e6b5..2e2cfe5bc 100644
--- a/cf-dependencies/pom.xml
+++ b/cf-dependencies/pom.xml
@@ -170,6 +170,11 @@
cf-spring-boot-starter-biz-error-code
${revision}
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-id
+ ${revision}
+
com.cf.imes
cf-spring-boot-starter-biz-ip
diff --git a/cf-framework/cf-spring-boot-starter-biz-operatelog/src/main/java/com/cf/imes/framework/operatelog/core/aop/OperateLogAspect.java b/cf-framework/cf-spring-boot-starter-biz-operatelog/src/main/java/com/cf/imes/framework/operatelog/core/aop/OperateLogAspect.java
index 5b886bb72..175e07f12 100644
--- a/cf-framework/cf-spring-boot-starter-biz-operatelog/src/main/java/com/cf/imes/framework/operatelog/core/aop/OperateLogAspect.java
+++ b/cf-framework/cf-spring-boot-starter-biz-operatelog/src/main/java/com/cf/imes/framework/operatelog/core/aop/OperateLogAspect.java
@@ -4,6 +4,7 @@ import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.common.util.monitor.TracerUtils;
@@ -310,7 +311,9 @@ public class OperateLogAspect {
String argName = argNames[i];
Object argValue = argValues[i];
// 被忽略时,标记为 ignore 字符串,避免和 null 混在一起
- args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
+ if (ObjectUtil.isNotNull(argValue)) {
+ args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
+ }
}
return JsonUtils.toJsonString(args);
}
diff --git a/cf-framework/cf-spring-boot-starter-mq/pom.xml b/cf-framework/cf-spring-boot-starter-mq/pom.xml
index 3ced5489a..8a2f2e268 100644
--- a/cf-framework/cf-spring-boot-starter-mq/pom.xml
+++ b/cf-framework/cf-spring-boot-starter-mq/pom.xml
@@ -30,7 +30,6 @@
org.springframework.amqp
spring-rabbit
- true
org.apache.rocketmq
diff --git a/cf-framework/cf-spring-boot-starter-mq/src/main/java/com/cf/imes/framework/mq/rabbitmq/config/ChenfengRabbitMQAutoConfiguration.java b/cf-framework/cf-spring-boot-starter-mq/src/main/java/com/cf/imes/framework/mq/rabbitmq/config/ChenfengRabbitMQAutoConfiguration.java
index 62bd489cf..bf52fd5c0 100644
--- a/cf-framework/cf-spring-boot-starter-mq/src/main/java/com/cf/imes/framework/mq/rabbitmq/config/ChenfengRabbitMQAutoConfiguration.java
+++ b/cf-framework/cf-spring-boot-starter-mq/src/main/java/com/cf/imes/framework/mq/rabbitmq/config/ChenfengRabbitMQAutoConfiguration.java
@@ -1,12 +1,25 @@
package com.cf.imes.framework.mq.rabbitmq.config;
-import cn.hutool.core.util.ReflectUtil;
+import com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.amqp.utils.SerializationUtils;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.DirectExchange;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.QueueBuilder;
+import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
+import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
-import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_EXCHANGE;
+import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_QUEUE;
+import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY;
/**
* RabbitMQ 消息队列配置类
@@ -18,12 +31,75 @@ import java.lang.reflect.Field;
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
public class ChenfengRabbitMQAutoConfiguration {
- static {
- // 强制设置 SerializationUtils 的 TRUST_ALL 为 true,避免 RabbitMQ Consumer 反序列化消息报错
- // 为什么不通过设置 spring.amqp.deserialization.trust.all 呢?因为可能在 SerializationUtils static 初始化后
- Field trustAllField = ReflectUtil.getField(SerializationUtils.class, "TRUST_ALL");
- ReflectUtil.removeFinalModify(trustAllField);
- ReflectUtil.setFieldValue(SerializationUtils.class, trustAllField, true);
+ /**
+ * Jackson2JsonMessageConverter Bean:使用 jackson 序列化消息
+ */
+ @Bean
+ public MessageConverter createMessageConverter() {
+ return new Jackson2JsonMessageConverter();
+ }
+
+
+ /**
+ * 生产单导入交换机、队列、绑定声明
+ *
+ * @return
+ */
+ @Bean
+ public FanoutExchange orderImportFanoutExchange() {
+ return new FanoutExchange(RabbitMqConstants.ORDER_IMPORT_DEFAULT_EXCEL_EXCHANGE);
+ }
+
+ /**
+ * 生产单导入队列声明
+ *
+ * @return
+ */
+ @Bean
+ public Queue orderImportQueue() {
+ Map args = new HashMap<>(1);
+ // x-dead-letter-exchange 这里声明当前队列绑定的死信交换机
+ args.put("x-dead-letter-exchange", ORDER_IMPORT_DEAD_LETTER_EXCHANGE);
+ // 设置死信路由键
+ args.put("x-dead-letter-routing-key", ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY);
+ return QueueBuilder.durable(RabbitMqConstants.ORDER_IMPORT_DEFAULT_EXCEL_QUEUE).withArguments(args).build();
+ }
+
+ /**
+ * 生产单excel导入交换机声明
+ *
+ * @return
+ */
+ @Bean
+ public Binding orderImportDefaultExcelBinding() {
+ return BindingBuilder.bind(orderImportQueue()).to(orderImportFanoutExchange());
+ }
+
+ /**
+ * 生产单导入死信交换机声明
+ * @return
+ */
+ @Bean
+ public DirectExchange orderImportDeadLetterExchange(){
+ return new DirectExchange(ORDER_IMPORT_DEAD_LETTER_EXCHANGE);
+ }
+
+ /**
+ * 生产单导入死信队列声明
+ * @return
+ */
+ @Bean
+ public Queue orderImportDeadLetterQueue() {
+ return new Queue(ORDER_IMPORT_DEAD_LETTER_QUEUE);
+ }
+
+ /**
+ * 生产单导入死信队列、交换机、绑定声明
+ * @return
+ */
+ @Bean
+ public Binding deadLetterBindingA() {
+ return BindingBuilder.bind(orderImportDeadLetterQueue()).to(orderImportDeadLetterExchange()).with(ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY);
}
}
diff --git a/cf-framework/cf-spring-boot-starter-mq/src/main/java/com/cf/imes/framework/mq/rabbitmq/constant/RabbitMqConstants.java b/cf-framework/cf-spring-boot-starter-mq/src/main/java/com/cf/imes/framework/mq/rabbitmq/constant/RabbitMqConstants.java
new file mode 100644
index 000000000..f136772b3
--- /dev/null
+++ b/cf-framework/cf-spring-boot-starter-mq/src/main/java/com/cf/imes/framework/mq/rabbitmq/constant/RabbitMqConstants.java
@@ -0,0 +1,34 @@
+package com.cf.imes.framework.mq.rabbitmq.constant;
+
+/**
+ * rabbitmq常量
+ *
+ * @author Gqr
+ * @since 2025/1/6 11:15
+ */
+public class RabbitMqConstants {
+ /**
+ * 生产单导入交换机
+ */
+ public static final String ORDER_IMPORT_DEFAULT_EXCEL_EXCHANGE = "order_import_default_excel_exchange";
+
+ /**
+ * 生产单导入队列
+ */
+ public static final String ORDER_IMPORT_DEFAULT_EXCEL_QUEUE = "order_import_default_excel_queue";
+
+ /**
+ * 生产单导入死信交换机
+ */
+ public static final String ORDER_IMPORT_DEAD_LETTER_EXCHANGE = "order_import_dead_letter_exchange";
+
+ /**
+ * 生产单导入死信队列
+ */
+ public static final String ORDER_IMPORT_DEAD_LETTER_QUEUE = "order_import_dead_letter_queue";
+
+ /**
+ * 生产单导入死信路由键
+ */
+ public static final String ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY = "order_import_dead_letter_routing_key";
+}
diff --git a/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/config/ChenfengMybatisAutoConfiguration.java b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/config/ChenfengMybatisAutoConfiguration.java
index 1cca14d3b..ed03d7794 100644
--- a/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/config/ChenfengMybatisAutoConfiguration.java
+++ b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/config/ChenfengMybatisAutoConfiguration.java
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.*;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import com.cf.imes.framework.mybatis.core.injector.MybatisPlusInjector;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
@@ -75,4 +76,9 @@ public class ChenfengMybatisAutoConfiguration {
throw new IllegalArgumentException("DbType为空");
}
+ @Bean
+ public MybatisPlusInjector mybatisPlusInjector() {
+ return new MybatisPlusInjector();
+ }
+
}
diff --git a/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/injector/BaseBatchMapper.java b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/injector/BaseBatchMapper.java
new file mode 100644
index 000000000..e3d3c4f49
--- /dev/null
+++ b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/injector/BaseBatchMapper.java
@@ -0,0 +1,22 @@
+package com.cf.imes.framework.mybatis.core.injector;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+/**
+ * 基础批量映射器
+ *
+ * @author Gqr
+ * @since 2025/1/14 14:54
+ */
+public interface BaseBatchMapper extends BaseMapper {
+ /**
+ * 批量插入
+ * 区别于mybatisplus的saveBatch:拼接(a,b,c,...)value(aval,bval,cval,...)而不是把多个insert一次性提交到数据库
+ *
+ * @param entityList
+ * @return
+ */
+ int insertBatchSomeColumn(List entityList);
+}
diff --git a/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/injector/MybatisPlusInjector.java b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/injector/MybatisPlusInjector.java
new file mode 100644
index 000000000..bedeee563
--- /dev/null
+++ b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/injector/MybatisPlusInjector.java
@@ -0,0 +1,22 @@
+package com.cf.imes.framework.mybatis.core.injector;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.core.injector.AbstractMethod;
+import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
+import com.baomidou.mybatisplus.core.metadata.TableInfo;
+import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
+
+import java.util.List;
+
+/**
+ * @author Gqr
+ * @since 2025/1/14 14:46
+ */
+public class MybatisPlusInjector extends DefaultSqlInjector {
+ @Override
+ public List getMethodList(Class> mapperClass, TableInfo tableInfo) {
+ List methodList = super.getMethodList(mapperClass, tableInfo);
+ methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
+ return methodList;
+ }
+}
diff --git a/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/query/LambdaUpdateWrapperX.java b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/query/LambdaUpdateWrapperX.java
new file mode 100644
index 000000000..c11464947
--- /dev/null
+++ b/cf-framework/cf-spring-boot-starter-mybatis/src/main/java/com/cf/imes/framework/mybatis/core/query/LambdaUpdateWrapperX.java
@@ -0,0 +1,26 @@
+package com.cf.imes.framework.mybatis.core.query;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+
+/**
+ * LambdaUpdateWrapper拓展
+ *
+ * @author Gqr
+ * @since 2025/1/22 15:58
+ */
+public class LambdaUpdateWrapperX extends LambdaUpdateWrapper {
+ public LambdaUpdateWrapperX eqIfPresent(SFunction column, Object val) {
+ if (ObjectUtil.isNotEmpty(val)) {
+ return (LambdaUpdateWrapperX) super.eq(column, val);
+ }
+ return this;
+ }
+
+ @Override
+ public LambdaUpdateWrapperX eq(SFunction column, Object val) {
+ super.eq(column, val);
+ return this;
+ }
+}
diff --git a/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheAutoConfiguration.java b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheAutoConfiguration.java
index 9980e3891..861118c27 100644
--- a/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheAutoConfiguration.java
+++ b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheAutoConfiguration.java
@@ -82,7 +82,7 @@ public class ChenfengCacheAutoConfiguration {
}
@Bean
- public RedisLockUtil lockUtil(ChenfengCacheProperties chenfengCacheProperties, RedissonClient client) {
- return new RedisLockUtil(chenfengCacheProperties, client);
+ public RedisLockUtil lockUtil(ChenfengCacheProperties chenfengCacheProperties, RedissonClient client, RedisTemplate redisTemplate) {
+ return new RedisLockUtil(chenfengCacheProperties, client, redisTemplate);
}
}
diff --git a/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheProperties.java b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheProperties.java
index f5539a74f..1d3527e30 100644
--- a/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheProperties.java
+++ b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/config/ChenfengCacheProperties.java
@@ -34,5 +34,5 @@ public class ChenfengCacheProperties {
* 等待获取锁的时间,单位:毫秒(ms)
* 默认0.5秒
*/
- private int lockWaitTime = 500;
+ private int lockWaitTime = 5000;
}
diff --git a/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/constants/RedisKeyConstants.java b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/constants/RedisKeyConstants.java
new file mode 100644
index 000000000..384f663c2
--- /dev/null
+++ b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/constants/RedisKeyConstants.java
@@ -0,0 +1,14 @@
+package com.cf.imes.framework.redis.constants;
+
+/**
+ * 多模块公用redis key常量
+ *
+ * @author Gqr
+ * @since 2025/1/14 15:22
+ */
+public class RedisKeyConstants {
+ /**
+ * 生产单导入
+ */
+ public static final String ORDER_IMPORT_LOCK_KEY = "order_import:%s";
+}
diff --git a/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/util/RedisLockUtil.java b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/util/RedisLockUtil.java
index 636f7d8ea..9ffb20f9c 100644
--- a/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/util/RedisLockUtil.java
+++ b/cf-framework/cf-spring-boot-starter-redis/src/main/java/com/cf/imes/framework/redis/util/RedisLockUtil.java
@@ -6,6 +6,7 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
+import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;
@@ -23,6 +24,8 @@ public class RedisLockUtil {
private RedissonClient redissonClient;
+ private RedisTemplate redisTemplate;
+
/**
* 加锁
*
@@ -63,6 +66,7 @@ public class RedisLockUtil {
/**
* 解锁
+ * 使用注意:配合以上两个redisson的lock只能在当前线程中unlock,否则失败!!!
*
* @param key rediskey
*/
@@ -74,4 +78,37 @@ public class RedisLockUtil {
log.error("[RedisLockUtil][unlock]解锁失败", e);
}
}
+
+ /**
+ * 手动set nx ex加锁
+ * 使用注意:可用于跨服务
+ *
+ * @param key
+ * @param uniqeKey 解锁的时候校验,避免其他任务误解
+ * @param timeout
+ * @return
+ */
+ public boolean lock(String key, String uniqeKey, Integer timeout) {
+ return redisTemplate.opsForValue().setIfAbsent(key, uniqeKey, timeout, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 解锁
+ * 校验唯一值后删除key
+ * 使用注意:可用于跨服务
+ *
+ * @param key
+ * @param uniqeKey 解锁时校验,避免同key下其他任务解锁到
+ */
+ public void unlock(String key, String uniqeKey) {
+ Object object = redisTemplate.opsForValue().get(key);
+ if (ObjectUtil.equal(object, uniqeKey)) {
+ Boolean delete = redisTemplate.delete(key);
+ if (delete) {
+ log.info(String.format("[RedisLockUtil][unlock][%s]解锁", key));
+ } else {
+ log.error(String.format("[RedisLockUtil][unlock][%s]解锁失败", key));
+ }
+ }
+ }
}
diff --git a/cf-framework/pom.xml b/cf-framework/pom.xml
index 12ae6eb44..4b8d6c7b3 100644
--- a/cf-framework/pom.xml
+++ b/cf-framework/pom.xml
@@ -37,6 +37,7 @@
cf-spring-boot-starter-biz-organ
cf-spring-boot-starter-biz-data-permission
cf-spring-boot-starter-biz-error-code
+ cf-spring-boot-starter-biz-id
cf-spring-boot-starter-biz-ip
cf-spring-boot-starter-flowable
diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java
index 9c02f71b3..a39359198 100644
--- a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java
+++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/ErrorCodeConstants.java
@@ -70,10 +70,24 @@ public class ErrorCodeConstants {
public static final ErrorCode API_MES_ERR = new ErrorCode(1_002_031_001, "MES接口数据出错:{}");
public static final ErrorCode CHANGE_DETAILS_ITEM_ERROR = new ErrorCode(1_002_032_001, "明细转换失败");
- // ========== 自定义板编号生成 ==========
+ // ========== 自定义板编号生成 1_002_030_ ==========
public static final ErrorCode CUSTOM_PLATENO_GENERATE_ORDERNO_RULE_NOT_SUPPORT_RESETMODE = new ErrorCode(1_002_030_001, "自定义版编号生产单序号规则中存在不支持的复位类型:{}");
public static final ErrorCode CUSTOM_PLATENO_GENERATE_BODY_RULE_NOT_SUPPORT_RESETMODE = new ErrorCode(1_002_030_002, "自定义版编号柜体序号规则中存在不支持的复位类型:{}");
public static final ErrorCode CUSTOM_PLATENO_GENERATE_PROCESSGROUP_RULE_NOT_SUPPORT_RESETMODE = new ErrorCode(1_002_030_003, "自定义版编号加工组序号规则中存在不支持的复位类型:{}");
public static final ErrorCode CUSTOM_PLATENO_GENERATE_PLATE_RULE_NOT_SUPPORT_RESETMODE = new ErrorCode(1_002_030_004, "自定义版编号板件序号规则中存在不支持的复位类型:{}");
public static final ErrorCode CUSTOM_PLATENO_GENERATE_ORG_CUSTOM_PLATENO_SEQ_MODIFY_ERROR = new ErrorCode(1_002_030_005, "保存组织下自定义板编号序号配置失败,请联系客服处理");
+
+ // ========== 生产单导入 1_002_031 ==========
+ public static final ErrorCode ORDER_IMPORT_TYPE_NOT_SUPPORT = new ErrorCode(1_002_031_001, "不支持的生产单导入类型:{}");
+ public static final ErrorCode ORDER_IMPORT_ORGAN_LOCK_ERROR = new ErrorCode(1_002_031_002, "组织下存在正在导入的生产单,请稍后再试");
+ public static final ErrorCode ORDER_IMPORT_FILE_ANALYZE_ERROR = new ErrorCode(1_002_031_003, "生产单导入文件解析失败,请检查文件类型和格式");
+ public static final ErrorCode ORDER_IMPORT_ORDER_FIELD_EMPTY = new ErrorCode(1_002_031_004, "生产单信息【{}】不能为空");
+ public static final ErrorCode ORDER_IMPORT_ORDER_FIELD_LENGTH_ERROR = new ErrorCode(1_002_031_005, "生产单信息【{}】长度不能超过【{}】个字符");
+ public static final ErrorCode ORDER_IMPORT_ORDER_FIELD_MOBILE_FORMAT_ERROR = new ErrorCode(1_002_031_006, "生产单信息【{}】手机号格式错误");
+ public static final ErrorCode ORDER_IMPORT_ORDER_FIELD_DATE_FORMAT_ERROR = new ErrorCode(1_002_031_007, "生产单信息【{}】日期格式错误");
+ public static final ErrorCode ORDER_IMPORT_ORDER_NOT_EXISTS = new ErrorCode(1_002_031_008, "生产单【{}】不存在");
+ public static final ErrorCode ORDER_IMPORT_ORDER_CUSTOMERNO_EXISTS = new ErrorCode(1_002_031_009, "{}【{}】已存在");
+ public static final ErrorCode ORDER_IMPORT_DETAIL_FIELD_EMPTY = new ErrorCode(1_002_031_010, "导入校验异常:第{}行,导入明细【{}】不能为空");
+ public static final ErrorCode ORDER_IMPORT_DETAIL_FIELD_LENGTH_ERROR = new ErrorCode(1_002_031_011, "导入校验异常:第{}行,导入明细【{}】长度不能超过【{}】个字符");
+ public static final ErrorCode ORDER_IMPORT_DETAIL_VALID_ERROR = new ErrorCode(1_002_031_012, "导入校验异常:{}");
}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportConstants.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportConstants.java
new file mode 100644
index 000000000..e3c9bb05d
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportConstants.java
@@ -0,0 +1,19 @@
+package com.cf.imes.module.executor.enums;
+
+/**
+ * 生产单导入常量
+ *
+ * @author Gqr
+ * @since 2025/1/14 16:18
+ */
+public class OrderImportConstants {
+ /**
+ * 导入商品缺省goodsid
+ */
+ public static final String DEFAULT_GOODS_ID = "no_code_1132589&";
+
+ /**
+ * 房间、柜体缺省name
+ */
+ public static final String NOT_ASSIGNED = "未命名";
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportStatusEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportStatusEnum.java
new file mode 100644
index 000000000..0e3ce3639
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportStatusEnum.java
@@ -0,0 +1,46 @@
+package com.cf.imes.module.executor.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 生产单导入状态枚举
+ *
+ * @author Gqr
+ * @since 2025/1/8 16:20
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderImportStatusEnum {
+ /**
+ * 未导入
+ */
+ IMPORT_NOT_YET(0),
+
+ /**
+ * 导入成功
+ */
+ IMPORT_SUCCESS(10),
+
+ /**
+ * 导入失败
+ */
+ IMPORT_FAIL(2);
+
+ private int status;
+
+ /**
+ * 是否匹配
+ *
+ * @param status
+ * @return
+ */
+ public static OrderImportStatusEnum match(int status) {
+ for (OrderImportStatusEnum statusEnum : OrderImportStatusEnum.values()) {
+ if (statusEnum.status == status) {
+ return statusEnum;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTaskStatusEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTaskStatusEnum.java
new file mode 100644
index 000000000..10b6c86d9
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTaskStatusEnum.java
@@ -0,0 +1,51 @@
+package com.cf.imes.module.executor.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 生产单导入任务状态枚举
+ *
+ * @author Gqr
+ * @since 2025/1/8 16:20
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderImportTaskStatusEnum {
+ /**
+ * 创建未消费
+ */
+ CREATE_NOT_CONSUME(0),
+
+ /**
+ * 创建已接收
+ */
+ CREATE_RECEIVE(10),
+
+ /**
+ * 消费成功
+ */
+ CONSUME_SUCCESS(20),
+
+ /**
+ * 消费失败
+ */
+ CONSUME_FAIL(30);
+
+ private int status;
+
+ /**
+ * 是否匹配
+ *
+ * @param status
+ * @return
+ */
+ public static OrderImportTaskStatusEnum match(int status) {
+ for (OrderImportTaskStatusEnum statusEnum : OrderImportTaskStatusEnum.values()) {
+ if (statusEnum.status == status) {
+ return statusEnum;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTmpDataTypeEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTmpDataTypeEnum.java
new file mode 100644
index 000000000..1ae1b979b
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTmpDataTypeEnum.java
@@ -0,0 +1,35 @@
+package com.cf.imes.module.executor.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 生产单导入临时表类型枚举
+ *
+ * @author Gqr
+ * @since 2025/1/8 16:20
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderImportTmpDataTypeEnum {
+ ORDER(0),
+ PLATE(1),
+ PART(2);
+
+ private int type;
+
+ /**
+ * 是否匹配
+ *
+ * @param type
+ * @return
+ */
+ public static OrderImportTmpDataTypeEnum match(int type) {
+ for (OrderImportTmpDataTypeEnum typeEnum : OrderImportTmpDataTypeEnum.values()) {
+ if (typeEnum.type == type) {
+ return typeEnum;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTypeEnum.java b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTypeEnum.java
new file mode 100644
index 000000000..1ee48f06d
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-api/src/main/java/com/cf/imes/module/executor/enums/OrderImportTypeEnum.java
@@ -0,0 +1,35 @@
+package com.cf.imes.module.executor.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 生产单导入类型枚举
+ * @author Gqr
+ * @since 2025/1/8 16:20
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderImportTypeEnum {
+ EXCEL(0),
+ JSON(1),
+ XML(2),
+ API(3);
+
+ private int type;
+
+ /**
+ * 是否匹配
+ *
+ * @param type
+ * @return
+ */
+ public static OrderImportTypeEnum match(int type) {
+ for (OrderImportTypeEnum typeEnum : OrderImportTypeEnum.values()) {
+ if (typeEnum.type == type) {
+ return typeEnum;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/pom.xml b/cf-module-prod-executor/cf-module-prod-executor-biz/pom.xml
index 8b37e6290..8878e9684 100644
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/pom.xml
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/pom.xml
@@ -182,6 +182,15 @@
com.alibaba
fastjson
+
+ com.cf.imes
+ cf-spring-boot-starter-mq
+
+
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-id
+
@@ -272,6 +281,14 @@
com.cf.imes
cf-spring-boot-starter-web
+
+ com.cf.imes
+ cf-spring-boot-starter-mq
+
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-id
+
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java
index 6cc9adec1..830cba110 100644
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/OrderController.java
@@ -393,6 +393,22 @@ public class OrderController {
}
+ @PostMapping("/import")
+ @Operation(summary = "生产单导入新增")
+ @Parameters({
+ @Parameter(name = "file", description = "文件", required = true),
+ @Parameter(name = "type", description = "文件类型", required = true),
+ @Parameter(name = "id", description = "生产单id")
+ })
+ @OperateLog(type = IMPORT)
+ @PreAuthorize("@ss.hasPermission('production:manager-list:create')")
+ public void orderImport(@RequestPart("file") MultipartFile file,
+ @RequestParam(value = "type") Integer type,
+ @RequestParam(value = "id", required = false) Long orderId) {
+ OrderImportAsyncReqVO orderImportAsyncReqVO = new OrderImportAsyncReqVO(orderId, type, null);
+ orderService.orderImportAsync(orderImportAsyncReqVO, file);
+ }
+
// 生产单详情
@GetMapping("/get-room")
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/vo/order/OrderImportAsyncReqVO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/vo/order/OrderImportAsyncReqVO.java
new file mode 100644
index 000000000..8820fb9d3
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/controller/admin/order/vo/order/OrderImportAsyncReqVO.java
@@ -0,0 +1,37 @@
+package com.cf.imes.module.executor.controller.admin.order.vo.order;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 生产单异步导入 reqVO
+ *
+ * @author Gqr
+ * @since 2025/1/8 17:05
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderImportAsyncReqVO implements Serializable {
+ @Serial
+ private static final long serialVersionUID = -1237291692917676281L;
+
+ /**
+ * 生产单id
+ */
+ Long orderId;
+
+ /**
+ * 导入类型,参考OrderImportTypeEnum
+ */
+ Integer type;
+
+ /**
+ * 外部订单号:api导入用
+ */
+ String orderNo;
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderImport/OrderImportTaskDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderImport/OrderImportTaskDO.java
new file mode 100644
index 000000000..28e857d6a
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderImport/OrderImportTaskDO.java
@@ -0,0 +1,57 @@
+package com.cf.imes.module.executor.dal.dataobject.orderImport;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 生产单导入任务
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:30
+ */
+@TableName("order_import_task")
+@KeySequence("order_import_task_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderImportTaskDO extends BaseDO {
+ /**
+ * 主键
+ */
+ @TableId
+ private Long id;
+
+ /**
+ * 组织id
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+
+ /**
+ * 导入类型,参考OrderImportTypeEnum
+ */
+ private Integer type;
+
+ /**
+ * 导入状态
+ */
+ private Integer importStatus;
+
+ /**
+ * 消费状态
+ */
+ private Integer status;
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderImport/OrderImportTempDataDO.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderImport/OrderImportTempDataDO.java
new file mode 100644
index 000000000..47e6d6e12
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/dataobject/orderImport/OrderImportTempDataDO.java
@@ -0,0 +1,188 @@
+package com.cf.imes.module.executor.dal.dataobject.orderImport;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+
+/**
+ * 生产单导入临时表
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:36
+ */
+@TableName("order_import_temp_data")
+@KeySequence("order_import_temp_data_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderImportTempDataDO {
+ /**
+ * 主键
+ */
+ @TableId
+ private Long id;
+
+ /**
+ * 组织id
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+
+ /**
+ * 导入任务id
+ */
+ private Long taskId;
+
+ /**
+ * 生产单id(补板用)
+ */
+ private Long orderId;
+
+ /**
+ * 类型
+ */
+ private Integer type;
+
+ /**
+ * 物料编码
+ */
+ private String outerGoodsId;
+
+ /**
+ * imes商品id
+ */
+ private String innerGoodsId;
+
+ /**
+ * 商品名称
+ */
+ private String goodsName;
+
+ /**
+ * 材料
+ */
+ private String material;
+
+ /**
+ * 颜色
+ */
+ private String color;
+
+ /**
+ * 纹路
+ */
+ private String wave;
+
+ /**
+ * 宽度
+ */
+ private String width;
+
+ /**
+ * 长度
+ */
+ private String height;
+
+ /**
+ * 厚度
+ */
+ private String thickness;
+
+ /**
+ * 品牌
+ */
+ private String brand;
+
+ /**
+ * 是否复合部件
+ */
+ @TableField("is_composite")
+ private String isComposite;
+
+ /**
+ * 配件主类
+ */
+ private String category;
+
+ /**
+ * 配件子类型
+ */
+ private String subType;
+
+ /**
+ * 厂家
+ */
+ private String factory;
+
+ /**
+ * 规格
+ */
+ private String spec;
+
+ /**
+ * 型号
+ */
+ private String model;
+
+ /**
+ * 单位
+ */
+ private String unit;
+
+ /**
+ * 房间名称
+ */
+ private String roomName;
+
+ /**
+ * 柜体名称
+ */
+ private String bodyName;
+
+ /**
+ * 加工组类型
+ */
+ private String groupTypeName;
+
+ /**
+ * 模块名称
+ */
+ private String groupName;
+
+ /**
+ * 创建人
+ */
+ private String creater;
+
+ /**
+ * 导入数据明细
+ */
+ private String detail;
+
+ /**
+ * 数量
+ */
+ private Double num;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+
+ /**
+ * 排序号
+ */
+ private int sort;
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderImport/OrderImportTaskMapper.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderImport/OrderImportTaskMapper.java
new file mode 100644
index 000000000..7c18d78bf
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderImport/OrderImportTaskMapper.java
@@ -0,0 +1,15 @@
+package com.cf.imes.module.executor.dal.mysql.orderImport;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cf.imes.module.executor.dal.dataobject.orderImport.OrderImportTaskDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单导入任务 Mapper
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:42
+ */
+@Mapper
+public interface OrderImportTaskMapper extends BaseMapper {
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderImport/OrderImportTempDataMapper.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderImport/OrderImportTempDataMapper.java
new file mode 100644
index 000000000..917dcb0af
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/dal/mysql/orderImport/OrderImportTempDataMapper.java
@@ -0,0 +1,15 @@
+package com.cf.imes.module.executor.dal.mysql.orderImport;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.executor.dal.dataobject.orderImport.OrderImportTempDataDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单导入临时表 Mapper
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:42
+ */
+@Mapper
+public interface OrderImportTempDataMapper extends BaseBatchMapper {
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderService.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderService.java
index 3767ffe48..317a82484 100644
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderService.java
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderService.java
@@ -10,6 +10,7 @@ import com.cf.imes.module.executor.controller.admin.orderParts.vo.OrderPartsResp
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
import com.cf.imes.module.executor.util.fileConversion.admin.api.webcad.ApiDataTypeVo;
import org.springframework.boot.system.ApplicationHome;
+import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
@@ -39,7 +40,7 @@ public interface OrderService {
* @param id 编号
* @return 生产单表 order_{N}
*/
- OrderDO getOrder(Long id );
+ OrderDO getOrder(Long id);
/**
* 获得生产单表 order_{N}分页
@@ -63,44 +64,45 @@ public interface OrderService {
* @param orderId: 生产单Id
* @return Map
*/
- Map getModule(Long orderId, Integer deleted);
+ Map getModule(Long orderId, Integer deleted);
/**
* @param orderId: 生产单id
- * @param roomId: 房间id
- * @param bodyId: 柜体id
+ * @param roomId: 房间id
+ * @param bodyId: 柜体id
* @return List
- * 需要修改返回值
+ * 需要修改返回值
*/
PageResult getPlatesDetail(Long orderId, Set roomId, Set bodyId, Set groupId, String groupName, Integer pageNo, Integer pageSize, Integer deleted);
/**
* @param orderId: 生产单id
- * @param roomId: 房间id
- * @param bodyId: 柜体id
+ * @param roomId: 房间id
+ * @param bodyId: 柜体id
* @return List
- * 需要修改返回值
+ * 需要修改返回值
*/
- PageResult getPartsDetail(Long orderId, Set roomId , Set bodyId, Set groupId, String name, Integer pageNo, Integer pageSize, Integer deleted, Set types);
+ PageResult getPartsDetail(Long orderId, Set roomId, Set bodyId, Set groupId, String name, Integer pageNo, Integer pageSize, Integer deleted, Set types);
/**
* @param orderId: 生产单id
- * @param roomId: 房间id
- * @param bodyId: 柜体id
+ * @param roomId: 房间id
+ * @param bodyId: 柜体id
* @return List
- * 需要修改返回值
+ * 需要修改返回值
*/
- PageResult getGoodsDetail(Long orderId, Set roomId , Set bodyId, Set groupId, Set goodsId, Integer pageNo, Integer pageSize, Integer deleted);
+ PageResult getGoodsDetail(Long orderId, Set roomId, Set bodyId, Set groupId, Set goodsId, Integer pageNo, Integer pageSize, Integer deleted);
/**
* 删除柜体/柜体还原
+ *
* @param orderId: 生产单id
- * @param roomId: 房间id
- * @param bodyId: 柜体id
+ * @param roomId: 房间id
+ * @param bodyId: 柜体id
*/
- void updateDeleteBody(Long orderId , Set roomId, Long bodyId, Integer status);
+ void updateDeleteBody(Long orderId, Set roomId, Long bodyId, Integer status);
- void updateRestoreBody(Long orderId , Set roomId, Long bodyId, Integer status);
+ void updateRestoreBody(Long orderId, Set roomId, Long bodyId, Integer status);
/**
* @param apiDataTypeVo:生产单号
@@ -121,7 +123,7 @@ public interface OrderService {
/**
* 打印/导出数据获取 (单文件)
*/
- Map getPrintDataMap(Long orderId, String type,HttpServletResponse response) ;
+ Map getPrintDataMap(Long orderId, String type, HttpServletResponse response);
default String getSavePath() {
ApplicationHome applicationHome = new ApplicationHome(this.getClass());
@@ -164,4 +166,10 @@ public interface OrderService {
*/
void realDeletedOrder(Long orderId);
+ /**
+ * 生产单异步导入
+ *
+ * @param importAsyncReqVO
+ */
+ void orderImportAsync(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file);
}
\ No newline at end of file
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java
index 8e4a645fd..bc14e5f1d 100644
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/order/OrderServiceImpl.java
@@ -1,6 +1,7 @@
package com.cf.imes.module.executor.service.order;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -10,10 +11,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.cf.imes.framework.common.enums.DeletedCodeEnum;
import com.cf.imes.framework.common.enums.OrderPackageStatusEnum;
+import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
+import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
@@ -56,17 +59,20 @@ import com.cf.imes.module.executor.enums.CategoryEnum;
import com.cf.imes.module.executor.enums.OrderDeletedEnum;
import com.cf.imes.module.executor.enums.OrderStatusEnum;
import com.cf.imes.module.executor.service.customplateno.CustomPlateNoGenerateService;
+import com.cf.imes.module.executor.service.orderImport.OrderImportHandler;
+import com.cf.imes.module.executor.service.orderImport.factory.OrderImportHandlerFactory;
import com.cf.imes.module.executor.service.plan.PlanService;
import com.cf.imes.module.executor.util.deviseData.structure.FieldConstants;
import com.cf.imes.module.executor.util.deviseData.structure.PlateDetail;
import com.cf.imes.module.executor.util.elasticsearch.EsUtils;
-import com.cf.imes.module.executor.util.fileConversion.admin.SnowflakeIdWorker3rd;
import com.cf.imes.module.executor.util.fileConversion.admin.api.webcad.ApiDataTypeVo;
import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
+import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
@@ -167,6 +173,9 @@ public class OrderServiceImpl implements OrderService {
@Resource
private PlanService planService;
+ @Autowired
+ private OrderImportHandlerFactory orderImportHandlerFactory;
+
@Override
public void updateOrder(OrderSaveReqVO updateReqVO) {
// 校验存在, 生产单未删除
@@ -1266,5 +1275,18 @@ public class OrderServiceImpl implements OrderService {
}
+ @Override
+ public void orderImportAsync(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file) {
+ // 根据导入类型和工厂(预留)获取处理类
+ OrderImportHandler orderImportHandler = orderImportHandlerFactory.getOrderImportHandler(importAsyncReqVO.getType(), null);
+ // 如果是补板校验生产单存在
+ Long orderId = importAsyncReqVO.getOrderId();
+ if (ObjectUtil.isNotNull(orderId)) {
+ Optional.ofNullable(getOrder(orderId)).orElseThrow(() -> ServiceExceptionUtil.exception(ORDER_IMPORT_ORDER_NOT_EXISTS, orderId));
+ }
+ // 准备前置数据,准备完成发送消息消费解析临时表
+ orderImportHandler.prepareAndConvert(importAsyncReqVO, file);
+ }
+
}
\ No newline at end of file
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/OrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/OrderImportHandler.java
new file mode 100644
index 000000000..021020ae0
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/OrderImportHandler.java
@@ -0,0 +1,24 @@
+package com.cf.imes.module.executor.service.orderImport;
+
+import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderImportAsyncReqVO;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 生产单导入处理器抽象类
+ *
+ * @author Gqr
+ * @since 2024/11/8 16:45
+ */
+public interface OrderImportHandler {
+ /**
+ * 获取工厂名,默认走default
+ * @return
+ */
+ String getFactoryName();
+
+ /**
+ * 准备、转换前置数据
+ *
+ */
+ void prepareAndConvert(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file);
+}
\ No newline at end of file
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/factory/OrderImportHandlerFactory.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/factory/OrderImportHandlerFactory.java
new file mode 100644
index 000000000..27b747725
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/factory/OrderImportHandlerFactory.java
@@ -0,0 +1,126 @@
+package com.cf.imes.module.executor.service.orderImport.factory;
+
+import com.cf.imes.framework.common.exception.ServiceException;
+import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
+import com.cf.imes.module.executor.enums.ErrorCodeConstants;
+import com.cf.imes.module.executor.enums.OrderImportTypeEnum;
+import com.cf.imes.module.executor.service.orderImport.OrderImportHandler;
+import com.cf.imes.module.executor.service.orderImport.handler.api.AbstractApiOrderImportHandler;
+import com.cf.imes.module.executor.service.orderImport.handler.excel.AbstractExcelOrderImportHandler;
+import com.cf.imes.module.executor.service.orderImport.handler.json.AbstractJsonOrderImportHandler;
+import com.cf.imes.module.executor.service.orderImport.handler.xml.AbstractXmlOrderImportHandler;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * 生产单导入处理器工厂类
+ *
+ * @author Gqr
+ * @since 2024/11/28 16:21
+ */
+@Component
+public class OrderImportHandlerFactory {
+ private final ApplicationContext applicationContext;
+
+ @Autowired
+ public OrderImportHandlerFactory(ApplicationContext applicationContext) {
+ this.applicationContext = applicationContext;
+ }
+
+ /**
+ * 根据导入类型获取对应的处理器
+ *
+ * @param type 导入类型
+ * @param factoryName 工厂名称预留
+ * @return
+ */
+ public OrderImportHandler getOrderImportHandler(int type, String factoryName) {
+ OrderImportTypeEnum importTypeEnum = OrderImportTypeEnum.match(type);
+ // 没有传入工厂/厂商用default
+ if (StringUtils.isEmpty(factoryName)) {
+ factoryName = "default";
+ }
+ ServiceException typeNotSupportException = ServiceExceptionUtil.exception(ErrorCodeConstants.ORDER_IMPORT_TYPE_NOT_SUPPORT, type);
+ switch (importTypeEnum) {
+ case EXCEL:
+ return Optional.ofNullable(getExcelHandler(factoryName)).orElseThrow(() -> typeNotSupportException);
+ case JSON:
+ return Optional.ofNullable(getJsonHandler(factoryName)).orElseThrow(() -> typeNotSupportException);
+ case XML:
+ return Optional.ofNullable(getXmlHandler(factoryName)).orElseThrow(() -> typeNotSupportException);
+ case API:
+ return Optional.ofNullable(getApiHandler(factoryName)).orElseThrow(() -> typeNotSupportException);
+ default:
+ throw typeNotSupportException;
+ }
+ }
+
+ /**
+ * 获取excel处理类
+ *
+ * @param factoryName
+ * @return
+ */
+ private OrderImportHandler getExcelHandler(String factoryName) {
+ for (Map.Entry entry : applicationContext.getBeansOfType(AbstractExcelOrderImportHandler.class).entrySet()) {
+ AbstractExcelOrderImportHandler entryValue = entry.getValue();
+ if (factoryName.equals(entryValue.getFactoryName())) {
+ return entryValue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 获取json处理类
+ *
+ * @param factoryName
+ * @return
+ */
+ private OrderImportHandler getJsonHandler(String factoryName) {
+ for (Map.Entry entry : applicationContext.getBeansOfType(AbstractJsonOrderImportHandler.class).entrySet()) {
+ AbstractJsonOrderImportHandler entryValue = entry.getValue();
+ if (factoryName.equals(entryValue.getFactoryName())) {
+ return entryValue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 获取xml处理类
+ *
+ * @param factoryName
+ * @return
+ */
+ private OrderImportHandler getXmlHandler(String factoryName) {
+ for (Map.Entry entry : applicationContext.getBeansOfType(AbstractXmlOrderImportHandler.class).entrySet()) {
+ AbstractXmlOrderImportHandler entryValue = entry.getValue();
+ if (factoryName.equals(entryValue.getFactoryName())) {
+ return entryValue;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 获取api处理类
+ *
+ * @param factoryName
+ * @return
+ */
+ private OrderImportHandler getApiHandler(String factoryName) {
+ for (Map.Entry entry : applicationContext.getBeansOfType(AbstractApiOrderImportHandler.class).entrySet()) {
+ AbstractApiOrderImportHandler entryValue = entry.getValue();
+ if (factoryName.equals(entryValue.getFactoryName())) {
+ return entryValue;
+ }
+ }
+ return null;
+ }
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/api/AbstractApiOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/api/AbstractApiOrderImportHandler.java
new file mode 100644
index 000000000..4905b32cf
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/api/AbstractApiOrderImportHandler.java
@@ -0,0 +1,12 @@
+package com.cf.imes.module.executor.service.orderImport.handler.api;
+
+import com.cf.imes.module.executor.service.orderImport.OrderImportHandler;
+
+/**
+ * 生产单api导入处理器抽象类
+ *
+ * @author Gqr
+ * @since 2025/1/8 16:35
+ */
+public interface AbstractApiOrderImportHandler extends OrderImportHandler {
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/api/DefaultApiOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/api/DefaultApiOrderImportHandler.java
new file mode 100644
index 000000000..260db3543
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/api/DefaultApiOrderImportHandler.java
@@ -0,0 +1,26 @@
+package com.cf.imes.module.executor.service.orderImport.handler.api;
+
+import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderImportAsyncReqVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 默认api生产单导入处理器
+ *
+ * @author Gqr
+ * @since 2025/1/9 9:21
+ */
+@Service("defaultApiOrderImportHandler")
+@Slf4j
+public class DefaultApiOrderImportHandler implements AbstractApiOrderImportHandler {
+ @Override
+ public String getFactoryName() {
+ return "default";
+ }
+
+ @Override
+ public void prepareAndConvert(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file) {
+ // todo api 准备、转换前置数据
+ }
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/excel/AbstractExcelOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/excel/AbstractExcelOrderImportHandler.java
new file mode 100644
index 000000000..f57a0e3d9
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/excel/AbstractExcelOrderImportHandler.java
@@ -0,0 +1,12 @@
+package com.cf.imes.module.executor.service.orderImport.handler.excel;
+
+import com.cf.imes.module.executor.service.orderImport.OrderImportHandler;
+
+/**
+ * 生产单excel导入处理器抽象类
+ *
+ * @author Gqr
+ * @since 2025/1/8 16:35
+ */
+public interface AbstractExcelOrderImportHandler extends OrderImportHandler {
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/excel/DefaultExcelOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/excel/DefaultExcelOrderImportHandler.java
new file mode 100644
index 000000000..0cbb864a1
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/excel/DefaultExcelOrderImportHandler.java
@@ -0,0 +1,139 @@
+package com.cf.imes.module.executor.service.orderImport.handler.excel;
+
+import com.alibaba.excel.EasyExcelFactory;
+import com.cf.imes.framework.common.exception.ServiceException;
+import com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants;
+import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
+import com.cf.imes.framework.redis.config.ChenfengCacheProperties;
+import com.cf.imes.framework.redis.constants.RedisKeyConstants;
+import com.cf.imes.framework.redis.util.RedisLockUtil;
+import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderImportAsyncReqVO;
+import com.cf.imes.module.executor.dal.dataobject.orderImport.OrderImportTaskDO;
+import com.cf.imes.module.executor.dal.mysql.orderImport.OrderImportTaskMapper;
+import com.cf.imes.module.executor.dal.mysql.orderImport.OrderImportTempDataMapper;
+import com.cf.imes.module.executor.enums.OrderImportStatusEnum;
+import com.cf.imes.module.executor.enums.OrderImportTaskStatusEnum;
+import com.cf.imes.module.executor.enums.OrderImportTypeEnum;
+import com.cf.imes.module.executor.service.order.OrderService;
+import com.cf.imes.module.executor.util.fileConversion.admin.files.excel.DefaultOrderImportExcelListener;
+import com.cf.imes.module.system.api.dict.DictDataApi;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.core.MessageBuilder;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.InputStream;
+
+import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_FILE_ANALYZE_ERROR;
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORGAN_LOCK_ERROR;
+
+/**
+ * 默认excel生产单导入处理器
+ * @author Gqr
+ * @since 2025/1/9 9:21
+ */
+@Service("defaultExcelOrderImportHandler")
+@Slf4j
+public class DefaultExcelOrderImportHandler implements AbstractExcelOrderImportHandler {
+
+ @Resource
+ private OrderImportTempDataMapper orderImportTempDataMapper;
+
+ @Resource
+ private OrderService orderService;
+
+ @Resource
+ private SnowFlakeGenerator snowFlakeGenerator;
+
+ @Resource
+ private OrderImportTaskMapper orderImportTaskMapper;
+
+ @Resource
+ private RabbitTemplate rabbitTemplate;
+
+ @Resource
+ private DictDataApi dictDataApi;
+
+ @Resource
+ private RedisLockUtil redisLockUtil;
+
+ @Resource
+ private ChenfengCacheProperties chenfengCacheProperties;
+
+ @Override
+ public String getFactoryName() {
+ return "default";
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void prepareAndConvert(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file) {
+ // 创建任务
+ Long taskId = createImportTask();
+ String importLockKey = String.format(RedisKeyConstants.ORDER_IMPORT_LOCK_KEY, getUserOrganId());
+ // 检查机构导入锁
+ boolean lockResult = redisLockUtil.lock(importLockKey, String.valueOf(taskId), chenfengCacheProperties.getLockTimeout());
+ if (!lockResult) {
+ throw new ServiceException(ORDER_IMPORT_ORGAN_LOCK_ERROR);
+ }
+ DefaultOrderImportExcelListener excelListener =
+ new DefaultOrderImportExcelListener(orderImportTempDataMapper, orderService, dictDataApi, snowFlakeGenerator, importAsyncReqVO.getOrderId(), taskId);
+
+ try (InputStream inputStream = file.getInputStream()) {
+ // 读取excel
+ EasyExcelFactory.read(inputStream, excelListener).headRowNumber(-1).sheet().doRead();
+ } catch (ServiceException sev) {
+ // 导入锁解锁
+ redisLockUtil.unlock(importLockKey, taskId.toString());
+ throw sev;
+ } catch (Exception e) {
+ log.error(ORDER_IMPORT_FILE_ANALYZE_ERROR.getMsg(), e);
+ // 导入锁解锁
+ redisLockUtil.unlock(importLockKey, taskId.toString());
+ throw new ServiceException(ORDER_IMPORT_FILE_ANALYZE_ERROR);
+ }
+
+ Message message = MessageBuilder
+ .withBody(taskId.toString().getBytes())
+ .setHeader("x-message-ttl", 60000) // 设置 TTL 为 60000 毫秒(60 秒)
+ .build();
+ //如果处于事务中,待事务提交成功了再执行后续操作,防止事务未提交完成导致消费端查不到数据
+ if (TransactionSynchronizationManager.isActualTransactionActive()) {
+ TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+ @Override
+ public void afterCommit() {
+ // 数据库操作全部完成发送消息
+ rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_IMPORT_DEFAULT_EXCEL_EXCHANGE, null, message);
+ }
+ });
+ } else {
+ // 数据库操作全部完成发送消息
+ rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_IMPORT_DEFAULT_EXCEL_EXCHANGE, null, message);
+ }
+
+ }
+
+ /**
+ * 创建导入任务
+ *
+ * @return taskId
+ */
+ private Long createImportTask() {
+ // 创建导入任务
+ OrderImportTaskDO orderImportTaskDO = OrderImportTaskDO.builder()
+ .id((Long) snowFlakeGenerator.nextId(null))
+ .type(OrderImportTypeEnum.EXCEL.getType())
+ .importStatus(OrderImportStatusEnum.IMPORT_NOT_YET.getStatus())
+ .status(OrderImportTaskStatusEnum.CREATE_NOT_CONSUME.getStatus())
+ .build();
+ orderImportTaskMapper.insert(orderImportTaskDO);
+ return orderImportTaskDO.getId();
+ }
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/json/AbstractJsonOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/json/AbstractJsonOrderImportHandler.java
new file mode 100644
index 000000000..306956193
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/json/AbstractJsonOrderImportHandler.java
@@ -0,0 +1,13 @@
+package com.cf.imes.module.executor.service.orderImport.handler.json;
+
+
+import com.cf.imes.module.executor.service.orderImport.OrderImportHandler;
+
+/**
+ * 生产单json导入处理器抽象类
+ *
+ * @author Gqr
+ * @since 2025/1/8 16:35
+ */
+public interface AbstractJsonOrderImportHandler extends OrderImportHandler {
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/json/DefaultJsonOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/json/DefaultJsonOrderImportHandler.java
new file mode 100644
index 000000000..427393d58
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/json/DefaultJsonOrderImportHandler.java
@@ -0,0 +1,26 @@
+package com.cf.imes.module.executor.service.orderImport.handler.json;
+
+import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderImportAsyncReqVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 默认json生产单导入处理器
+ *
+ * @author Gqr
+ * @since 2025/1/9 9:21
+ */
+@Service("defaultJsonOrderImportHandler")
+@Slf4j
+public class DefaultJsonOrderImportHandler implements AbstractJsonOrderImportHandler {
+ @Override
+ public String getFactoryName() {
+ return "default";
+ }
+
+ @Override
+ public void prepareAndConvert(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file) {
+ // todo json 准备、转换前置数据
+ }
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/xml/AbstractXmlOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/xml/AbstractXmlOrderImportHandler.java
new file mode 100644
index 000000000..12b758968
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/xml/AbstractXmlOrderImportHandler.java
@@ -0,0 +1,12 @@
+package com.cf.imes.module.executor.service.orderImport.handler.xml;
+
+import com.cf.imes.module.executor.service.orderImport.OrderImportHandler;
+
+/**
+ * 生产单xml导入处理器抽象类
+ *
+ * @author Gqr
+ * @since 2025/1/8 16:35
+ */
+public interface AbstractXmlOrderImportHandler extends OrderImportHandler {
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/xml/DefaultXmlOrderImportHandler.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/xml/DefaultXmlOrderImportHandler.java
new file mode 100644
index 000000000..9d5cfbe2a
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/orderImport/handler/xml/DefaultXmlOrderImportHandler.java
@@ -0,0 +1,24 @@
+package com.cf.imes.module.executor.service.orderImport.handler.xml;
+
+import com.cf.imes.module.executor.controller.admin.order.vo.order.OrderImportAsyncReqVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author Gqr
+ * @since 2025/1/9 9:21
+ */
+@Service("defaultXmlOrderImportHandler")
+@Slf4j
+public class DefaultXmlOrderImportHandler implements AbstractXmlOrderImportHandler {
+ @Override
+ public String getFactoryName() {
+ return "default";
+ }
+
+ @Override
+ public void prepareAndConvert(OrderImportAsyncReqVO importAsyncReqVO, MultipartFile file) {
+ // todo xml 准备、转换前置数据
+ }
+}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plate/PlateServiceImpl.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plate/PlateServiceImpl.java
index ec5fb6353..6bd422534 100644
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plate/PlateServiceImpl.java
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/service/plate/PlateServiceImpl.java
@@ -20,6 +20,7 @@ import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.es.core.service.ESDocumentService;
+import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.cf.imes.framework.mybatis.core.query.QueryWrapperX;
@@ -49,7 +50,6 @@ import com.cf.imes.module.executor.enums.OrderItemType;
import com.cf.imes.module.executor.enums.OrderStatusEnum;
import com.cf.imes.module.executor.service.plan.PlanService;
import com.cf.imes.module.executor.util.elasticsearch.EsUtils;
-import com.cf.imes.module.executor.util.fileConversion.admin.SnowflakeIdWorker3rd;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/MinuteCounter.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/MinuteCounter.java
deleted file mode 100644
index 0868a5f90..000000000
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/MinuteCounter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.cf.imes.module.executor.util;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class MinuteCounter {
- private static final int MASK = 0x7FFFFFFF;
- private final AtomicInteger atom;
-
- public MinuteCounter() {
- atom = new AtomicInteger(0);
- }
-
- public final int incrementAndGet() {
- return atom.incrementAndGet() & MASK;
- }
-
- public int get() {
- return atom.get() & MASK;
- }
-
- public void set(int newValue) {
- atom.set(newValue & MASK);
- }
-
-}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/SnowflakeIdWorker3rd.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/SnowflakeIdWorker3rd.java
deleted file mode 100644
index db0ce773f..000000000
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/SnowflakeIdWorker3rd.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package com.cf.imes.module.executor.util.fileConversion.admin;
-
-
-import com.cf.imes.module.executor.util.MinuteCounter;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDate;
-
-/**
- * @ClassName: SnowflakeIdWorker3rd
- * @Description:snowflake算法改进
- * @author: yonnie
- * @date: 2024/06/18 14:10:47
- * @version V1.0
- *
- * 将产生的Id类型更改为Integer 32bit
- * 把时间戳的单位改为分钟,使用25bit的时间戳
- * 7bit作为自增值即 2^7 = 128
- */
-@Slf4j
-@Component
-public class SnowflakeIdWorker3rd {
- /** 初始时间 (2024-01-01: 1704038400) */
- // private final int twepoch = 28400640;// 1704038400000L/1000/60;
- private final int twepoch = 1704038400;
- /** 序列在id中占位数 */
- private final long sequenceBits = 7L;
- /** 时间截向左移7bit */
- private final long timestampLeftShift = sequenceBits;
- /** 生成序列的MASK (0x7F) */
- private final int sequenceMask = -1 ^ (-1 << sequenceBits);
- /** 分钟内序 (0~127) */
- private int sequence = 0;
- private int laterSequence = 0;
- /** 上次生成ID的时间戳 */
- private int lastTimestamp = -1;
- private final MinuteCounter counter = new MinuteCounter();
- /** 预支时间标志 */
- boolean isAdvance = false;
-
- // ==============================Constructors=====================================
-
- public SnowflakeIdWorker3rd() {
- // No Args Constructors
- }
-
- // ==============================Test=============================================
-
- /** 测试 */
- public static void main(String[] args) {
- SnowflakeIdWorker3rd idWorker = new SnowflakeIdWorker3rd();
- long obtainingTime = idWorker.obtainingTime();
- for (int i = 0; i < 10001; i++) {
- long id = idWorker.nextId();
- System.out.println(i + ": " + id + " " + obtainingTime + Long.toString(id).substring(2));
- }
- // long id = idWorker.nextId();
- // System.out.println(id);
- }
-
- // ==============================Methods==========================================
- /**
- * 获取当前年月
- * @return null
- */
- public static int obtainingTime() {
- LocalDate now = LocalDate.now();
- int year = now.getYear();
- String year_last_two_digits = String.valueOf(year).substring(2);
- int month = now.getMonthValue();
- String formatted_date = year_last_two_digits + String.format("%02d", month);
- return Integer.parseInt(formatted_date);
- }
-
- /**
- * 获得下一个ID (该方法是线程安全)
- *
- * @return SnowflakeId
- */
- public synchronized int nextId() {
- int timestamp = timeGen();
- // 如果当前时间小于上一次ID生成的时间戳,说明系统时钟修改过
- if (timestamp < lastTimestamp) {
- throw new RuntimeException(String.format(
- "Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
- }
-
- if (timestamp > counter.get()) {
- counter.set(timestamp);
- isAdvance = false;
- }
-
- // 如果是同时间生成的,则进行分钟内序列
- if (lastTimestamp == timestamp || isAdvance) {
- if (!isAdvance) {
- sequence = (sequence + 1) & sequenceMask;
- }
-
- // 分钟内自增列溢出
- if (sequence == 0) {
- // 预支下一分获得新的时间戳
- isAdvance = true;
- int laterTimestamp = counter.get();
- if (laterSequence == 0) {
- laterTimestamp = counter.incrementAndGet();
- }
- int nextId = ((laterTimestamp - twepoch) << timestampLeftShift) | laterSequence;
- laterSequence = (laterSequence + 1) & sequenceMask;
- return nextId;
- }
- } else { // 时间戳改变,分钟内序列置0
- sequence = 0;
- laterSequence = 0;
- }
- // 上次生成ID的时间截
- lastTimestamp = timestamp;
- // 移位并或运算拼成32位的ID
- return ((timestamp - twepoch) << timestampLeftShift) | sequence;
- }
-
- /**
- * 返回以分钟为单位的当前时
- *
- * @return 当前时间(分钟)
- */
- protected int timeGen() {
- // String timestamp = String.valueOf(System.currentTimeMillis() / 1000 / 60);
- String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
- return Integer.valueOf(timestamp);
- }
-
-}
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/api/webcad/ApiTypeRealize.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/api/webcad/ApiTypeRealize.java
index 4b20756f9..d5e4af1c3 100644
--- a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/api/webcad/ApiTypeRealize.java
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/api/webcad/ApiTypeRealize.java
@@ -3,6 +3,7 @@ package com.cf.imes.module.executor.util.fileConversion.admin.api.webcad;//packa
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.module.executor.controller.admin.orderParts.vo.OrderPartsRemark;
import com.cf.imes.module.executor.controller.admin.plan.dto.Point;
import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO;
@@ -14,7 +15,6 @@ import com.cf.imes.module.executor.dal.dataobject.orderParts.OrderPartsDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO;
import com.cf.imes.module.executor.dal.dataobject.rawgoods.RawGoodsDO;
import com.cf.imes.module.executor.enums.*;
-import com.cf.imes.module.executor.util.fileConversion.admin.SnowflakeIdWorker3rd;
import com.cf.imes.module.executor.util.deviseData.structure.*;
import com.cf.imes.module.system.api.dict.DictDataApi;
import lombok.extern.slf4j.Slf4j;
diff --git a/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/DefaultOrderImportExcelListener.java b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/DefaultOrderImportExcelListener.java
new file mode 100644
index 000000000..ceb9ade23
--- /dev/null
+++ b/cf-module-prod-executor/cf-module-prod-executor-biz/src/main/java/com/cf/imes/module/executor/util/fileConversion/admin/files/excel/DefaultOrderImportExcelListener.java
@@ -0,0 +1,721 @@
+package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
+import com.alibaba.excel.util.ListUtils;
+import com.alibaba.fastjson.JSON;
+import com.cf.imes.framework.common.exception.ServiceException;
+import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
+import com.cf.imes.framework.common.util.json.JsonUtils;
+import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
+import com.cf.imes.framework.organ.core.context.OrganContextHolder;
+import com.cf.imes.framework.web.core.util.WebFrameworkUtils;
+import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
+import com.cf.imes.module.executor.dal.dataobject.orderImport.OrderImportTempDataDO;
+import com.cf.imes.module.executor.dal.mysql.orderImport.OrderImportTempDataMapper;
+import com.cf.imes.module.executor.enums.CategoryEnum;
+import com.cf.imes.module.executor.enums.DataTypeEnum;
+import com.cf.imes.module.executor.enums.DictTypeConstants;
+import com.cf.imes.module.executor.enums.IsHavaeEnum;
+import com.cf.imes.module.executor.enums.OrderImportConstants;
+import com.cf.imes.module.executor.enums.OrderImportTmpDataTypeEnum;
+import com.cf.imes.module.executor.enums.OrderStatusEnum;
+import com.cf.imes.module.executor.enums.QuarrelEnum;
+import com.cf.imes.module.executor.service.order.OrderService;
+import com.cf.imes.module.executor.util.fileConversion.admin.ToolUtil;
+import com.cf.imes.module.system.api.dict.DictDataApi;
+import com.cf.imes.module.system.api.dict.dto.DictDataRespDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.lang.reflect.Field;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_DETAIL_VALID_ERROR;
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORDER_CUSTOMERNO_EXISTS;
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORDER_FIELD_DATE_FORMAT_ERROR;
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORDER_FIELD_EMPTY;
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORDER_FIELD_LENGTH_ERROR;
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORDER_FIELD_MOBILE_FORMAT_ERROR;
+
+/**
+ * 默认生产单excel导入监听器
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:14
+ */
+@Slf4j
+public final class DefaultOrderImportExcelListener extends AnalysisEventListener
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-id
+
@@ -271,6 +275,10 @@
com.cf.imes
cf-spring-boot-starter-web
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-id
+
diff --git a/cf-module-prod-manage/cf-module-prod-manage-biz/src/main/java/com/cf/imes/module/manage/service/pack/PackServiceImpl.java b/cf-module-prod-manage/cf-module-prod-manage-biz/src/main/java/com/cf/imes/module/manage/service/pack/PackServiceImpl.java
index af423809a..1f3b9e080 100644
--- a/cf-module-prod-manage/cf-module-prod-manage-biz/src/main/java/com/cf/imes/module/manage/service/pack/PackServiceImpl.java
+++ b/cf-module-prod-manage/cf-module-prod-manage-biz/src/main/java/com/cf/imes/module/manage/service/pack/PackServiceImpl.java
@@ -9,6 +9,7 @@ import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
+import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.framework.mybatis.core.query.QueryWrapperX;
import com.cf.imes.module.executor.api.plan.OrderPlanApi;
import com.cf.imes.module.manage.controller.admin.pack.prePack.PackPlateList;
@@ -29,7 +30,6 @@ import com.cf.imes.module.manage.dal.mysql.plate.OrderPlateMapper;
import com.cf.imes.module.manage.dal.mysql.process.OrdersMapper;
import com.cf.imes.module.manage.dal.mysql.query.OrderItemMapper;
import com.cf.imes.module.manage.dal.mysql.query.OrderPartsMapper;
-import com.cf.imes.module.manage.util.SnowflakeIdWorker3rd;
import com.cf.imes.module.system.api.setting.SettingApi;
import com.cf.imes.module.system.api.setting.dto.PackageConfigDTO;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
diff --git a/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java b/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java
index 16894119c..d9c2f3e98 100644
--- a/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java
+++ b/cf-module-prod-plan/cf-module-prod-plan-api/src/main/java/com/cf/imes/module/plan/enums/ErrorCodeConstants.java
@@ -1,8 +1,14 @@
package com.cf.imes.module.plan.enums;
+import com.cf.imes.framework.common.exception.ErrorCode;
+
/**
* @author there
* 生产计划服务错误码枚举 使用 1-005-000-000 段
*/
-public interface ErrorCodeConstants {
+public class ErrorCodeConstants {
+ // ========== 生产单导入 1_005_000 ==========
+ public static final ErrorCode ORDER_IMPORT_PLATE_GOODS_NOT_EXISTS = new ErrorCode(1_005_000_000, "{}小板数据不存在:{}");
+ public static final ErrorCode ORDER_IMPORT_ORGANID_NOT_EXISTS = new ErrorCode(1_005_000_001, "不存在组织id,导入终止");
+ public static final ErrorCode ORDER_IMPORT_FAIL = new ErrorCode(1_005_000_002, "导入失败");
}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/pom.xml b/cf-module-prod-plan/cf-module-prod-plan-biz/pom.xml
index 27daed935..30e8c4e17 100644
--- a/cf-module-prod-plan/cf-module-prod-plan-biz/pom.xml
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/pom.xml
@@ -68,6 +68,23 @@
cf-spring-boot-starter-mybatis
+
+ com.cf.imes
+ cf-spring-boot-starter-elasticsearch
+
+
+ jakarta.json
+ jakarta.json-api
+
+
+ ${revision}
+
+
+ jakarta.json
+ jakarta.json-api
+ 2.1.1
+
+
com.cf.imes
cf-spring-boot-starter-redis
@@ -127,6 +144,21 @@
cf-spring-boot-starter-file
+
+ com.cf.imes
+ cf-spring-boot-starter-mq
+
+
+ com.cf.imes
+ cf-module-prod-executor-api
+ ${revision}
+
+
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-id
+
+
@@ -138,6 +170,87 @@
org.springframework.boot
spring-boot-maven-plugin
${spring.boot.version}
+
+ ZIP
+
+
+ com.cf.imes
+ cf-common
+
+
+ com.cf.imes
+ cf-module-infra-api
+
+
+ com.cf.imes
+ cf-module-prod-plan-api
+
+
+ com.cf.imes
+ cf-module-system-api
+
+
+ com.cf.imes
+ cf-spring-boot-starter-banner
+
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-error-code
+
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-operatelog
+
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-organ
+
+
+ com.cf.imes
+ cf-spring-boot-starter-excel
+
+
+ com.cf.imes
+ cf-spring-boot-starter-monitor
+
+
+ com.cf.imes
+ cf-spring-boot-starter-mybatis
+
+
+ com.cf.imes
+ cf-spring-boot-starter-redis
+
+
+ com.cf.imes
+ cf-spring-boot-starter-rpc
+
+
+ com.cf.imes
+ cf-spring-boot-starter-security
+
+
+ com.cf.imes
+ cf-spring-boot-starter-web
+
+
+ com.cf.imes
+ cf-spring-boot-starter-mq
+
+
+ com.cf.imes
+ cf-spring-boot-starter-elasticsearch
+
+
+ com.cf.imes
+ cf-module-prod-executor-api
+
+
+ com.cf.imes
+ cf-spring-boot-starter-biz-id
+
+
+
@@ -156,12 +269,12 @@
copy-dependencies
-
-
- target/lib
-
- com.cf.imes
-
+
+
+
+
+
+
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/orderImport/vo/OrderImportTempDataReqVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/orderImport/vo/OrderImportTempDataReqVO.java
new file mode 100644
index 000000000..4130dfa5e
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/orderImport/vo/OrderImportTempDataReqVO.java
@@ -0,0 +1,64 @@
+package com.cf.imes.module.plan.controller.orderImport.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * @author Gqr
+ * @since 2025/1/15 16:59
+ */
+@Schema(description = "管理后台 - 生产单导入临时数据 Request VO")
+@Data
+@Builder
+public class OrderImportTempDataReqVO {
+ /**
+ * 导入任务id
+ */
+ private Long taskId;
+
+ /**
+ * 临时数据类型,参考OrderImportTmpDataTypeEnum
+ */
+ private Integer type;
+
+ /**
+ * 物料编码
+ */
+ private String goodsId;
+
+ /**
+ * 是否做分页
+ */
+ private boolean doPaging;
+
+ /**
+ * 偏移量 (page - 1) * pageSize
+ */
+ private int offset;
+
+ /**
+ * 页大小
+ */
+ private int size;
+
+ /**
+ * 房间名称
+ */
+ private String roomName;
+
+ /**
+ * 柜体名称
+ */
+ private String bodyName;
+
+ /**
+ * 加工组类型
+ */
+ private String groupTypeName;
+
+ /**
+ * 模块名称
+ */
+ private String groupName;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/orderImport/vo/OrderPlateImportExcelVO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/orderImport/vo/OrderPlateImportExcelVO.java
new file mode 100644
index 000000000..abecfa191
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/controller/orderImport/vo/OrderPlateImportExcelVO.java
@@ -0,0 +1,181 @@
+package com.cf.imes.module.plan.controller.orderImport.vo;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 生产单 Excel 导入 VO
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = false) // 设置 chain = false,避免生产单导入有问题
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class OrderPlateImportExcelVO {
+
+ @JsonIgnore
+ private String ordinal;
+
+ @JsonIgnore
+ private String goodType;
+
+ @JsonIgnore
+ private String goodsId;
+
+ @JsonIgnore
+ private Long goodId; // 商品id
+
+ @JsonIgnore
+ private String goodsName;
+
+ @JsonIgnore
+ private String material;
+
+ @JsonIgnore
+ private String wave;
+
+ @JsonIgnore
+ private String color;
+
+ @JsonIgnore
+ private String isComposite;
+
+ @JsonIgnore
+ private String category;
+
+ @JsonIgnore
+ private String type;
+
+ @JsonIgnore
+ private String factory;
+
+ @JsonIgnore
+ private String brand;
+
+ @JsonIgnore
+ private String model;
+
+ @JsonIgnore
+ private String goodsHeight;
+
+ @JsonIgnore
+ private String goodsWidth;
+
+ @JsonIgnore
+ private String goodsThickness;
+
+ @JsonIgnore
+ private String spec;
+
+ @JsonIgnore
+ private String unit;
+
+ @NotNull
+ @JsonIgnore
+ private String goodsNumber;
+
+ @JsonIgnore
+ private String roomsName;
+
+ @JsonIgnore
+ private String cabinetsName;
+
+ @JsonIgnore
+ private String synthesisTypeName; // 加工组类型的名称
+
+ @JsonIgnore
+ private String combinationName;
+
+ @JsonIgnore
+ private String name;
+
+ @JsonIgnore
+ private String plateNo;
+
+ @JsonIgnore
+ private String height;
+
+ @JsonIgnore
+ private String width;
+
+ @JsonIgnore
+ private String splitHeight;
+
+ @JsonIgnore
+ private String splitWidth;
+
+ @JsonIgnore
+ private String thickness;
+
+ @JsonIgnore
+ private String sealLeft;
+
+ @JsonIgnore
+ private String sealRight;
+
+ @JsonIgnore
+ private String sealUp;
+
+ @JsonIgnore
+ private String sealDown;
+
+ @JsonIgnore
+ private String typographicFace;
+
+ @JsonIgnore
+ private String texture;
+
+ @JsonIgnore
+ private String openDoorType;
+
+ @JsonIgnore
+ private String result;
+
+ private String remark1;
+
+ private String remark2;
+
+ private String remark3;
+
+ private String remark4;
+
+ private String remark5;
+
+ private String remark6;
+
+ private String remark7;
+
+ private String remark8;
+
+ private String remark9;
+
+ private String remark10;
+
+ private String remark;
+
+ @JsonIgnore
+ private Double area; // 面积
+
+ // 备注转json数据
+ public String remarkJSON() {
+ ObjectMapper objectMapper = new ObjectMapper();
+ // 设置实体类字段的值
+ try {
+ String json = objectMapper.writeValueAsString(this);
+ return json;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "";
+ }
+ }
+}
+
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/goods/GoodsDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/goods/GoodsDO.java
new file mode 100644
index 000000000..a85d8e7bb
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/goods/GoodsDO.java
@@ -0,0 +1,110 @@
+package com.cf.imes.module.plan.dal.dataobject.goods;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+
+/**
+ * 生产单商品 DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("order_goods")
+@KeySequence("order_goods_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class GoodsDO extends BaseDO {
+
+ /**
+ * 主键
+ */
+ @TableId
+ private Long id;
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+ /**
+ * 生产单号
+ */
+ private Long orderId;
+ /**
+ * 设计端商品ID
+ */
+ private String rawGoodsId;
+ /**
+ * 商品 ID
+ */
+ private String goodsId;
+ /**
+ * 排单 ID
+ */
+ private Long planId;
+ /**
+ * 商品名称
+ */
+ private String goodsName;
+ /**
+ * 材质:颗粒板、欧松板、多层板、生态板、禾香板、密度板、实木、铝蜂窝板、铝塑板
+ */
+ private String material;
+ /**
+ * 纹路 0 正纹 1 可翻转 2 反纹
+ */
+ private Boolean texture;
+ /**
+ * 颜色
+ */
+ private String color;
+ /**
+ * 背面颜色
+ */
+ private String colorBlack;
+ /**
+ * 宽度
+ */
+ private BigDecimal width;
+ /**
+ * 高度
+ */
+ private BigDecimal height;
+ /**
+ * 厚度
+ */
+ private BigDecimal thickness;
+ /**
+ * 价格
+ */
+ private Double price;
+ /**
+ * 品牌
+ */
+ private String brand;
+ /**
+ * 规格
+ */
+ private String spec;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/order/OrderDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/order/OrderDO.java
new file mode 100644
index 000000000..8a0e26abc
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/order/OrderDO.java
@@ -0,0 +1,135 @@
+package com.cf.imes.module.plan.dal.dataobject.order;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import com.cf.imes.framework.mybatis.core.type.CompressStringTypeHandler;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+
+/**
+ * 生产单表 order_{N} DO
+ *
+ * @author 晨丰科技
+ */
+@TableName(value = "`orders`", autoResultMap = true)
+@KeySequence("order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderDO extends BaseDO {
+
+ /**
+ * 生产单号,主键
+ */
+ @TableId
+ private Long id;
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+
+ /**
+ * 父单号
+ */
+ private Long parentNo;
+ /**
+ * 源生产单号
+ */
+ private String apiOrderId;
+ /**
+ * 生产单日期
+ */
+ private LocalDateTime orderDate;
+ /**
+ * 交付日期
+ */
+ private LocalDateTime deliveryDate;
+ /**
+ * 生产单的完成时间
+ */
+ private LocalDateTime finishTime;
+ /**
+ * 生产单类型,1主单 2子单
+ */
+ private Integer orderType;
+ /**
+ * 生产单排序号
+ */
+ private Integer orderSort;
+ /**
+ * 数据类型,0文件导入 1API 2数据源
+ */
+ private Integer dataType;
+ /**
+ * 订单状态,0空订单1新单2已排单3生产中4生产完成
+ */
+ private Integer status;
+ /**
+ * 打包状态:0未打包1打包中2已打包
+ */
+ private Integer packaged;
+ /**
+ * 自定义单号
+ */
+ private String customOrderNo;
+ /**
+ * 客户
+ */
+ private String customer;
+ /**
+ * 客户地址
+ */
+ private String address;
+ /**
+ * 客户电话
+ */
+ private String phoneNumber;
+ /**
+ * 经销商
+ */
+ private String dealer;
+ /**
+ * 经销商电话
+ */
+ private String dealerPhoneNumber;
+ /**
+ * 业务员
+ */
+ private String salesman;
+ /**
+ * 拆单员
+ */
+ private String splitter;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+
+ /**
+ * 自定义板编号配置id
+ */
+ @TableField(value = "custom_plateno_config_id")
+ private Long customPlatenoConfigId;
+
+ /**
+ * 自定义板编号序号
+ */
+ @TableField(value = "custom_plateno_seq", typeHandler = CompressStringTypeHandler.class)
+ private String customPlatenoSeq;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderBody/OrderBodyDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderBody/OrderBodyDO.java
new file mode 100644
index 000000000..281f43b2c
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderBody/OrderBodyDO.java
@@ -0,0 +1,93 @@
+package com.cf.imes.module.plan.dal.dataobject.orderBody;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 生产单柜体 DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("order_body")
+@KeySequence("order_body_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderBodyDO extends BaseDO {
+
+ /**
+ * 模块 ID
+ */
+ @TableId
+ private Long id;
+
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+ /**
+ * 生产单号
+ */
+ private Long orderId;
+ /**
+ * 房间ID,后端生成
+ */
+ private Long roomId;
+ /**
+ * 房间名称
+ */
+ private String roomName;
+ /**
+ * 模块名称
+ */
+ private String name;
+ /**
+ * 模块宽度
+ */
+ private Double width;
+ /**
+ * 模块高度
+ */
+ private Double height;
+ /**
+ * 模块深度
+ */
+ private Double depth;
+ /**
+ * 模块复制数量
+ */
+ private Integer multiNum;
+ /**
+ * 板材数量
+ */
+ private Integer plateNum;
+ /**
+ * 异型数量
+ */
+ private Integer unregularNum;
+
+ /**
+ * 文件名
+ */
+ private String filename;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderGroup/OrderGroupDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderGroup/OrderGroupDO.java
new file mode 100644
index 000000000..5dac7b856
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderGroup/OrderGroupDO.java
@@ -0,0 +1,96 @@
+package com.cf.imes.module.plan.dal.dataobject.orderGroup;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 生产单加工组 DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("order_group")
+@KeySequence("order_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderGroupDO extends BaseDO {
+
+ /**
+ * 模块 ID
+ */
+ @TableId
+ private Long id;
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+ /**
+ * 生产单号
+ */
+ private Long orderId;
+ /**
+ * 柜体ID,上表中ID
+ */
+ private Long bodyId;
+ /**
+ * 加工组类型id,依据同一生产单的同一房间的同一柜体的相同加工组类型,由服务端生成
+ */
+ private Long groupTypeId;
+ /**
+ * 加工组类型
+ */
+ private String groupTypeName;
+ /**
+ * 模块名称
+ */
+ private String name;
+ /**
+ * 加工组宽度
+ */
+ private Double width;
+ /**
+ * 加工组高度
+ */
+ private Double height;
+ /**
+ * 加工组深度
+ */
+ private Double depth;
+ /**
+ * 模块复制数量
+ */
+ private Integer multiNum;
+ /**
+ * 板材数量
+ */
+ private Integer plateNum;
+ /**
+ * 异型数量
+ */
+ private Integer unregularNum;
+ /**
+ * 文件名
+ */
+ private String filename;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTaskDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTaskDO.java
new file mode 100644
index 000000000..26cca719d
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTaskDO.java
@@ -0,0 +1,67 @@
+package com.cf.imes.module.plan.dal.dataobject.orderImport;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 生产单导入任务
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:30
+ */
+@TableName("order_import_task")
+@KeySequence("order_import_task_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderImportTaskDO extends BaseDO {
+ /**
+ * 主键
+ */
+ @TableId
+ private Long id;
+
+ /**
+ * 组织id
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+
+ /**
+ * 生产单id
+ */
+ private Long orderId;
+
+ /**
+ * 导入类型,参考OrderImportTypeEnum
+ */
+ private Integer type;
+
+ /**
+ * 导入状态
+ */
+ private Integer importStatus;
+
+ /**
+ * 消费状态
+ */
+ private Integer status;
+
+ /**
+ * 导入结果0
+ */
+ private String result;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataDO.java
new file mode 100644
index 000000000..54aefd5ed
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataDO.java
@@ -0,0 +1,188 @@
+package com.cf.imes.module.plan.dal.dataobject.orderImport;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+
+/**
+ * 生产单导入临时表
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:36
+ */
+@TableName("order_import_temp_data")
+@KeySequence("order_import_temp_data_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderImportTempDataDO {
+ /**
+ * 主键
+ */
+ @TableId
+ private Long id;
+
+ /**
+ * 组织id
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+
+ /**
+ * 导入任务id
+ */
+ private Long taskId;
+
+ /**
+ * 生产单id(补板用)
+ */
+ private Long orderId;
+
+ /**
+ * 类型
+ */
+ private Integer type;
+
+ /**
+ * 物料编码
+ */
+ private String outerGoodsId;
+
+ /**
+ * imes商品id
+ */
+ private String innerGoodsId;
+
+ /**
+ * 商品名称
+ */
+ private String goodsName;
+
+ /**
+ * 材料
+ */
+ private String material;
+
+ /**
+ * 颜色
+ */
+ private String color;
+
+ /**
+ * 纹路
+ */
+ private String wave;
+
+ /**
+ * 宽度
+ */
+ private String width;
+
+ /**
+ * 长度
+ */
+ private String height;
+
+ /**
+ * 厚度
+ */
+ private String thickness;
+
+ /**
+ * 品牌
+ */
+ private String brand;
+
+ /**
+ * 是否复合部件
+ */
+ @TableField("is_composite")
+ private String isComposite;
+
+ /**
+ * 配件主类
+ */
+ private String category;
+
+ /**
+ * 配件子类型
+ */
+ private String subType;
+
+ /**
+ * 厂家
+ */
+ private String factory;
+
+ /**
+ * 规格
+ */
+ private String spec;
+
+ /**
+ * 型号
+ */
+ private String model;
+
+ /**
+ * 单位
+ */
+ private String unit;
+
+ /**
+ * 房间名称
+ */
+ private String roomName;
+
+ /**
+ * 柜体名称
+ */
+ private String bodyName;
+
+ /**
+ * 加工组类型
+ */
+ private String groupTypeName;
+
+ /**
+ * 模块名称
+ */
+ private String groupName;
+
+ /**
+ * 数量
+ */
+ private Double num;
+
+ /**
+ * 创建人
+ */
+ private String creater;
+
+ /**
+ * 导入数据明细
+ */
+ private String detail;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+
+ /**
+ * 排序号
+ */
+ private int sort;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataGoodsGroupDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataGoodsGroupDO.java
new file mode 100644
index 000000000..47c9782f4
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataGoodsGroupDO.java
@@ -0,0 +1,134 @@
+package com.cf.imes.module.plan.dal.dataobject.orderImport;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @author Gqr
+ * @since 2025/1/15 16:49
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderImportTempDataGoodsGroupDO implements Serializable {
+ @Serial
+ private static final long serialVersionUID = -1853615166652757427L;
+
+ /**
+ * 排序号
+ */
+ private int sortn;
+
+ /**
+ * 商品名称
+ */
+ private String goodsName;
+
+ /**
+ * 材料
+ */
+ private String material;
+
+ /**
+ * 颜色
+ */
+ private String color;
+
+ /**
+ * 纹路
+ */
+ private String wave;
+
+ /**
+ * 宽度
+ */
+ private String width;
+
+ /**
+ * 长度
+ */
+ private String height;
+
+ /**
+ * 厚度
+ */
+ private String thickness;
+
+ /**
+ * 品牌
+ */
+ private String brand;
+
+ /**
+ * 规格
+ */
+ private String spec;
+
+ private String isComposite;
+
+ /**
+ * 配件主类
+ */
+ private String category;
+
+ /**
+ * 配件子类型
+ */
+ private String subType;
+
+ /**
+ * 厂家
+ */
+ private String factory;
+
+ /**
+ * 型号
+ */
+ private String model;
+
+ /**
+ * 单位
+ */
+ private String unit;
+
+ /**
+ * 房间名称
+ */
+ private String roomName;
+
+ /**
+ * 柜体名称
+ */
+ private String bodyName;
+
+ /**
+ * 柜体板件数
+ */
+ private int bodyPlateNum;
+
+ /**
+ * 加工组类型
+ */
+ private String groupTypeName;
+
+ /**
+ * 模块名称
+ */
+ private String groupName;
+
+ /**
+ * 加工组板件数
+ */
+ private int groupNameNum;
+
+ /**
+ * 统计总数
+ */
+ private int count;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataGoodsIdGroupDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataGoodsIdGroupDO.java
new file mode 100644
index 000000000..adcb63042
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderImport/OrderImportTempDataGoodsIdGroupDO.java
@@ -0,0 +1,32 @@
+package com.cf.imes.module.plan.dal.dataobject.orderImport;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @author Gqr
+ * @since 2025/1/15 16:49
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderImportTempDataGoodsIdGroupDO implements Serializable {
+ @Serial
+ private static final long serialVersionUID = -1853615166652757427L;
+
+ /**
+ * 排序号
+ */
+ private int sortn;
+
+ /**
+ * 物料编码
+ */
+ private String outerGoodsId;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderItem/OrderItemDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderItem/OrderItemDO.java
new file mode 100644
index 000000000..239c7616b
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderItem/OrderItemDO.java
@@ -0,0 +1,78 @@
+package com.cf.imes.module.plan.dal.dataobject.orderItem;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 生产单明细表 order_item DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("order_item")
+@KeySequence("order_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderItemDO {
+
+ /**
+ * 明细编号
+ */
+ @TableId
+ private Long id;
+
+ /**
+ * 生产单号
+ */
+ private Long orderId;
+ /**
+ * 明细类型,1 板材 2 五金/配件 3 其他 4 报价配件
+ */
+ private Integer type;
+ /**
+ * 房间 ID
+ */
+ private Long roomId;
+ /**
+ * 柜体 ID
+ */
+ private Long bodyId;
+ /**
+ * 排单 ID
+ */
+ private Long planId;
+ /**
+ * 包裹 ID
+ */
+ private Long packageId;
+ /**
+ * 加工组 ID
+ */
+ private Long groupId;
+ /**
+ * 生产单板件id
+ */
+ private Long plateId;
+ /**
+ * 五金配件id
+ */
+ private Long partsId;
+ /**
+ * 部件数量
+ */
+ private Double num;
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderParts/OrderPartsDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderParts/OrderPartsDO.java
new file mode 100644
index 000000000..bb3436dfd
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderParts/OrderPartsDO.java
@@ -0,0 +1,118 @@
+package com.cf.imes.module.plan.dal.dataobject.orderParts;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 生产单配件表 order_parts_{N} DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("order_parts")
+@KeySequence("order_parts_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderPartsDO extends BaseDO {
+
+ /**
+ * 配件 ID
+ */
+ @TableId
+ private Long id;
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+ /**
+ * 生产单号
+ */
+ private Long orderId;
+ /**
+ * 商品ID
+ */
+ private String goodsId;
+ /**
+ * 配件名称
+ */
+ private String name;
+ /**
+ * 颜色
+ */
+ private String color;
+ /**
+ * 材质
+ */
+ private String material;
+ /**
+ * 配件类型
+ */
+ private String category;
+ /**
+ * 配件子类
+ */
+ private String type;
+ /**
+ * 宽度
+ */
+ private Double width;
+ /**
+ * 长度
+ */
+ private Double length;
+ /**
+ * 厚度
+ */
+ private Double thickness;
+ /**
+ * 型号
+ */
+ private String model;
+ /**
+ * 规格
+ */
+ private String spec;
+ /**
+ * 品牌
+ */
+ private String brand;
+ /**
+ * 厂家
+ */
+ private String factory;
+ /**
+ * 单位
+ */
+ private String unit;
+ /**
+ * 价格
+ */
+ private Double price;
+ /**
+ * 是否复合部件:0 否 1 是
+ */
+ private Boolean isComposite;
+ /**
+ * 子配件ID列表,复合部件时记录子配件ID,半角逗号分隔
+ */
+ private String subparts;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderParts/PartsDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderParts/PartsDO.java
new file mode 100644
index 000000000..f4272f8c2
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/orderParts/PartsDO.java
@@ -0,0 +1,110 @@
+package com.cf.imes.module.plan.dal.dataobject.orderParts;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 配件表 parts_{N} DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("parts")
+@KeySequence("parts_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PartsDO extends BaseDO {
+
+ /**
+ * 配件 ID
+ */
+ @TableId
+ private Long id;
+ /**
+ * 组织id
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+ /**
+ * 设计端商品ID
+ */
+ private String goodsId;
+ /**
+ * 配件名称
+ */
+ private String name;
+ /**
+ * 材质:颗粒板、欧松板、多层板、生态板、禾香板、密度板、实木、铝蜂窝板、铝塑板
+ */
+ private String material;
+ /**
+ * 颜色
+ */
+ private String color;
+ /**
+ * 配件类型
+ */
+ private String type;
+ /**
+ * 配件主类
+ */
+ private String category;
+ /**
+ * 型号
+ */
+ private String model;
+ /**
+ * 宽度
+ */
+ private Double width;
+ /**
+ * 长度
+ */
+ private Double length;
+ /**
+ * 厚度
+ */
+ private Double thickness;
+ /**
+ * 规格
+ */
+ private String spec;
+ /**
+ * 品牌
+ */
+ private String brand;
+ /**
+ * 厂家
+ */
+ private String factory;
+ /**
+ * 单位
+ */
+ private String unit;
+ /**
+ * 是否复合部件:0 否 1 是
+ */
+ private Boolean isComposite;
+ /**
+ * 子配件ID列表,复合部件时记录子配件ID,半角逗号分隔
+ */
+ private String subparts;
+ /**
+ * 备注
+ */
+ private String remark;
+
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderModelDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderModelDO.java
new file mode 100644
index 000000000..db8241cea
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderModelDO.java
@@ -0,0 +1,121 @@
+package com.cf.imes.module.plan.dal.dataobject.ordermodel;
+
+import com.alibaba.fastjson.JSONObject;
+import com.cf.imes.framework.es.core.dal.ESDocument;
+import com.cf.imes.module.plan.dal.elasticsearch.BasePosition;
+import com.cf.imes.module.plan.dal.elasticsearch.HoleDetail;
+import com.cf.imes.module.plan.dal.elasticsearch.ModelDetail;
+import com.cf.imes.module.plan.dal.elasticsearch.PartsInfo;
+import com.cf.imes.module.plan.dal.elasticsearch.PointDetail;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Beal
+ * 生产单 小板的轮廓数据对象
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderModelDO extends ESDocument {
+ /*@Schema(description = "组织id")
+ private Long organId;*/
+ @Schema(description = "生产单id")
+ private Long orderId;
+ @Schema(description = "小板id")
+ private Long plateId;
+
+ @Schema(description = "大板的实际ID")
+ private String goodsId;
+
+ @Schema(description = "大板的分类ID")
+ private Long plateGoodsId;
+
+ @Schema(description = "是否已优化")
+ private Boolean isOptimized;
+
+ @Schema(description = "房间的基点坐标")
+ private BasePosition roomBasePosition; // 板件基准点坐标
+ @Schema(description = "柜体的基点坐标")
+ private BasePosition bodyBasePosition; // 板件基准点坐标
+ @Schema(description = "板件的基点坐标")
+ private BasePosition plateBasePosition; // 板件基准点坐标
+
+ @Schema(description = "纹路 纹路(0正纹1可翻转2反纹)")
+ private Integer texture;
+ @Schema(description = "排版面 排钻类型(0正面1反面2随意面)")
+ private Integer typographicFace;
+ @Schema(description = "开门类型 0非门板,1左开,2右开,3上翻,4下翻")
+ private Integer openDoorType; // 字典转换
+ @Schema(description = "小板类型")
+ private String boardType;
+
+ @Schema(description = "板件配件信息")
+ private List partsInfos;
+
+ @Schema(description = "开料长")
+ private BigDecimal splitLength;
+ @Schema(description = "开料宽")
+ private BigDecimal splitWidth;
+
+
+ @Schema(description = "偏移量X")
+ private BigDecimal offsetX;
+ @Schema(description = "偏移量Y")
+ private BigDecimal offsetY;
+
+ @Schema(description = "是否有二维刀路")
+ private Boolean has2DModel;
+ @Schema(description = "是否有三维刀路")
+ private Boolean has3DModel;
+
+ @Schema(description = "点明细,表示小板外围轮廓的几个转折点(不含封边)")
+ private List pointDetail;
+ @Schema(description = "原始点明细列表")
+ private List rawPointDetail;
+ @Schema(description = "坯料点明细")
+ private List basePointDetail ; //坯料点明细
+ @Schema(description = "holes数量集合 count=孔数量 countFaceA=正面垂直孔数量] countFaceB=反面垂直孔数量] countSide=水平侧孔数量] countSideL=左侧孔数量] countSideR=右侧孔数量 countSideU=上侧孔数量 countSideD=下侧孔数量 countBevelled=斜面孔数量 countLocking=偏心轮/锁定孔数量 countBuildIn=预埋件/插入孔数量 countHinge=铰链孔数量 countThrough=通孔(对穿孔)/挖穿孔数量]")
+ private Map holeCount;//孔类型数量集合
+ @Schema(description = "孔明细列表")
+ private List holeDetail;
+ @Schema(description = "凹槽数量集合")
+ private Map contourCount;//凹槽数量集合
+ @Schema(description = "造型明细(凹槽)")
+ private List contourDetail;
+ @Schema(description = "造型明细(孤岛,现在是xml数据格式添加)")
+ private List sideDetail ; //造型明细(孤岛) sideDetail
+ @Schema(description = "侧面孔明细列表")
+ private List sideHoleDetail;
+
+ @Schema(description = "生产封边备注")
+ private Map sideRemark;// 封边备注
+ @Schema(description = "板材扩展备注")
+ private JSONObject plateExtraRemark;// 封边备注
+
+ @Schema(description = "扩展备注(包含铰链备注、订单板件流水号)")
+ private String extraRemark; // 扩展备注(包含铰链备注、订单板件流水号)(板材明细中)
+ @Schema(description = "特殊备注(Json字符串)")
+ private String specialRemarkDei; // 特殊备注(Json字符串)
+ @Schema(description = "拉手备注(Json字符串)")
+ private String extraHandleRemark; // 拉手备注
+ @Schema(description = "排钻备注(Json字符串)")
+ private String drillsRemark; // 排钻备注(Json字符串)
+ @Schema(description = "板其他备注(Json字符串)")
+ private String infoRemark; // 板其他备注(Json字符串)
+ @Schema(description = "板件备注(Json字符串)")
+ private String remarkJsonDei; // 板件备注(Json字符串)
+
+ @Schema(description = "普通备注(板材数据中)")
+ private String remarkJson; // 普通备注(板材数据中)
+ @Schema(description = "特殊备注(板材数据中)")
+ private String specialRemark; // 特殊备注(板材数据中)
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderPlateList.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderPlateList.java
new file mode 100644
index 000000000..17d9c2dbe
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderPlateList.java
@@ -0,0 +1,107 @@
+package com.cf.imes.module.plan.dal.dataobject.ordermodel;
+
+import com.alibaba.fastjson.JSONObject;
+import com.cf.imes.module.plan.dal.elasticsearch.BasePosition;
+import com.cf.imes.module.plan.dal.elasticsearch.HoleDetail;
+import com.cf.imes.module.plan.dal.elasticsearch.ModelDetail;
+import com.cf.imes.module.plan.dal.elasticsearch.PartsInfo;
+import com.cf.imes.module.plan.dal.elasticsearch.PointDetail;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderPlateList {
+
+
+ @Schema(description = "小板id")
+ private Long plateId;
+ @Schema(description = "是否已优化")
+ private Boolean isOptimized;
+ @Schema(description = "房间的基点坐标")
+ private BasePosition roomBasePosition; // 板件基准点坐标
+ @Schema(description = "柜体的基点坐标")
+ private BasePosition bodyBasePosition; // 板件基准点坐标
+ @Schema(description = "板件的基点坐标")
+ private BasePosition plateBasePosition; // 板件基准点坐标
+
+ @Schema(description = "纹路 纹路(0正纹1可翻转2反纹)")
+ private Integer texture;
+ @Schema(description = "排版面 排钻类型(0正面1反面2随意面)")
+ private Integer typographicFace;
+ @Schema(description = "开门类型 0非门板,1左开,2右开,3上翻,4下翻")
+ private Integer openDoorType; // 字典转换
+ @Schema(description = "小板类型")
+ private String boardType;
+
+ @Schema(description = "板件配件信息")
+ private List partsInfos;
+
+ @Schema(description = "开料长")
+ private BigDecimal splitLength;
+ @Schema(description = "开料宽")
+ private BigDecimal splitWidth;
+
+
+ @Schema(description = "偏移量X")
+ private BigDecimal offsetX;
+ @Schema(description = "偏移量Y")
+ private BigDecimal offsetY;
+
+ @Schema(description = "是否有二维刀路")
+ private Boolean has2DModel;
+ @Schema(description = "是否有三维刀路")
+ private Boolean has3DModel;
+
+ @Schema(description = "点明细,表示小板外围轮廓的几个转折点(不含封边)")
+ private List pointDetail;
+ @Schema(description = "原始点明细列表")
+ private List rawPointDetail;
+ @Schema(description = "坯料点明细")
+ private List basePointDetail ; //坯料点明细
+ @Schema(description = "holes数量集合 count=孔数量 countFaceA=正面垂直孔数量] countFaceB=反面垂直孔数量] countSide=水平侧孔数量] countSideL=左侧孔数量] countSideR=右侧孔数量 countSideU=上侧孔数量 countSideD=下侧孔数量 countBevelled=斜面孔数量 countLocking=偏心轮/锁定孔数量 countBuildIn=预埋件/插入孔数量 countHinge=铰链孔数量 countThrough=通孔(对穿孔)/挖穿孔数量]")
+ private Map holeCount;//孔类型数量集合
+ @Schema(description = "孔明细列表")
+ private List holeDetail;
+ @Schema(description = "凹槽数量集合")
+ private Map contourCount;//凹槽数量集合
+ @Schema(description = "造型明细(凹槽)")
+ private List contourDetail;
+ @Schema(description = "造型明细(孤岛,现在是xml数据格式添加)")
+ private List sideDetail ; //造型明细(孤岛) sideDetail
+ @Schema(description = "侧面孔明细列表")
+ private List sideHoleDetail;
+
+ @Schema(description = "生产封边备注")
+ private Map sideRemark;// 封边备注
+ @Schema(description = "板材扩展备注")
+ private JSONObject plateExtraRemark;// 封边备注
+
+ @Schema(description = "扩展备注(包含铰链备注、订单板件流水号)")
+ private String extraRemark; // 扩展备注(包含铰链备注、订单板件流水号)(板材明细中)
+ @Schema(description = "特殊备注(Json字符串)")
+ private String specialRemarkDei; // 特殊备注(Json字符串)
+ @Schema(description = "拉手备注(Json字符串)")
+ private String extraHandleRemark; // 拉手备注
+ @Schema(description = "排钻备注(Json字符串)")
+ private String drillsRemark; // 排钻备注(Json字符串)
+ @Schema(description = "板其他备注(Json字符串)")
+ private String infoRemark; // 板其他备注(Json字符串)
+ @Schema(description = "板件备注(Json字符串)")
+ private String remarkJsonDei; // 板件备注(Json字符串)
+
+ @Schema(description = "普通备注(板材数据中)")
+ private String remarkJson; // 普通备注(板材数据中)
+ @Schema(description = "特殊备注(板材数据中)")
+ private String specialRemark; // 特殊备注(板材数据中)
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderPlateModel.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderPlateModel.java
new file mode 100644
index 000000000..24673ee41
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/ordermodel/OrderPlateModel.java
@@ -0,0 +1,29 @@
+package com.cf.imes.module.plan.dal.dataobject.ordermodel;
+
+
+import com.cf.imes.framework.es.core.dal.ESDocument;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author 高级筛选数据
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderPlateModel extends ESDocument {
+
+ @Schema(description = "生产单id")
+ private Long orderId;
+
+ @Schema(description = "大板分类ID")
+ private Long plateGoodsId;
+
+ @Schema(description = "大板实际ID")
+ private String goodsId;
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/plate/PlateDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/plate/PlateDO.java
new file mode 100644
index 000000000..09c212232
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/plate/PlateDO.java
@@ -0,0 +1,218 @@
+package com.cf.imes.module.plan.dal.dataobject.plate;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+
+/**
+ * 生产单板件 DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("order_plate")
+@KeySequence("order_plate_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PlateDO extends BaseDO {
+
+ /**
+ * 板件 ID
+ */
+ @TableId
+ private Long id;
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+ /**
+ * 生产单号
+ */
+ private Long orderId;
+ /**
+ * 板名称
+ */
+ private String name;
+ /**
+ * 组织中唯一板编号
+ */
+ private String plateNo;
+ /**
+ * 板类型,0 层板 1 立板 2 背板 3 自增板
+ */
+ private Integer type;
+ /**
+ * 商品 ID
+ */
+ private Long goodsId;
+ /**
+ * 宽度
+ */
+ private BigDecimal width;
+ /**
+ * 高度
+ */
+ private BigDecimal height;
+ /**
+ * 厚度
+ */
+ private BigDecimal thickness;
+ /**
+ * 拆单宽度
+ */
+ private BigDecimal splitWidth;
+ /**
+ * 拆单高度
+ */
+ private BigDecimal splitHeight;
+ /**
+ * 拆单厚度
+ */
+ private BigDecimal splitThickness;
+ /**
+ * 左封边厚度
+ */
+ private BigDecimal sealLeft;
+ /**
+ * 右封边厚度
+ */
+ private BigDecimal sealRight;
+ /**
+ * 上封边厚度
+ */
+ private BigDecimal sealUp;
+ /**
+ * 下封边厚度
+ */
+ private BigDecimal sealDown;
+ /**
+ * 面积
+ */
+ private BigDecimal area;
+ /**
+ * 纹路类型,0 正纹 1 可翻转 2 反纹
+ */
+ private Integer texture;
+ /**
+ * 孔面类型,0 正面 1 反面 2 侧面
+ */
+ private Integer holeFace;
+ /**
+ * 排孔类型,0 正纹 1 反面 2 随意面
+ */
+ private Integer holeArrange;
+ /**
+ * 异型孔数量
+ */
+ private Integer unregularPointCount;
+ /**
+ * 正面孔数量
+ */
+ private Integer frontHoleCount;
+ /**
+ * 背面孔数量
+ */
+ private Integer backHoleCount;
+ /**
+ * 侧面孔数量
+ */
+ private Integer sideHoleCount;
+ /**
+ * 正面造型量
+ */
+ private Integer frontModelCount;
+ /**
+ * 背面造型量
+ */
+ private Integer backModelCount;
+ /**
+ * 是否门板
+ */
+ private Boolean isDoor;
+ /**
+ * 开门类型,0 无 1 左 2 右 3 上 4 下
+ */
+ private Integer openDoorType;
+ /**
+ * 异型偏移 x
+ */
+ private BigDecimal offsetX;
+ /**
+ * 异型偏移 y
+ */
+ private BigDecimal offsetY;
+ /**
+ * 是否孤形对角
+ */
+ private Boolean isArcAcross;
+ /**
+ * 模块类型 ID
+ */
+ private Long moduleTypeId;
+ /**
+ * 是否异性
+ */
+ private Boolean isSpecialShaped;
+ /**
+ * 是否造型
+ */
+ private Boolean isSculpt;
+ /**
+ * 是否造型
+ */
+ private Boolean isRowHole;
+ /**
+ * 是否优化
+ */
+ private Boolean isOptimized;
+ /**
+ * 是否开料,0:未开料,1:开料中,2:已开料
+ */
+ private Integer isCutted;
+ /**
+ * 排单过滤类型,1 有挖穿造型 2 有挖穿孔 4 有二维刀路 8 可叠
+ */
+ private String filterType;
+ /**
+ * 备注
+ */
+ private String remark;
+ /**
+ * 是否作废
+ */
+ private Boolean isCancel;
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+
+ private String customPlateNo;
+
+ /**
+ * 房间名
+ */
+ @TableField(exist = false)
+ private String roomName;
+
+ /**
+ * 柜体名
+ */
+ @TableField(exist = false)
+ private String bodyName;
+
+ @TableField(exist = false)
+ private StringBuilder customPlateNoBuilder;
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/plate/PlateGoodDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/plate/PlateGoodDO.java
new file mode 100644
index 000000000..1c59a9d31
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/plate/PlateGoodDO.java
@@ -0,0 +1,95 @@
+package com.cf.imes.module.plan.dal.dataobject.plate;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 板材信息表 plate_N DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("plate")
+@KeySequence("plate_n_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PlateGoodDO extends BaseDO {
+
+ /**
+ * 主键
+ */
+ @TableId
+ private Long id;
+ /**
+ * 客户的商品编号
+ */
+ private String goodsId;
+ /**
+ * 商品名称
+ */
+ private String goodsName;
+ /**
+ * 材质:颗粒板、欧松板、多层板、生态板、禾香板、密度板、实木、铝蜂窝板、铝塑板
+ */
+ private String material;
+ /**
+ * 颜色
+ */
+ private String color;
+ /**
+ * 背面颜色
+ */
+ private String colorBlack;
+ /**
+ * 纹路
+ */
+ private Boolean texture;
+ /**
+ * 宽度
+ */
+ private Double width;
+ /**
+ * 高度
+ */
+ private Double height;
+ /**
+ * 厚度
+ */
+ private Double thickness;
+ /**
+ * 价格
+ */
+// private Double price;
+ /**
+ * 品牌
+ */
+ private String brand;
+ /**
+ * 规格
+ */
+ private String spec;
+ /**
+ * 备注
+ */
+ private String remark;
+
+ /**
+ * 组织id
+ */
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/rawgoods/RawGoodsDO.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/rawgoods/RawGoodsDO.java
new file mode 100644
index 000000000..63b0b966e
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/dataobject/rawgoods/RawGoodsDO.java
@@ -0,0 +1,88 @@
+package com.cf.imes.module.plan.dal.dataobject.rawgoods;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * 生产单设计商品表 order_raw_goods_{N} DO
+ *
+ * @author 晨丰科技
+ */
+@TableName("order_raw_goods")
+@KeySequence("order_raw_goods_n_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class RawGoodsDO extends BaseDO {
+
+ /**
+ * id
+ */
+ @TableId
+ private Long id;
+ // 组织 ID
+ @TableField(fill = FieldFill.INSERT_UPDATE)
+ private Long organId;
+ /**
+ * 生产单号
+ */
+ private Long orderId;
+ /**
+ * 设计端商品编码
+ */
+ private String rawGoodsId;
+ /**
+ * 设计端商品名称
+ */
+ private String goodsName;
+ /**
+ * 材质
+ */
+ private String material;
+ /**
+ * 颜色
+ */
+ private String color;
+ /**
+ * 背面颜色
+ */
+ private String colorBlack;
+ /**
+ * 纹路 0 正纹 1 可翻转 2 反纹
+ */
+ private Boolean texture;
+ /**
+ * 厚度
+ */
+ private Double thickness;
+ /**
+ * 价格
+ */
+ private Double price;
+ /**
+ * 品牌
+ */
+ private String brand;
+ /**
+ * 规格
+ */
+ private String spec;
+ /**
+ * 是否删除
+ */
+ private Boolean deleted;
+
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/BasePosition.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/BasePosition.java
new file mode 100644
index 000000000..960e39f58
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/BasePosition.java
@@ -0,0 +1,30 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 基准位置,用于画图
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class BasePosition {
+ private String basePoint;// 基准点
+
+ private Double basePointX;// 基准点X坐标
+
+ private Double basePointY;// 基准点Y坐标
+
+ private Double basePointZ;// 基准点Z坐标
+
+ private Double axisXrotate;// 绕X轴旋转角度
+
+ private Double axisYrotate;// 绕Y轴旋转角度
+
+ private Double axisZrotate;// 绕Z轴旋转角度
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/DrillsInfo.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/DrillsInfo.java
new file mode 100644
index 000000000..0d0c1f951
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/DrillsInfo.java
@@ -0,0 +1,24 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 排钻类型数据
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class DrillsInfo {
+
+ private String name; // 排钻名称
+
+ private String type; // 排钻类型名称
+
+ private String face; // 排钻朝向名称
+
+ private Double count; // 排钻数量
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/HoleDetail.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/HoleDetail.java
new file mode 100644
index 000000000..e4e641252
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/HoleDetail.java
@@ -0,0 +1,100 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 孔明细,板上的孔的明细
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class HoleDetail {
+
+ @Schema(description = "孔ID")
+ private String id;
+
+ @Schema(description = "孔名称,用于类型相同的孔,进行分组区分,一组的孔名称相同")
+ private String holeName;
+
+ @Schema(description = "打孔面(0正面, 1反面, 2侧面)")
+ private Integer faceType;
+ @Schema(description = "方向 0:其他(斜方向),1:上方向,2:右方向,3:下方向,4:左方向")
+ private Integer direction;
+ @Schema(description = "孔类型(0大孔, 10小孔, 20木削, 21木削大孔, 30层板钉, 40通孔, 50连接杆, -10造型孔)")
+ private Integer holeType;
+
+ // xml无法转换数据
+ @Schema(description = "[加工面——正面、反面、左侧面、右侧面、上侧面、下侧面、斜面]")
+ private String faceTypeStr;
+ @Schema(description = "[方向——向后Z-、向前Z+、向右X+、向左X-、向下Y-、向上Y+、斜O]")
+ private String directionStr;
+ @Schema(description = "孔类型——简单孔(恒定直径的孔(盲孔、通孔/穿孔、间断孔))、沉头孔(恒定直径孔连接直径较大的孔(柱形、锥形))、锥孔、螺纹孔]")
+ private String holeTypeStr;
+
+
+ @Schema(description = "孔的起点坐标")
+ private Double startX;
+ private Double startY;
+ private Double startZ;
+
+
+ @Schema(description = " 打孔的半径-孔半径")
+ private Double radius;
+
+
+ @Schema(description = "孔的终点坐标")
+ private Double endX;
+ private Double endY;
+ private Double endZ;
+
+ @Schema(description = "深度")
+ private Double depth;
+
+ // xml新增数据
+ @Schema(description = " 沉头孔内直径")
+ private Double diameterInner;
+
+ @Schema(description = " 沉头孔(台阶孔)深孔深度")
+ private Double depthInner;
+
+ @Schema(description = " 孔组X坐标偏移")
+ private Double groupXOffset;
+
+ @Schema(description = " 孔组Y坐标偏移")
+ private Double groupYOffset;
+
+ @Schema(description = " 孔组Z坐标偏移")
+ private Double groupZOffset;
+
+ @Schema(description = " 孔组数量")
+ private Integer groupNumber;
+
+ @Schema(description = "刀号")
+ private String toolNo;
+
+ @Schema(description = "刀名称")
+ private String toolName;
+
+ @Schema(description = "刀具起点X轴旋转角度")
+ private Double toolStartRotateX;
+
+ @Schema(description = "刀具起点Y轴旋转角度")
+ private Double toolStartRotateY;
+
+ @Schema(description = "刀具起点Z轴旋转角度")
+ private Double toolStartRotateZ;
+
+ @Schema(description = "刀具终点X轴旋转角度")
+ private Double toolEndRotateX;
+
+ @Schema(description = "刀具终点Y轴旋转角度")
+ private Double toolEndRotateY;
+
+ @Schema(description = "刀具终点Z轴旋转角度")
+ private Double toolEndRotateZ;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/IContourData.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/IContourData.java
new file mode 100644
index 000000000..f569b4ef3
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/IContourData.java
@@ -0,0 +1,27 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+
+/**
+ * 轮廓数据
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = false) // 设置 chain = false,避免生产单导入有问
+public class IContourData {
+
+ @Schema(description = "点集(二维向量(x,y,z))")
+ private Point pts; //
+ @Schema(description = "凸度(0直线段 >0逆时针方向 <0顺时针方向)")
+ private Double buls; //
+ @Schema(description = "起点圆弧半径(直线段为0)")
+ private Double radius; //
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/IOriginModelingData.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/IOriginModelingData.java
new file mode 100644
index 000000000..36a56ebf9
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/IOriginModelingData.java
@@ -0,0 +1,51 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * 板的造型生成刀路数据
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = false) // 设置 chain = false,避免生产单导入有问
+public class IOriginModelingData {
+
+ @Schema(description = "刀半径")
+ private Double knifeRadius;
+
+ @Schema(description = "厚度")
+ private Double thickness; // xml中没有
+ @Schema(description = "方向")
+ private Integer dir;
+
+ // xml中修改
+ @Schema(description = "造型/凹槽(边缘)的刀路方向——内圈顺时针(最)外圈逆时针、内圈顺时针(最)外圈顺时针、内圈逆时针(最)外圈顺时针、内圈逆时针(最)外圈逆时针")
+ private String direction;
+
+ @Schema(description = "轮廓,造型最外围的轮廓数据")
+ private List outline;
+ @Schema(description = "孤岛轮廓")
+ private List> holes;
+
+
+ @Schema(description = "槽加长")
+ private Double addLen;
+ @Schema(description = "槽加宽")
+ private Double addWidth;
+ @Schema(description = "槽加深")
+ private Double addDepth;
+
+// ============ 启用 api =============
+// @Schema(description = "造型点列表")
+// private List pointList;
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/ModelDetail.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/ModelDetail.java
new file mode 100644
index 000000000..eceb2b617
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/ModelDetail.java
@@ -0,0 +1,80 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 造型明细
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Schema(description = "管理后台 - 造型信息")
+public class ModelDetail {
+
+ @Schema(description = "造型ID")
+ private Integer id;
+
+ @Schema(description = "刀路ID")
+ private Integer lineID;
+
+ @Schema(description = "内部孤岛ID集合")
+ private String[] subIDs;
+
+ @Schema(description = "类型——矩形槽Rectangle、路径槽Path、内铣槽internalMilling、折返路径槽turnbackPath")
+ private String type; // 目前只在xml中
+
+ @Schema(description = "根据是否为正面,face有不同的含义")
+ private Integer faceType;
+
+ // xml更新
+ @Schema(description = "加工面——正面、反面、左侧面、右侧面、上侧面、下侧面、斜面")
+ private String grooveFace; // 目前只在xml中
+
+ @Schema(description = "造型长度")
+ private Double width;
+ @Schema(description = "造型宽度")
+ private Double length;
+ @Schema(description = "造型深度")
+ private Double depth;
+
+ @Schema(description = "圆角半径")
+ private Double round; // 目前只在xml中
+
+ @Schema(description = "刀路冗余量(偏移重叠量)")
+ private Double redundance; // 目前只在xml中
+ @Schema(description = "角度(二维刀路V型刀提角/清角用)")
+ private Double tangentAngle; // 目前只在xml中
+
+// @Schema(description = "造型数量")
+// private Integer count;
+
+ @Schema(description = "造像使用刀具名称")
+ private String knifeName;
+ @Schema(description = "刀号")
+ private String toolNo;
+ @Schema(description = "刀半径")
+ private Double knifeRadius;
+
+
+ @Schema(description = "造型数据")
+ private IOriginModelingData originModeling;
+
+ @Schema(description = "造型点列表")
+ private List pointList;
+
+ @Schema(description = "造型偏移量列表-模块偏移数据")
+ private List offSetList;
+
+
+ // xml新增
+ @Schema(description = "加工模式/方式——由内向外、由外向内")
+ private String mode;
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OffSetList.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OffSetList.java
new file mode 100644
index 000000000..544b9cdca
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OffSetList.java
@@ -0,0 +1,39 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 偏移量列表 模块偏移数据
+ * 在有用到二维刀路的时候,需要这个数据
+ * 注:1、有用到type之类需要转换类型的诗句,将type全部存原有的值,然后在接口这一块,通过字典进行进行转换
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = false) // 设置 chain = false,避免生产单导入有问
+public class OffSetList {
+
+ @Schema(description = "偏移刀路ID")
+ private String id;
+
+// 刀路的偏移值
+ @Schema(description = "刀路的偏倚值")
+ private Double value;
+ @Schema(description = "下刀的深度")
+ private Double depth;
+ @Schema(description = "角度")
+ private Double angle;
+
+// 二维刀路的属性
+ @Schema(description = "二维刀路的属性-刀的名称")
+ private String name;
+ @Schema(description = "二维刀路的属性-刀的半径")
+ private Double radius; // api中为直径
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OrderGoodsPlateIds.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OrderGoodsPlateIds.java
new file mode 100644
index 000000000..359d7d8d8
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OrderGoodsPlateIds.java
@@ -0,0 +1,23 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import lombok.Data;
+
+
+@Data
+public class OrderGoodsPlateIds {
+
+
+ private Long id;
+
+
+ private Long orderId;
+
+
+ private String actualGoodsId;
+
+
+ private Long goodsId;
+
+}
+
+
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OrderPartsRemark.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OrderPartsRemark.java
new file mode 100644
index 000000000..b7aca559f
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/OrderPartsRemark.java
@@ -0,0 +1,38 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import com.cf.imes.framework.es.core.dal.ESDocument;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Schema(description = "管理后台 - 生产单配件 备注信息")
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderPartsRemark extends ESDocument {
+
+ @Schema(description = "配件 ID")
+ private Long partsId;
+
+ @Schema(description = "生产单号")
+ private Long orderId;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "额外规格")
+ private String specExtras;
+
+ @Schema(description = "门板组件铰链备注")
+ private String doorRemark;
+
+ @Schema(description = "门板组件拉手备注")
+ private String hingeRemark;
+
+ @Schema(description = "特殊备注(Json字符串)")
+ private String specialRemark;
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PartsInfo.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PartsInfo.java
new file mode 100644
index 000000000..827b555b4
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PartsInfo.java
@@ -0,0 +1,25 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 配件基本信息
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class PartsInfo {
+
+ private Long id; // 配件标识
+ private String name; // 配件名称
+
+// 单个配件的数量
+ private Double partNum;
+
+// 配件数量单位
+ private String unit;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PlateDetail.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PlateDetail.java
new file mode 100644
index 000000000..0d2a7fb2d
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PlateDetail.java
@@ -0,0 +1,128 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * CAD板件信息详情
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class PlateDetail {
+ // 组织id
+ private Long organId;
+ // 生产单id
+ private Long orderId;
+ // 板名称
+ private String name;
+ // 板id
+ private Long plateId;
+ // 设计板编号
+ private String plateNo;
+ // 设计板编号
+ private String customPlateNo;
+
+ private Integer texture; //纹路 纹路(0正纹1可翻转2反纹)
+ private Integer typographicFace; //排版面 排钻类型(0正面1反面2随意面)
+ private Integer openDoorType; //开门类型 0非门板,1左开,2右开,3上翻,4下翻 字典转换
+ private String boardType; // 小板类型
+
+
+ // 板件所属信息
+ private String roomsName; //房间名称
+ private String roomNo; // 房间号
+ private String bodyName; //柜体名
+ private String bodyNo; // 柜体号
+ private String groupName; //加工组号
+ private String groupNo; // 加工组名称
+ // 柜体 长 宽 深
+ private Double width;
+ private Double height;
+ private Double depth;
+
+ // 柜体成倍拆单的倍数
+ private Integer multiNum;
+
+
+ // 板材所属加工组
+ private String group;// 板件加工组Group的名称,可以有多个
+// 加工组具体信息
+// private List groupList;
+
+ // 成品长宽、面积
+ private BigDecimal plateWidth;
+ private BigDecimal plateLength;
+ private BigDecimal acreage;
+
+ // 开料长宽、面积
+ private BigDecimal splitLength;
+ private BigDecimal splitWidth;
+ private BigDecimal sealAcreage;
+
+ // 是否异形
+ private Boolean isUnRegular;
+ // 封边,用于矩形
+ private BigDecimal sealLeft;
+ private BigDecimal sealRight;
+ private BigDecimal sealUp;
+ private BigDecimal sealDown;
+
+
+ // 偏移量
+ private BigDecimal offsetX;
+ private BigDecimal offsetY;
+ private Boolean isHXDJX; // 是否弧形地脚
+
+ // 大板基本信息
+// private BoardInfo boardInfo;
+// 配件基本信息
+ private List partsInfos; // xml中有,估计之后不需要
+ // 排钻类型
+ private List drillsInfos; // api中有
+
+ private Double throughHoleCount; // 挖孔的孔数
+ private Double throughModelCount; // 挖穿的造型数
+
+ private Boolean has2DModel; // 是否有二维刀路
+ private Boolean has3DModel; // 是否有三维刀路
+
+ // 轮廓数据、造型数据
+ private BasePosition roomBasePosition; // 板件基准点坐标
+ private BasePosition bodyBasePosition; // 柜体基准点坐标
+ private BasePosition plateBasePosition; // 板件基准点坐标
+ private List pointDetail; //点明细,表示小板外围轮廓的几个转折点(不含封边)
+ private List rawPointDetail; //原始点明细(含封边)
+ private List basePointDetail; //坯料点明细 (xml中特有,现可以不用)
+
+ private Map holeCount;//孔类型数量集合 (xml中特有----孔类型,对应的数量)
+ private List holeDetail; //孔明细,表示板上的孔
+ private Map contourCount;//凹槽数量集合 (xml中特有----槽所在板面的对应数量)
+ private List contourDetail; //造型明细(xml中为凹槽,将孤岛的信息放入槽中)
+ private List sideDetail; //造型明细(侧面)
+
+ private List sideHoleDetail;//侧面孔明细
+
+ // 备注
+ private Map plateRemark;// 板件备注 (生产数据接口中)(不用)
+ private Map sideRemark;// 板边备注
+ private JSONObject plateExtraRemark;// 板材扩展备注 (不含板件的备注)
+
+ private String extraRemark; // 扩展备注(包含铰链备注、订单板件流水号)(板材明细中)
+ private String specialRemarkDei; // 特殊备注(Json字符串)
+ private String extraHandleRemark; // 拉手备注
+ private String drillsRemark; // 排钻备注(Json字符串)
+ private String infoRemark; // 板其他备注(Json字符串)
+ private String remarkJsonDei; // 板件备注(Json字符串)
+
+ private String remarkJson; // 普通备注(板材数据中)
+ private String specialRemark; // 特殊备注(板材数据中)
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/Point.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/Point.java
new file mode 100644
index 000000000..55717ecc4
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/Point.java
@@ -0,0 +1,19 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Beal
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class Point {
+ private Double x;
+ private Double y;
+ private Double z;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PointDetail.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PointDetail.java
new file mode 100644
index 000000000..579dc6469
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PointDetail.java
@@ -0,0 +1,39 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+
+/**
+ * 点明细 , 表示小板外围轮廓的几个转折点
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = false) // 设置 chain = false,避免生产单导入有问
+public class PointDetail {
+
+ @Schema(description = "点id")
+ private String id;
+ // 点的位置信息
+ @Schema(description = "点的位置信息")
+ private Double pointX;
+ private Double pointY;
+ @Schema(description = "曲线-凸度")
+ private Double curve;
+ @Schema(description = "边圆弧半径(直线段为0)")
+ private Double radius;
+
+ // 点的封边尺寸
+ @Schema(description = "点的封边尺寸,封边尺寸,封边的厚度,长同边长")
+ private BigDecimal sealSize;
+
+ @Schema(description = "加工工艺")
+ private String process;
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PointList.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PointList.java
new file mode 100644
index 000000000..e368e62b2
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/elasticsearch/PointList.java
@@ -0,0 +1,39 @@
+package com.cf.imes.module.plan.dal.elasticsearch;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 点列表
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Accessors(chain = false) // 设置 chain = false,避免生产单导入有问
+public class PointList {
+
+ @Schema(description = "纹路Id")
+ private Integer lineId;
+ @Schema(description = "点Id")
+ private Integer pointId;
+
+
+ @Schema(description = "点的位置信息")
+ private Double pointX;
+ private Double pointY;
+ private Double pointZ;
+ private Double radius;
+
+ @Schema(description = "曲线")
+ private Double curve;
+ @Schema(description = "曲线深度")
+ private Double depth;
+ @Schema(description = "起点圆弧半径(直线段为0)")
+ private Double holeRadius;
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/goods/GoodsMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/goods/GoodsMapper.java
new file mode 100644
index 000000000..5751deb70
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/goods/GoodsMapper.java
@@ -0,0 +1,14 @@
+package com.cf.imes.module.plan.dal.mysql.goods;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.goods.GoodsDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单商品 Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface GoodsMapper extends BaseBatchMapper {
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/order/OrderMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/order/OrderMapper.java
new file mode 100644
index 000000000..c1d91cd1a
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/order/OrderMapper.java
@@ -0,0 +1,14 @@
+package com.cf.imes.module.plan.dal.mysql.order;
+
+import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
+import com.cf.imes.module.plan.dal.dataobject.order.OrderDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单表 order_{N} Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface OrderMapper extends BaseMapperX {
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderBody/OrderBodyMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderBody/OrderBodyMapper.java
new file mode 100644
index 000000000..e4cee8ccb
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderBody/OrderBodyMapper.java
@@ -0,0 +1,14 @@
+package com.cf.imes.module.plan.dal.mysql.orderBody;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.orderBody.OrderBodyDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单柜体 Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface OrderBodyMapper extends BaseBatchMapper {
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderGroup/OrderGroupMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderGroup/OrderGroupMapper.java
new file mode 100644
index 000000000..8fe0f16eb
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderGroup/OrderGroupMapper.java
@@ -0,0 +1,13 @@
+package com.cf.imes.module.plan.dal.mysql.orderGroup;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.orderGroup.OrderGroupDO;
+import org.apache.ibatis.annotations.Mapper;
+/**
+ * 生产单加工组 Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface OrderGroupMapper extends BaseBatchMapper {
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderImport/OrderImportTaskMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderImport/OrderImportTaskMapper.java
new file mode 100644
index 000000000..56655e47e
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderImport/OrderImportTaskMapper.java
@@ -0,0 +1,15 @@
+package com.cf.imes.module.plan.dal.mysql.orderImport;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTaskDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单导入任务 Mapper
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:42
+ */
+@Mapper
+public interface OrderImportTaskMapper extends BaseMapper {
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderImport/OrderImportTempDataMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderImport/OrderImportTempDataMapper.java
new file mode 100644
index 000000000..1acb01472
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderImport/OrderImportTempDataMapper.java
@@ -0,0 +1,156 @@
+package com.cf.imes.module.plan.dal.mysql.orderImport;
+
+import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
+import com.cf.imes.module.plan.controller.orderImport.vo.OrderImportTempDataReqVO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTempDataDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTempDataGoodsGroupDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTempDataGoodsIdGroupDO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 生产单导入临时表 Mapper
+ *
+ * @author Gqr
+ * @since 2025/1/9 11:42
+ */
+@Mapper
+public interface OrderImportTempDataMapper extends BaseMapperX {
+ /**
+ * 基于物料编码分组的总数查询
+ *
+ * @param reqVO
+ * @return
+ */
+ int selectCountGoodsIdGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于物料编码的分组查询(可分页)
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectGoodsIdGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于商品名称、材料、纹理、颜色、规格、商品高、商品宽、商品厚、品牌分组的商品总数查询
+ *
+ * @param reqVO
+ * @return
+ */
+ int selectCountPlateGoodsGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于商品名称、材料、纹理、颜色、规格、商品高、商品宽、商品厚、品牌的商品分组查询(可分页)
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectPlateGoodsGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于商品名称、材料、复合部件、配件类型、配件子类、厂家、型号、规格、、商品高、商品宽、商品厚、单位、品牌分组的配件总数查询
+ *
+ * @param reqVO
+ * @return
+ */
+ int selectCountPartGoodsGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于商品名称、材料、复合部件、配件类型、配件子类、厂家、型号、规格、、商品高、商品宽、商品厚、单位、品牌的配件分组查询
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectPartGoodsGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于房间名的分组总数查询
+ *
+ * @param taskId
+ * @return
+ */
+ int selectCountRoomGroup(@Param("taskId") Long taskId);
+
+ /**
+ * 基于房间名的分组查询
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectRoomGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于房间名下柜体名的分组总数查询
+ *
+ * @param reqVO
+ * @return
+ */
+ int selectCountBodyGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于房间名下柜体名的分组查询
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectBodyGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于房间名、柜体名下的加工组类型名称分组总数查询
+ *
+ * @param reqVO
+ * @return
+ */
+ int selectCountGroupTypeNameGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于房间名、柜体名下的加工组类型名称分组查询
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectGroupTypeNameGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于房间名、柜体名、加工组类型名称下的加工组名称分组总数查询
+ *
+ * @param reqVO
+ * @return
+ */
+ int selectCountGroupNameGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 基于房间名、柜体名、加工组类型名称下的加工组名称分组查询
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectGroupNameGroup(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 查询房间名、柜体名、加工组类型名称、加工组名称下的总数
+ *
+ * @param reqVO
+ * @return
+ */
+ int selectCountGroupName(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 查询房间名、柜体名、加工组类型名称、加工组名称下的临时数据列表
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectGroupNameList(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+
+ /**
+ * 查询配件商品id下的临时数据列表
+ *
+ * @param reqVO
+ * @return
+ */
+ List selectPartList(@Param("reqVO") OrderImportTempDataReqVO reqVO);
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderItem/OrderItemMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderItem/OrderItemMapper.java
new file mode 100644
index 000000000..3a348ae96
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderItem/OrderItemMapper.java
@@ -0,0 +1,14 @@
+package com.cf.imes.module.plan.dal.mysql.orderItem;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.orderItem.OrderItemDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单明细表 order_item Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface OrderItemMapper extends BaseBatchMapper {
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderParts/OrderPartsMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderParts/OrderPartsMapper.java
new file mode 100644
index 000000000..c1a7c1d93
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderParts/OrderPartsMapper.java
@@ -0,0 +1,14 @@
+package com.cf.imes.module.plan.dal.mysql.orderParts;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.orderParts.OrderPartsDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单配件表 order_parts_{N} Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface OrderPartsMapper extends BaseBatchMapper {
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderParts/PartsMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderParts/PartsMapper.java
new file mode 100644
index 000000000..fa2570d10
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/orderParts/PartsMapper.java
@@ -0,0 +1,18 @@
+package com.cf.imes.module.plan.dal.mysql.orderParts;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.orderParts.PartsDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 配件表 parts_{N} Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface PartsMapper extends BaseBatchMapper {
+ default PartsDO selectByGoodID(String goodId , Long organId) {
+ return selectOne(new LambdaQueryWrapper().eq(PartsDO::getGoodsId, goodId).eq(PartsDO::getOrganId, organId));
+ }
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/plate/PlateGoodMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/plate/PlateGoodMapper.java
new file mode 100644
index 000000000..bacd05034
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/plate/PlateGoodMapper.java
@@ -0,0 +1,45 @@
+package com.cf.imes.module.plan.dal.mysql.plate;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.plate.PlateGoodDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 板材信息 Mapper plate
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface PlateGoodMapper extends BaseBatchMapper {
+ default List selectGoodOne(String id, Long organId) {
+ return selectList(new LambdaQueryWrapper()
+ .eq(PlateGoodDO::getGoodsId, id)
+ .eq(PlateGoodDO::getDeleted, 0)
+ .eq(PlateGoodDO::getOrganId, organId));
+ }
+
+ default List selectGood(String goodsName, String material, String color, Boolean texture, BigDecimal width,
+ BigDecimal thickness, BigDecimal height, String brand, String spec, Long organId) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper()
+ .eq(PlateGoodDO::getGoodsName, goodsName)
+ .eq(PlateGoodDO::getMaterial, material)
+ .eq(PlateGoodDO::getColor, color)
+ .eq(PlateGoodDO::getTexture, texture)
+ .eq(PlateGoodDO::getWidth, width)
+ .eq(PlateGoodDO::getHeight, height)
+ .eq(PlateGoodDO::getThickness, thickness)
+ .eq(PlateGoodDO::getSpec, spec)
+ .eq(PlateGoodDO::getDeleted, 0)
+ .eq(PlateGoodDO::getOrganId, organId);
+ if (brand == null) {
+ queryWrapper.eq(PlateGoodDO::getBrand,"");
+ }else {
+ queryWrapper.eq(PlateGoodDO::getBrand, brand);
+ }
+ return selectList(queryWrapper);
+ }
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/plate/PlateMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/plate/PlateMapper.java
new file mode 100644
index 000000000..586eec091
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/plate/PlateMapper.java
@@ -0,0 +1,14 @@
+package com.cf.imes.module.plan.dal.mysql.plate;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.plate.PlateDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单板件 Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface PlateMapper extends BaseBatchMapper {
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/rawgoods/RawGoodsMapper.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/rawgoods/RawGoodsMapper.java
new file mode 100644
index 000000000..088fba921
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/dal/mysql/rawgoods/RawGoodsMapper.java
@@ -0,0 +1,14 @@
+package com.cf.imes.module.plan.dal.mysql.rawgoods;
+
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.module.plan.dal.dataobject.rawgoods.RawGoodsDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 生产单设计商品表 order_raw_goods_{N} Mapper
+ *
+ * @author 晨丰科技
+ */
+@Mapper
+public interface RawGoodsMapper extends BaseBatchMapper {
+}
\ No newline at end of file
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/framework/rpc/config/RpcConfiguration.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/framework/rpc/config/RpcConfiguration.java
index 519fea409..eca90da00 100644
--- a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/framework/rpc/config/RpcConfiguration.java
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/framework/rpc/config/RpcConfiguration.java
@@ -1,5 +1,6 @@
package com.cf.imes.module.plan.framework.rpc.config;
+import com.cf.imes.module.system.api.dict.DictDataApi;
import com.cf.imes.module.system.api.user.AdminUserApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@@ -8,6 +9,6 @@ import org.springframework.context.annotation.Configuration;
* @author there
*/
@Configuration(proxyBeanMethods = false)
-@EnableFeignClients(clients = AdminUserApi.class)
+@EnableFeignClients(clients = {AdminUserApi.class, DictDataApi.class})
public class RpcConfiguration {
}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/order/OrderInputProcessor.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/order/OrderInputProcessor.java
new file mode 100644
index 000000000..e66cc31d7
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/order/OrderInputProcessor.java
@@ -0,0 +1,124 @@
+package com.cf.imes.module.plan.service.order;
+
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.IdUtil;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch._types.ElasticsearchException;
+import co.elastic.clients.elasticsearch.core.BulkRequest;
+import co.elastic.clients.elasticsearch.core.BulkResponse;
+import co.elastic.clients.elasticsearch.core.DeleteByQueryRequest;
+import co.elastic.clients.elasticsearch.core.DeleteByQueryResponse;
+import com.cf.imes.framework.common.exception.ServiceException;
+import com.cf.imes.framework.es.core.dal.ESDocument;
+import com.cf.imes.module.plan.dal.dataobject.ordermodel.OrderModelDO;
+import com.cf.imes.module.plan.dal.elasticsearch.OrderPartsRemark;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
+
+/**
+ * @author Beal
+ * 生产单入库处理器
+ */
+@Slf4j
+@Component
+public class OrderInputProcessor {
+
+ @Resource
+ private ElasticsearchClient elasticsearchClient;
+
+ private Snowflake snowflake = IdUtil.getSnowflake();
+
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ public static final String ORDER_PLATE_MODEL = "imes_order_plate_model";
+
+
+ public static final String ORDER_PLATE_MODEL_COMPRESS = "imes_order_plate_model_compress";
+
+ public static final String ORDER_PARTS_REMARK_MODEL = "imes_order_parts_remark_model";
+
+ private static final String FIELD_ORDER_ID = "orderId";
+
+ /**
+ * 保存生产单造型数据
+ *
+ * @param orderModelDOs
+ */
+ public void batchSaveModel(List orderModelDOs) {
+ try {
+ BulkResponse bulkResponse = bulkCreate(ORDER_PLATE_MODEL, orderModelDOs);
+ boolean errors = bulkResponse.errors();
+ if (errors) {
+ log.error(bulkResponse.items().toString());
+ throw new ServiceException(500, "未知异常");
+ }
+ } catch (IOException | ElasticsearchException e) {
+ e.printStackTrace();
+ log.error(e.getMessage());
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public void deleteByOrderId(Long orderId, String index) {
+ DeleteByQueryRequest.Builder builder = new DeleteByQueryRequest.Builder();
+ builder.index(index);
+ builder.query(q -> q.term(t -> t.field(FIELD_ORDER_ID).value(orderId)));
+
+ try {
+ DeleteByQueryResponse response = elasticsearchClient.deleteByQuery(builder.build());
+ log.info("Deleted {} documents with planId {}", response.deleted(), orderId);
+ } catch (IOException | ElasticsearchException e) {
+ log.error("Error deleting documents with planId {}: {}", orderId, e.getMessage());
+ throw new ServiceException(INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ /**
+ * 保存生产单配件备注数据
+ *
+ * @param orderPartsRemarks
+ */
+ public void batchSaveOrderPartsModel(List orderPartsRemarks) {
+ try {
+ BulkResponse bulkResponse = bulkCreate(ORDER_PARTS_REMARK_MODEL, orderPartsRemarks);
+ boolean errors = bulkResponse.errors();
+ if (errors) {
+ log.error(bulkResponse.items().toString());
+ throw new ServiceException(500, "未知异常");
+ }
+ } catch (IOException | ElasticsearchException e) {
+ e.printStackTrace();
+ log.error(e.getMessage());
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public BulkResponse bulkCreate(String idxName, List extends ESDocument> documents) throws IOException, ElasticsearchException {
+ BulkRequest.Builder br = new BulkRequest.Builder();
+ Date date = new Date();
+ documents.forEach(esDocument -> {
+ if (CharSequenceUtil.isBlank(esDocument.getId())) {
+ esDocument.setId(snowflake.nextIdStr());
+ }
+ esDocument.setCreateTime(simpleDateFormat.format(date));
+
+ esDocument.setUpdateTime(simpleDateFormat.format(date));
+ br.operations(op -> op.index(idx -> idx
+ .index(idxName)
+ .id(esDocument.getId())
+ .document(esDocument)));
+ });
+ return elasticsearchClient.bulk(br.build());
+ }
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/consumer/DefaultExcelOrderImportConsumer.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/consumer/DefaultExcelOrderImportConsumer.java
new file mode 100644
index 000000000..8737a8c7c
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/consumer/DefaultExcelOrderImportConsumer.java
@@ -0,0 +1,261 @@
+package com.cf.imes.module.plan.service.orderImport.consumer;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.cf.imes.framework.common.enums.OrderPackageStatusEnum;
+import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
+import com.cf.imes.framework.common.util.json.JsonUtils;
+import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
+import com.cf.imes.module.executor.enums.OrderStatusEnum;
+import com.cf.imes.module.plan.dal.mysql.orderParts.PartsMapper;
+import com.cf.imes.module.plan.dal.mysql.plate.PlateGoodMapper;
+import com.cf.imes.module.plan.service.order.OrderInputProcessor;
+import com.cf.imes.module.plan.service.orderImport.factory.DefaultExcelOrderImportFactory;
+import com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants;
+import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
+import com.cf.imes.framework.organ.core.context.OrganContextHolder;
+import com.cf.imes.framework.redis.constants.RedisKeyConstants;
+import com.cf.imes.framework.redis.util.RedisLockUtil;
+import com.cf.imes.module.executor.enums.OrderImportStatusEnum;
+import com.cf.imes.module.executor.enums.OrderImportTaskStatusEnum;
+import com.cf.imes.module.executor.enums.OrderImportTmpDataTypeEnum;
+import com.cf.imes.module.plan.dal.dataobject.order.OrderDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTaskDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTempDataDO;
+import com.cf.imes.module.plan.dal.mysql.goods.GoodsMapper;
+import com.cf.imes.module.plan.dal.mysql.order.OrderMapper;
+import com.cf.imes.module.plan.dal.mysql.orderBody.OrderBodyMapper;
+import com.cf.imes.module.plan.dal.mysql.orderGroup.OrderGroupMapper;
+import com.cf.imes.module.plan.dal.mysql.orderImport.OrderImportTaskMapper;
+import com.cf.imes.module.plan.dal.mysql.orderImport.OrderImportTempDataMapper;
+import com.cf.imes.module.plan.dal.mysql.orderItem.OrderItemMapper;
+import com.cf.imes.module.plan.dal.mysql.orderParts.OrderPartsMapper;
+import com.cf.imes.module.plan.dal.mysql.plate.PlateMapper;
+import com.cf.imes.module.plan.dal.mysql.rawgoods.RawGoodsMapper;
+import com.cf.imes.module.system.api.dict.DictDataApi;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.amqp.support.AmqpHeaders;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.util.Objects;
+import java.util.Optional;
+
+import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_IMPORT_ORDER_NOT_EXISTS;
+import static com.cf.imes.module.plan.enums.ErrorCodeConstants.ORDER_IMPORT_FAIL;
+import static com.cf.imes.module.plan.enums.ErrorCodeConstants.ORDER_IMPORT_ORGANID_NOT_EXISTS;
+
+/**
+ * 默认excel导入生产单消费者
+ *
+ * @author Gqr
+ * @since 2025/1/6 11:18
+ */
+@Component
+@Slf4j
+public class DefaultExcelOrderImportConsumer {
+
+ @Resource
+ private OrderImportTaskMapper orderImportTaskMapper;
+
+ @Resource
+ private OrderImportTempDataMapper orderImportTempDataMapper;
+
+ @Resource
+ private OrderMapper orderMapper;
+
+ @Resource
+ private RedisLockUtil redisLockUtil;
+
+ @Resource
+ private SnowFlakeGenerator snowFlakeGenerator;
+
+ @Resource
+ private SnowflakeIdWorker3rd idWorker;
+
+ @Resource
+ private DictDataApi dictDataApi;
+
+ @Resource
+ private GoodsMapper goodsMapper;
+
+ @Resource
+ private RawGoodsMapper rawGoodsMapper;
+
+ @Resource
+ private OrderPartsMapper orderPartsMapper;
+
+ @Resource
+ private OrderBodyMapper orderBodyMapper;
+
+ @Resource
+ private OrderGroupMapper orderGroupMapper;
+
+ @Resource
+ private PlateMapper plateMapper;
+
+ @Resource
+ private OrderItemMapper orderItemMapper;
+
+ @Resource
+ private PlateGoodMapper plateGoodMapper;
+
+ @Resource
+ private OrderInputProcessor orderInputProcessor;
+
+ @Resource
+ private PartsMapper partsMapper;
+
+ @RabbitListener(queues = RabbitMqConstants.ORDER_IMPORT_DEFAULT_EXCEL_QUEUE)
+ @DS("imes_prod")
+ @Transactional(rollbackFor = Exception.class)
+ public void orderImport(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws Exception {
+ Long organId = null;
+ Long taskId = Long.parseLong(message);
+ try {
+ organId = OrganContextHolder.getOrganId();
+ if (ObjectUtil.isNull(organId)) {
+ throw ServiceExceptionUtil.exception(ORDER_IMPORT_ORGANID_NOT_EXISTS);
+ }
+ // 确认任务,更新状态为消费成功,没有找到任务中断后续消费
+ OrderImportTaskDO orderImportTaskDO = confirmOrderImport(taskId);
+ if (ObjectUtil.isNull(orderImportTaskDO)) {
+ return;
+ }
+ // 创建生产单
+ Long orderId = createOrder(taskId);
+ // 创建工厂
+ DefaultExcelOrderImportFactory defaultExcelOrderImportFactory = new DefaultExcelOrderImportFactory(taskId, orderId, organId, orderImportTaskDO.getCreator(),
+ snowFlakeGenerator, idWorker, orderImportTaskMapper, orderImportTempDataMapper, dictDataApi, goodsMapper, rawGoodsMapper, orderPartsMapper,
+ orderBodyMapper, orderGroupMapper, plateMapper, orderItemMapper, plateGoodMapper, orderInputProcessor, partsMapper);
+ // 解析临时表数据
+ defaultExcelOrderImportFactory.analyzeTempData();
+ } catch (Exception e) {
+ // 确认消息进入死信队列
+ channel.basicNack(deliveryTag, false, false);
+ String importFailNotify = ORDER_IMPORT_FAIL.getMsg();
+ // 更新状态为消费失败、导入失败
+ orderImportTaskMapper.update(new LambdaUpdateWrapper().eq(OrderImportTaskDO::getId, taskId)
+ .set(OrderImportTaskDO::getStatus, OrderImportTaskStatusEnum.CONSUME_FAIL.getStatus())
+ .set(OrderImportTaskDO::getImportStatus, OrderImportStatusEnum.IMPORT_FAIL.getStatus())
+ .set(OrderImportTaskDO::getResult, importFailNotify));
+ log.error(importFailNotify, e);
+ throw e;
+ } finally {
+ // 手动确认消息接收
+ channel.basicAck(deliveryTag, false);
+ // 导入锁解锁
+ redisLockUtil.unlock(String.format(RedisKeyConstants.ORDER_IMPORT_LOCK_KEY, organId), message);
+ }
+ }
+
+ /**
+ * 确认导入任务,更新任务状态
+ *
+ * @param taskId
+ */
+ private OrderImportTaskDO confirmOrderImport(Long taskId) {
+ boolean taskExist = false;
+ OrderImportTaskDO orderImportTaskDO = null;
+ // 线程每1s查询一次,查三次没有就提示任务不存在
+ for (int i = 0; i < 3; i++) {
+ orderImportTaskDO = orderImportTaskMapper.selectById(taskId);
+ if (ObjectUtil.isNotNull(orderImportTaskDO)) {
+ taskExist = true;
+ break;
+ } else {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ log.error("====================【线程中断异常】====================");
+ }
+ }
+ }
+ if (taskExist) {
+ // 更新状态为消费成功
+ orderImportTaskMapper.update(new LambdaUpdateWrapper().eq(OrderImportTaskDO::getId, taskId).set(OrderImportTaskDO::getStatus, OrderImportTaskStatusEnum.CONSUME_SUCCESS.getStatus()));
+ } else {
+ String taskNotExistNotify = String.format("%s不存在的导入任务,消费中止", taskId);
+ // 更新状态为消费成功,导入失败
+ orderImportTaskMapper.update(
+ new LambdaUpdateWrapper()
+ .eq(OrderImportTaskDO::getId, taskId)
+ .set(OrderImportTaskDO::getStatus, OrderImportTaskStatusEnum.CONSUME_SUCCESS.getStatus())
+ .set(OrderImportTaskDO::getImportStatus, OrderImportStatusEnum.IMPORT_FAIL.getStatus())
+ .set(OrderImportTaskDO::getResult, taskNotExistNotify)
+ );
+ log.error(String.format("====================【%s】====================", taskNotExistNotify));
+ }
+ return orderImportTaskDO;
+ }
+
+ /**
+ * 创建生产单
+ *
+ * @param taskId
+ * @return
+ */
+ private Long createOrder(Long taskId) {
+ // 查询临时表中的order
+ LambdaQueryWrapper orderTempData = new LambdaQueryWrapper()
+ .eq(OrderImportTempDataDO::getTaskId, taskId)
+ .eq(OrderImportTempDataDO::getType, OrderImportTmpDataTypeEnum.ORDER.getType())
+ .eq(OrderImportTempDataDO::getSort, 0);
+ OrderImportTempDataDO orderImportTempDataDO = orderImportTempDataMapper.selectOne(orderTempData);
+ // 不是新单不用创建
+ if (ObjectUtil.isNotNull(orderImportTempDataDO) && ObjectUtil.isNotNull(orderImportTempDataDO.getOrderId())) {
+ Long existOrderId = orderImportTempDataDO.getOrderId();
+ // 校验生产单id
+ OrderDO orderDO = orderMapper.selectById(existOrderId);
+ Optional.ofNullable(orderDO).orElseThrow(() -> ServiceExceptionUtil.exception(ORDER_IMPORT_ORDER_NOT_EXISTS, existOrderId));
+ // 更新补板生产单属性
+ updateOrder(orderDO);
+ return existOrderId;
+ }
+ // 取临时order数据,detail转orderDO,插入新增orderDO
+ String orderTempDetail = JsonUtils.unzipString(orderImportTempDataDO.getDetail());
+ OrderDO newOrder = JSON.parseObject(orderTempDetail, OrderDO.class);
+ Long orderId = (Long) snowFlakeGenerator.nextId(null);
+ newOrder.setId(orderId);
+ orderMapper.insert(newOrder);
+ // 生产单id更新到导入任务表
+ orderImportTaskMapper.update(new LambdaUpdateWrapper()
+ .eq(OrderImportTaskDO::getId, taskId)
+ .set(OrderImportTaskDO::getOrderId, orderId));
+ return orderId;
+ }
+
+ /**
+ * 更新补板生产单的属性
+ *
+ * @param orderDO
+ */
+ public void updateOrder(OrderDO orderDO) {
+ // 发货日期校验
+ LocalDate orderDate = LocalDate.from(orderDO.getOrderDate());
+ LocalDate deliveryDate = LocalDate.from(orderDO.getDeliveryDate());
+ if (deliveryDate.isBefore(orderDate)) {
+ // 将 deliveryDate 设置为 orderDate 后的第 30 天
+ deliveryDate = orderDate.plusMonths(1);
+ }
+ orderDO.setDeliveryDate(deliveryDate.atStartOfDay());
+ if (Objects.equals(orderDO.getStatus(), OrderStatusEnum.EMPTY.getStatus())) {
+ orderDO.setStatus(OrderStatusEnum.NEW_ORDER.getStatus());
+ }
+ if (Objects.equals(orderDO.getStatus(), OrderStatusEnum.FINISH_PRODUCTION.getStatus())) {
+ orderDO.setStatus(OrderStatusEnum.IN_PRODUCTION.getStatus());
+ }
+ if (Objects.equals(orderDO.getPackaged(), OrderPackageStatusEnum.PACKAGED.getStatus())) {
+ orderDO.setPackaged(OrderPackageStatusEnum.PACKAGED.getStatus());
+ }
+ orderMapper.updateById(orderDO);
+ }
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/consumer/OrderImportDeadLetterConsumer.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/consumer/OrderImportDeadLetterConsumer.java
new file mode 100644
index 000000000..a32e7e840
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/consumer/OrderImportDeadLetterConsumer.java
@@ -0,0 +1,45 @@
+package com.cf.imes.module.plan.service.orderImport.consumer;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.cf.imes.framework.organ.core.context.OrganContextHolder;
+import com.cf.imes.framework.redis.constants.RedisKeyConstants;
+import com.cf.imes.framework.redis.util.RedisLockUtil;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.amqp.support.AmqpHeaders;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+
+import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_QUEUE;
+
+/**
+ * 生产单导入死信队列消费
+ *
+ * @author Gqr
+ * @since 2025/2/12 10:48
+ */
+@Component
+@Slf4j
+public class OrderImportDeadLetterConsumer {
+
+ @Resource
+ private RedisLockUtil redisLockUtil;
+
+ @RabbitListener(queues = ORDER_IMPORT_DEAD_LETTER_QUEUE)
+ public void receiveA(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException {
+ log.info("====================【生产单导入收到死信消息:{}】====================", message);
+ // 手动确认消息
+ channel.basicAck(deliveryTag, false);
+
+ // 导入锁解锁
+ Long organId = OrganContextHolder.getOrganId();
+ if (ObjectUtil.isNotNull(organId)) {
+ redisLockUtil.unlock(String.format(RedisKeyConstants.ORDER_IMPORT_LOCK_KEY, organId), message);
+ }
+ }
+
+}
diff --git a/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/DefaultExcelOrderImportFactory.java b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/DefaultExcelOrderImportFactory.java
new file mode 100644
index 000000000..c796c2842
--- /dev/null
+++ b/cf-module-prod-plan/cf-module-prod-plan-biz/src/main/java/com/cf/imes/module/plan/service/orderImport/factory/DefaultExcelOrderImportFactory.java
@@ -0,0 +1,1155 @@
+package com.cf.imes.module.plan.service.orderImport.factory;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.PageUtil;
+import cn.hutool.json.JSONObject;
+import com.alibaba.excel.util.ListUtils;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.nacos.common.utils.StringUtils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.cf.imes.framework.common.enums.OrderPlateTypeEnum;
+import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
+import com.cf.imes.framework.common.util.json.JsonUtils;
+import com.cf.imes.framework.common.util.object.BeanUtils;
+import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
+import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
+import com.cf.imes.framework.mybatis.core.injector.BaseBatchMapper;
+import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
+import com.cf.imes.framework.organ.core.context.OrganContextHolder;
+import com.cf.imes.module.executor.enums.DictTypeConstants;
+import com.cf.imes.module.executor.enums.OrderImportConstants;
+import com.cf.imes.module.executor.enums.OrderImportStatusEnum;
+import com.cf.imes.module.executor.enums.OrderImportTmpDataTypeEnum;
+import com.cf.imes.module.executor.enums.OrderItemTypeEnum;
+import com.cf.imes.module.plan.controller.orderImport.vo.OrderImportTempDataReqVO;
+import com.cf.imes.module.plan.controller.orderImport.vo.OrderPlateImportExcelVO;
+import com.cf.imes.module.plan.dal.dataobject.goods.GoodsDO;
+import com.cf.imes.module.plan.dal.dataobject.orderBody.OrderBodyDO;
+import com.cf.imes.module.plan.dal.dataobject.orderGroup.OrderGroupDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTaskDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTempDataDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTempDataGoodsGroupDO;
+import com.cf.imes.module.plan.dal.dataobject.orderImport.OrderImportTempDataGoodsIdGroupDO;
+import com.cf.imes.module.plan.dal.dataobject.orderItem.OrderItemDO;
+import com.cf.imes.module.plan.dal.dataobject.orderParts.OrderPartsDO;
+import com.cf.imes.module.plan.dal.dataobject.orderParts.PartsDO;
+import com.cf.imes.module.plan.dal.dataobject.ordermodel.OrderModelDO;
+import com.cf.imes.module.plan.dal.dataobject.plate.PlateDO;
+import com.cf.imes.module.plan.dal.dataobject.plate.PlateGoodDO;
+import com.cf.imes.module.plan.dal.dataobject.rawgoods.RawGoodsDO;
+import com.cf.imes.module.plan.dal.elasticsearch.OrderPartsRemark;
+import com.cf.imes.module.plan.dal.mysql.goods.GoodsMapper;
+import com.cf.imes.module.plan.dal.mysql.orderBody.OrderBodyMapper;
+import com.cf.imes.module.plan.dal.mysql.orderGroup.OrderGroupMapper;
+import com.cf.imes.module.plan.dal.mysql.orderImport.OrderImportTaskMapper;
+import com.cf.imes.module.plan.dal.mysql.orderImport.OrderImportTempDataMapper;
+import com.cf.imes.module.plan.dal.mysql.orderItem.OrderItemMapper;
+import com.cf.imes.module.plan.dal.mysql.orderParts.OrderPartsMapper;
+import com.cf.imes.module.plan.dal.mysql.orderParts.PartsMapper;
+import com.cf.imes.module.plan.dal.mysql.plate.PlateGoodMapper;
+import com.cf.imes.module.plan.dal.mysql.plate.PlateMapper;
+import com.cf.imes.module.plan.dal.mysql.rawgoods.RawGoodsMapper;
+import com.cf.imes.module.plan.service.order.OrderInputProcessor;
+import com.cf.imes.module.system.api.dict.DictDataApi;
+import com.cf.imes.module.system.api.dict.dto.DictDataRespDTO;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.cf.imes.module.plan.enums.ErrorCodeConstants.ORDER_IMPORT_PLATE_GOODS_NOT_EXISTS;
+import static com.cf.imes.module.plan.service.order.OrderInputProcessor.ORDER_PARTS_REMARK_MODEL;
+import static com.cf.imes.module.plan.service.order.OrderInputProcessor.ORDER_PLATE_MODEL;
+import static com.cf.imes.module.plan.service.order.OrderInputProcessor.ORDER_PLATE_MODEL_COMPRESS;
+
+/**
+ * 默认excel导入生产单工厂服务
+ *
+ * @author Gqr
+ * @since 2025/2/11 16:03
+ */
+@Slf4j
+public class DefaultExcelOrderImportFactory {
+ /**
+ * 分组中做分页的阈值,如:总数1000以上就边分组边分页,否则一次性查出来
+ */
+ private static final int BATCH_THRESHOLD_NUMBER = 1000;
+
+ private Long organId;
+
+ private Long orderId;
+
+ private Long taskId;
+
+ private List rawGoodsDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List goodsDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List orderPartsDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List orderBodyDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List orderGroupDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List plateDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List orderItemDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List plateGoodDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List orderModelDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List orderPartsRemarks = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ private List partsDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+
+ private static final String EMPTY_STRING = new String();
+ private static final BigDecimal BIG_ZERO = new BigDecimal(0);
+
+ private static final int PLATE_TYPE = OrderImportTmpDataTypeEnum.PLATE.getType();
+ private static final int PART_TYPE = OrderImportTmpDataTypeEnum.PART.getType();
+
+ private SnowFlakeGenerator snowFlakeGenerator;
+
+ private SnowflakeIdWorker3rd idWorker;
+
+ private OrderImportTaskMapper orderImportTaskMapper;
+
+ private OrderImportTempDataMapper orderImportTempDataMapper;
+
+ private DictDataApi dictDataApi;
+
+ private GoodsMapper goodsMapper;
+
+ private RawGoodsMapper rawGoodsMapper;
+
+ private OrderPartsMapper orderPartsMapper;
+
+ private OrderBodyMapper orderBodyMapper;
+
+ private OrderGroupMapper orderGroupMapper;
+
+ private PlateMapper plateMapper;
+
+ private OrderItemMapper orderItemMapper;
+
+ private PlateGoodMapper plateGoodMapper;
+
+ private OrderInputProcessor orderInputProcessor;
+
+ private PartsMapper partsMapper;
+
+ private String operatorName;
+
+ public DefaultExcelOrderImportFactory(Long taskId,
+ Long orderId,
+ Long organId,
+ String operatorName,
+ SnowFlakeGenerator snowFlakeGenerator,
+ SnowflakeIdWorker3rd idWorker,
+ OrderImportTaskMapper orderImportTaskMapper,
+ OrderImportTempDataMapper orderImportTempDataMapper,
+ DictDataApi dictDataApi,
+ GoodsMapper goodsMapper,
+ RawGoodsMapper rawGoodsMapper,
+ OrderPartsMapper orderPartsMapper,
+ OrderBodyMapper orderBodyMapper,
+ OrderGroupMapper orderGroupMapper,
+ PlateMapper plateMapper,
+ OrderItemMapper orderItemMapper,
+ PlateGoodMapper plateGoodMapper,
+ OrderInputProcessor orderInputProcessor,
+ PartsMapper partsMapper) {
+ this.taskId = taskId;
+ this.orderId = orderId;
+ this.organId = organId;
+ this.operatorName = operatorName;
+ this.snowFlakeGenerator = snowFlakeGenerator;
+ this.idWorker = idWorker;
+ this.orderImportTaskMapper = orderImportTaskMapper;
+ this.orderImportTempDataMapper = orderImportTempDataMapper;
+ this.dictDataApi = dictDataApi;
+ this.goodsMapper = goodsMapper;
+ this.rawGoodsMapper = rawGoodsMapper;
+ this.orderPartsMapper = orderPartsMapper;
+ this.orderBodyMapper = orderBodyMapper;
+ this.orderGroupMapper = orderGroupMapper;
+ this.plateMapper = plateMapper;
+ this.orderItemMapper = orderItemMapper;
+ this.plateGoodMapper = plateGoodMapper;
+ this.orderInputProcessor = orderInputProcessor;
+ this.partsMapper = partsMapper;
+ }
+
+ /**
+ * 解析临时表数据
+ */
+ public void analyzeTempData() {
+ try {
+ // 解析商品数据
+ analyzeGoods();
+ // 解析配件数据
+ analyzePartsGoods();
+ // 解析小板/配件项
+ analyzeRooms();
+ // 删除临时数据
+ deleteTempData();
+ // 完成所有流程后更新任务为导入成功
+ updateTaskSuccess();
+ } catch (Exception e) {
+ // 数据库数据回滚,此时删除 ES 里的数据
+ orderInputProcessor.deleteByOrderId(orderId, ORDER_PLATE_MODEL);
+ orderInputProcessor.deleteByOrderId(orderId, ORDER_PLATE_MODEL_COMPRESS);
+ orderInputProcessor.deleteByOrderId(orderId, ORDER_PARTS_REMARK_MODEL);
+ throw e;
+ } finally {
+ // 解析结束后清理所有list
+ clearAll();
+ }
+ }
+
+ /**
+ * 解析商品
+ */
+ private void analyzeGoods() {
+ // 基于物料编码分组的总数
+ OrderImportTempDataReqVO goodsIdGroupCountReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PLATE_TYPE).build();
+ Integer goodsIdGroupCount = orderImportTempDataMapper.selectCountGoodsIdGroup(goodsIdGroupCountReqVO);
+ if (NumberUtil.compare(goodsIdGroupCount, 0) > 0) {
+ // 在阈值之下就不分组
+ if (goodsIdGroupCount <= BATCH_THRESHOLD_NUMBER) {
+ analyzeGoodsDetailNoPaging();
+ } else {
+
+ }
+ }
+ }
+
+ /**
+ * 不分页解析商品id分组列表
+ */
+ private void analyzeGoodsDetailNoPaging() {
+ // 基于物料编码查分组
+ OrderImportTempDataReqVO goodsIdGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PLATE_TYPE).build();
+ List goodsIdGroupList = orderImportTempDataMapper.selectGoodsIdGroup(goodsIdGroupReqVO);
+ for (OrderImportTempDataGoodsIdGroupDO goodsIdGroupDO : goodsIdGroupList) {
+ String outerGoodsId = goodsIdGroupDO.getOuterGoodsId();
+ // 查询物料编码下的大板属性分组后的总数
+ OrderImportTempDataReqVO plateGoodsGroupCountReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PLATE_TYPE).goodsId(outerGoodsId).build();
+ int plateGoodsGroupCount = orderImportTempDataMapper.selectCountPlateGoodsGroup(plateGoodsGroupCountReqVO);
+ if (NumberUtil.compare(plateGoodsGroupCount, 0) > 0) {
+ // 在阈值之下就不分组
+ if (plateGoodsGroupCount <= BATCH_THRESHOLD_NUMBER) {
+ // 查询物料编码下的大板属性的分组
+ OrderImportTempDataReqVO goodsGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PLATE_TYPE).goodsId(outerGoodsId).build();
+ List orderImportTempDataGoodsGroupDOS = orderImportTempDataMapper.selectPlateGoodsGroup(goodsGroupReqVO);
+ for (OrderImportTempDataGoodsGroupDO orderImportTempDataGoodsGroupDO : orderImportTempDataGoodsGroupDOS) {
+ analyzeInnerGoodsDetailNoPaging(outerGoodsId, orderImportTempDataGoodsGroupDO);
+ }
+ } else {
+ // 分组分页解析
+
+ }
+ }
+ }
+ // 最后批量插入rawgoods、goods、plategoods一次,避免最后一页小于BATCH_THRESHOLD_NUMBER漏插入
+ orderInfoBatchInsertWithinThreshold(rawGoodsMapper, rawGoodsDOS, true);
+ orderInfoBatchInsertWithinThreshold(goodsMapper, goodsDOS, true);
+ orderInfoBatchInsertWithinThreshold(plateGoodMapper, plateGoodDOS, true);
+ }
+
+
+ /**
+ * 不分页解析出imes goodsdo入库
+ *
+ * @param outerGoodsId
+ * @param orderImportTempDataGoodsGroupDO
+ */
+ private void analyzeInnerGoodsDetailNoPaging(String outerGoodsId, OrderImportTempDataGoodsGroupDO orderImportTempDataGoodsGroupDO) {
+ // 是否有物料编码
+ boolean outerGoodsIdExist = false;
+ // 创建rawgoods
+ RawGoodsDO rawGoodsDO = createRawGoodsDO(outerGoodsId, orderImportTempDataGoodsGroupDO);
+ // 创建goods
+ GoodsDO goodsDO = createGoodsDO(orderImportTempDataGoodsGroupDO).setRawGoodsId(String.valueOf(rawGoodsDO.getId()));
+ // 有物料编码用物料编码设置goodsId否则rawgoodsId、goodsId设空
+ if (ObjectUtil.notEqual(OrderImportConstants.DEFAULT_GOODS_ID, outerGoodsId)) {
+ goodsDO.setGoodsId(rawGoodsDO.getRawGoodsId());
+ outerGoodsIdExist = true;
+ } else {
+ rawGoodsDO.setRawGoodsId(EMPTY_STRING);
+ goodsDO.setGoodsId(EMPTY_STRING);
+ }
+ Long innerGoodsId = goodsDO.getId();
+ // 解析大板
+ analyzePlateGoods(goodsDO);
+ goodsDOS.add(goodsDO);
+ rawGoodsDOS.add(rawGoodsDO);
+ // 批量插入rawgoods、goods
+ orderInfoBatchInsertWithinThreshold(rawGoodsMapper, rawGoodsDOS, false);
+ orderInfoBatchInsertWithinThreshold(goodsMapper, goodsDOS, false);
+ // 有物料编码用物料编码更新innerGoodsId,没有就用大板属性
+ if (!outerGoodsIdExist) {
+ orderImportTempDataMapper.update(new LambdaUpdateWrapperX()
+ .eq(OrderImportTempDataDO::getTaskId, taskId)
+ .eq(OrderImportTempDataDO::getType, PLATE_TYPE)
+ .eqIfPresent(OrderImportTempDataDO::getGoodsName, orderImportTempDataGoodsGroupDO.getGoodsName())
+ .eqIfPresent(OrderImportTempDataDO::getMaterial, orderImportTempDataGoodsGroupDO.getMaterial())
+ .eqIfPresent(OrderImportTempDataDO::getWave, orderImportTempDataGoodsGroupDO.getWave())
+ .eqIfPresent(OrderImportTempDataDO::getColor, orderImportTempDataGoodsGroupDO.getColor())
+ .eqIfPresent(OrderImportTempDataDO::getSpec, orderImportTempDataGoodsGroupDO.getSpec())
+ .eqIfPresent(OrderImportTempDataDO::getWidth, orderImportTempDataGoodsGroupDO.getWidth())
+ .eqIfPresent(OrderImportTempDataDO::getHeight, orderImportTempDataGoodsGroupDO.getHeight())
+ .eqIfPresent(OrderImportTempDataDO::getThickness, orderImportTempDataGoodsGroupDO.getThickness())
+ .eqIfPresent(OrderImportTempDataDO::getBrand, orderImportTempDataGoodsGroupDO.getBrand())
+ .set(OrderImportTempDataDO::getInnerGoodsId, innerGoodsId));
+ } else {
+ orderImportTempDataMapper.update(new LambdaUpdateWrapper()
+ .eq(OrderImportTempDataDO::getOuterGoodsId, outerGoodsId)
+ .eq(OrderImportTempDataDO::getTaskId, taskId)
+ .eq(OrderImportTempDataDO::getType, PLATE_TYPE)
+ .set(OrderImportTempDataDO::getInnerGoodsId, innerGoodsId));
+ }
+ }
+
+ /**
+ * 解析配件
+ */
+ private void analyzePartsGoods() {
+ OrderImportTempDataReqVO partGoodsIdGroupCountReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PART_TYPE).build();
+ // 基于物料编码分组的总数
+ Integer partGoodsIdGroupCount = orderImportTempDataMapper.selectCountGoodsIdGroup(partGoodsIdGroupCountReqVO);
+ if (NumberUtil.compare(partGoodsIdGroupCount, 0) > 0) {
+ // 在阈值之下就不分组
+ if (partGoodsIdGroupCount <= BATCH_THRESHOLD_NUMBER) {
+ analyzePartGoodsDetailNoPaging();
+ } else {
+
+ }
+ }
+ }
+
+ /**
+ * 不分页解析配件
+ */
+ private void analyzePartGoodsDetailNoPaging() {
+ // 基于物料编码查分组列表
+ OrderImportTempDataReqVO partGoodsIdGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PART_TYPE).build();
+ List partGoodsIdGroupList = orderImportTempDataMapper.selectGoodsIdGroup(partGoodsIdGroupReqVO);
+ for (OrderImportTempDataGoodsIdGroupDO partGoodsIdGroupDO : partGoodsIdGroupList) {
+ String outerGoodsId = partGoodsIdGroupDO.getOuterGoodsId();
+ // 查询物料编码下的配件属性分组后的总数
+ OrderImportTempDataReqVO partGoodsGroupCountReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PART_TYPE).goodsId(outerGoodsId).build();
+ int plateGoodsGroupCount = orderImportTempDataMapper.selectCountPartGoodsGroup(partGoodsGroupCountReqVO);
+ if (NumberUtil.compare(plateGoodsGroupCount, 0) > 0) {
+ // 在阈值之下就不分组
+ if (plateGoodsGroupCount <= BATCH_THRESHOLD_NUMBER) {
+ // 查询物料编码下的配件属性的分组列表
+ OrderImportTempDataReqVO goodsGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).type(PART_TYPE).goodsId(outerGoodsId).build();
+ List orderImportTempDataGoodsGroupDOS = orderImportTempDataMapper.selectPartGoodsGroup(goodsGroupReqVO);
+ for (OrderImportTempDataGoodsGroupDO orderImportTempDataGoodsGroupDO : orderImportTempDataGoodsGroupDOS) {
+ analyzeInnerPartGoodsDetailNoPaging(outerGoodsId, orderImportTempDataGoodsGroupDO);
+ }
+ } else {
+ // 分组分页解析
+
+ }
+ }
+ }
+ // 最后批量插入orderParts一次,避免最后一页小于BATCH_THRESHOLD_NUMBER漏插入
+ orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, true);
+ orderInfoBatchInsertWithinThreshold(partsMapper, partsDOS, true);
+ // 批量插入配件备注
+ orderPartsRemarksBatchInsertWithinThreshold(true);
+ }
+
+ /**
+ * 不分页解析出imes order_parts入库
+ *
+ * @param outerGoodsId
+ * @param orderImportTempDataGoodsGroupDO
+ */
+ private void analyzeInnerPartGoodsDetailNoPaging(String outerGoodsId, OrderImportTempDataGoodsGroupDO orderImportTempDataGoodsGroupDO) {
+ // 是否有物料编码
+ boolean outerGoodsIdExist = false;
+ // 创建orderParts
+ OrderPartsDO orderParts = createOrderParts(outerGoodsId, orderImportTempDataGoodsGroupDO);
+ Long partId = orderParts.getId();
+ // 有物料编码用物料编码设置goodsId否则goodsId设空
+ if (ObjectUtil.notEqual(OrderImportConstants.DEFAULT_GOODS_ID, outerGoodsId)) {
+ orderParts.setGoodsId(outerGoodsId);
+ outerGoodsIdExist = true;
+ } else {
+ orderParts.setGoodsId(EMPTY_STRING);
+ }
+ // 解析配件商品
+ analyzePartsGoods(orderParts);
+ // 批量插入orderParts
+ orderPartsDOS.add(orderParts);
+ orderInfoBatchInsertWithinThreshold(orderPartsMapper, orderPartsDOS, false);
+ // 有物料编码用物料编码更新innerGoodsId,没有就用配件属性
+ if (!outerGoodsIdExist) {
+ orderImportTempDataMapper.update(new LambdaUpdateWrapperX()
+ .eq(OrderImportTempDataDO::getTaskId, taskId)
+ .eq(OrderImportTempDataDO::getType, PART_TYPE)
+ .eqIfPresent(OrderImportTempDataDO::getGoodsName, orderImportTempDataGoodsGroupDO.getGoodsName())
+ .eqIfPresent(OrderImportTempDataDO::getMaterial, orderImportTempDataGoodsGroupDO.getMaterial())
+ .eqIfPresent(OrderImportTempDataDO::getColor, orderImportTempDataGoodsGroupDO.getColor())
+ .eqIfPresent(OrderImportTempDataDO::getIsComposite, orderImportTempDataGoodsGroupDO.getIsComposite())
+ .eqIfPresent(OrderImportTempDataDO::getCategory, orderImportTempDataGoodsGroupDO.getCategory())
+ .eqIfPresent(OrderImportTempDataDO::getType, orderImportTempDataGoodsGroupDO.getSubType())
+ .eqIfPresent(OrderImportTempDataDO::getFactory, orderImportTempDataGoodsGroupDO.getFactory())
+ .eqIfPresent(OrderImportTempDataDO::getModel, orderImportTempDataGoodsGroupDO.getModel())
+ .eqIfPresent(OrderImportTempDataDO::getSpec, orderImportTempDataGoodsGroupDO.getSpec())
+ .eqIfPresent(OrderImportTempDataDO::getHeight, orderImportTempDataGoodsGroupDO.getHeight())
+ .eqIfPresent(OrderImportTempDataDO::getWidth, orderImportTempDataGoodsGroupDO.getWidth())
+ .eqIfPresent(OrderImportTempDataDO::getThickness, orderImportTempDataGoodsGroupDO.getThickness())
+ .eqIfPresent(OrderImportTempDataDO::getBrand, orderImportTempDataGoodsGroupDO.getBrand())
+ .eqIfPresent(OrderImportTempDataDO::getUnit, orderImportTempDataGoodsGroupDO.getUnit())
+ .set(OrderImportTempDataDO::getInnerGoodsId, partId));
+ } else {
+ orderImportTempDataMapper.update(new LambdaUpdateWrapper()
+ .eq(OrderImportTempDataDO::getOuterGoodsId, outerGoodsId)
+ .eq(OrderImportTempDataDO::getTaskId, taskId)
+ .eq(OrderImportTempDataDO::getType, PART_TYPE)
+ .set(OrderImportTempDataDO::getInnerGoodsId, partId));
+ }
+ // 解析配件备注
+ analyzePartsRemark(partId);
+ }
+
+ /**
+ * 解析配件备注
+ *
+ * @param partId
+ */
+ private void analyzePartsRemark(Long partId) {
+ // 配件id下的临时数据列表查询
+ List orderImportTempDataDOS = orderImportTempDataMapper.selectPartList(OrderImportTempDataReqVO.builder().goodsId(String.valueOf(partId)).build());
+ StringBuilder remark = new StringBuilder();
+ for (OrderImportTempDataDO tempDataDO : orderImportTempDataDOS) {
+ // 取明细压缩数据做解压
+ String detail = JsonUtils.unzipString(tempDataDO.getDetail());
+ OrderPlateImportExcelVO combination = JSON.parseObject(detail, OrderPlateImportExcelVO.class);
+ String extractedRemark = remarkExtract(combination.remarkJSON());
+ if (StringUtils.isNotEmpty(extractedRemark)) {
+ // 累加备注
+ remark.append(extractedRemark);
+ }
+ }
+
+ // 配件备注信息存储
+ OrderPartsRemark orderPartsRemark = OrderPartsRemark.builder().partsId(partId).orderId(orderId)
+ .remark(remark.toString()).build();
+ orderPartsRemark.setCreator(operatorName);
+ orderPartsRemark.setUpdater(operatorName);
+ orderPartsRemark.setOrganId(organId);
+ // 批量插入配件备注
+ orderPartsRemarks.add(orderPartsRemark);
+ orderPartsRemarksBatchInsertWithinThreshold(false);
+ }
+
+ /**
+ * 每达到阈值就批量插入一次生产单造型数据和压缩数据
+ *
+ * @param isLast 是否最后一次插入,不是就需要清理list
+ */
+ private void orderPartsRemarksBatchInsertWithinThreshold(boolean isLast) {
+ // 达到批量的阈值就做一次插入
+ if (CollUtil.isNotEmpty(orderPartsRemarks) && (orderPartsRemarks.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
+ orderInputProcessor.batchSaveOrderPartsModel(orderPartsRemarks);
+ if (!isLast) {
+ // 存储完成清理 list
+ orderPartsRemarks = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ }
+ }
+ }
+
+ /**
+ * 解析房间
+ */
+ private void analyzeRooms() {
+ // 基于roomName分组的总数
+ Integer roomGroupCount = orderImportTempDataMapper.selectCountRoomGroup(taskId);
+ if (NumberUtil.compare(roomGroupCount, 0) > 0) {
+ // 在阈值之下就不分组
+ if (roomGroupCount <= BATCH_THRESHOLD_NUMBER) {
+ analyzeRoomNoPaing();
+ } else {
+
+ }
+ }
+ // 最后批量插入一次,避免最后一页小于BATCH_THRESHOLD_NUMBER漏插入
+ orderInfoBatchInsertWithinThreshold(orderBodyMapper, orderBodyDOS, true);
+ orderInfoBatchInsertWithinThreshold(orderGroupMapper, orderGroupDOS, true);
+ orderInfoBatchInsertWithinThreshold(plateMapper, plateDOS, true);
+ orderInfoBatchInsertWithinThreshold(orderItemMapper, orderItemDOS, true);
+ // 批量插入造型数据
+ orderModelsBatchInsertWithinThreshold(true);
+ }
+
+ /**
+ * 不分页解析房间
+ */
+ private void analyzeRoomNoPaing() {
+ // 查询基于roomName的分组
+ OrderImportTempDataReqVO roomNameGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).build();
+ List roomNameGroup = orderImportTempDataMapper.selectRoomGroup(roomNameGroupReqVO);
+ for (OrderImportTempDataGoodsGroupDO roomNameGroupDO : roomNameGroup) {
+ analyzeRoomBody(roomNameGroupDO.getRoomName());
+ }
+ }
+
+ /**
+ * 解析房间下柜体
+ *
+ * @param roomName
+ */
+ private void analyzeRoomBody(String roomName) {
+ // 基于bodyName分组的总数
+ OrderImportTempDataReqVO countBodyNameGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).roomName(roomName).build();
+ Integer bodyGroupCount = orderImportTempDataMapper.selectCountBodyGroup(countBodyNameGroupReqVO);
+ if (NumberUtil.compare(bodyGroupCount, 0) > 0) {
+ // 在阈值之下就不分组
+ if (bodyGroupCount <= BATCH_THRESHOLD_NUMBER) {
+ analyzeBodyNoPaing(roomName);
+ } else {
+
+ }
+ }
+ }
+
+ /**
+ * 不分页解析房间下柜体
+ *
+ * @param roomName
+ */
+ private void analyzeBodyNoPaing(String roomName) {
+ // 基于房间下bodyName查询分组和板数量(只有plate计入数量)
+ OrderImportTempDataReqVO bodyNameGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).roomName(roomName).build();
+ List bodyNameGroup = orderImportTempDataMapper.selectBodyGroup(bodyNameGroupReqVO);
+ // 生成房间id
+ Long roomId = (Long) snowFlakeGenerator.nextId(null);
+ for (OrderImportTempDataGoodsGroupDO bodyNameGroupDO : bodyNameGroup) {
+ // 创建orderBodyDO
+ OrderBodyDO orderBodyDO = createOrderBodyDO(roomName, roomId, bodyNameGroupDO);
+ // 批量插入orderBody
+ orderBodyDOS.add(orderBodyDO);
+ orderInfoBatchInsertWithinThreshold(orderBodyMapper, orderBodyDOS, false);
+ // 解析房间、柜体下的加工组类型名称
+ analyzeBodyGroupTypeName(orderBodyDO);
+ }
+ }
+
+ /**
+ * 解析房间、柜体下的加工组类型名称
+ *
+ * @param orderBodyDO
+ */
+ private void analyzeBodyGroupTypeName(OrderBodyDO orderBodyDO) {
+ OrderImportTempDataReqVO countGroupTypeGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).roomName(orderBodyDO.getRoomName()).bodyName(orderBodyDO.getName()).build();
+ // 基于groupTypeName分组的总数
+ Integer countGroupTypeGroup = orderImportTempDataMapper.selectCountGroupTypeNameGroup(countGroupTypeGroupReqVO);
+ if (NumberUtil.compare(countGroupTypeGroup, 0) > 0) {
+ // 在阈值之下就不分组
+ if (countGroupTypeGroup <= BATCH_THRESHOLD_NUMBER) {
+ analyzeGroupTypeNameNoPaing(orderBodyDO);
+ } else {
+
+ }
+ }
+ }
+
+ /**
+ * 不分组解析房间、柜体下的加工组类型名称
+ *
+ * @param orderBodyDO
+ */
+ private void analyzeGroupTypeNameNoPaing(OrderBodyDO orderBodyDO) {
+ // 基于房间、柜体下加工组类型名称分组
+ OrderImportTempDataReqVO groupTypeNameGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).roomName(orderBodyDO.getRoomName()).bodyName(orderBodyDO.getName()).build();
+ List groupTypeNameGroup = orderImportTempDataMapper.selectGroupTypeNameGroup(groupTypeNameGroupReqVO);
+ // 生成加工组类型id
+ Long groupTypeId = (Long) snowFlakeGenerator.nextId(null);
+ for (OrderImportTempDataGoodsGroupDO groupTypeNameGroupDO : groupTypeNameGroup) {
+ // 解析房间、柜体、加工组类型名称下的加工组名称
+ analyzeGroupName(orderBodyDO, groupTypeNameGroupDO.getGroupTypeName(), groupTypeId);
+ }
+ }
+
+ /**
+ * 解析房间、柜体、加工组类型名称下的加工组名称
+ *
+ * @param orderBodyDO
+ * @param groupTypeName
+ * @param groupTypeId
+ */
+ private void analyzeGroupName(OrderBodyDO orderBodyDO, String groupTypeName, Long groupTypeId) {
+ // 基于groupName分组的总数
+ OrderImportTempDataReqVO countGroupNameGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).roomName(orderBodyDO.getRoomName()).bodyName(orderBodyDO.getName()).groupTypeName(groupTypeName).build();
+ Integer countGroupNameGroup = orderImportTempDataMapper.selectCountGroupNameGroup(countGroupNameGroupReqVO);
+ if (NumberUtil.compare(countGroupNameGroup, 0) > 0) {
+ // 在阈值之下就不分组
+ if (countGroupNameGroup <= BATCH_THRESHOLD_NUMBER) {
+ analyzeGroupNameNoPaing(orderBodyDO, groupTypeName, groupTypeId);
+ } else {
+
+ }
+ }
+ }
+
+ /**
+ * 不分组解析房间、柜体、加工组类型名称下的加工组名称
+ *
+ * @param orderBodyDO
+ * @param groupTypeName
+ * @param groupTypeId
+ */
+ private void analyzeGroupNameNoPaing(OrderBodyDO orderBodyDO, String groupTypeName, Long groupTypeId) {
+ // 基于groupName分组和数量(只有plate计入数量)
+ OrderImportTempDataReqVO groupNameGroupReqVO = OrderImportTempDataReqVO.builder().taskId(taskId).roomName(orderBodyDO.getRoomName()).bodyName(orderBodyDO.getName()).groupTypeName(groupTypeName).build();
+ List groupNameGroup = orderImportTempDataMapper.selectGroupNameGroup(groupNameGroupReqVO);
+ for (OrderImportTempDataGoodsGroupDO groupNameGroupDO : groupNameGroup) {
+ String groupName = groupNameGroupDO.getGroupName();
+ Long groupId = 0L;
+ if (StringUtils.isNotEmpty(groupName)) {
+ // 创建orderGroupDO
+ OrderGroupDO orderGroupDO = createOrderGroupDO(orderBodyDO.getId(), groupTypeName, groupTypeId, groupNameGroupDO);
+ groupId = orderGroupDO.getId();
+ // 生成orderGroup
+ orderGroupDOS.add(orderGroupDO);
+ // 批量插入orderGroup
+ orderInfoBatchInsertWithinThreshold(orderGroupMapper, orderGroupDOS, false);
+ }
+ // 根据数量生成相应的item
+ analyzeItem(orderBodyDO, groupTypeName, groupName, groupId);
+ // 根据数量生成相应的配件
+ analyzePart(orderBodyDO, groupTypeName, groupName, groupId);
+ }
+ }
+
+ /**
+ * 分页解析小板orderPlate、orderItem
+ *
+ * @param orderBodyDO
+ * @param groupTypeName
+ * @param groupName
+ * @param groupId
+ */
+ private void analyzeItem(OrderBodyDO orderBodyDO, String groupTypeName, String groupName, Long groupId) {
+ String roomName = orderBodyDO.getRoomName();
+ String bodyName = orderBodyDO.getName();
+ OrderImportTempDataReqVO groupNameListReqVO = OrderImportTempDataReqVO.builder().type(PLATE_TYPE).taskId(taskId).roomName(roomName).bodyName(orderBodyDO.getName()).groupTypeName(groupTypeName).groupName(groupName).build();
+ // 查询房间、柜体、加工组类型名称、加工组名称下的数量
+ int countGroupName = orderImportTempDataMapper.selectCountGroupName(groupNameListReqVO);
+ // 计算页码
+ int pageNum = PageUtil.totalPage(countGroupName, BATCH_THRESHOLD_NUMBER);
+ // 分页查询临时表
+ for (int page = 1; page <= pageNum; page++) {
+ OrderImportTempDataReqVO groupNamePageReqVO = groupNameListReqVO.setDoPaging(true).setOffset((page - 1) * BATCH_THRESHOLD_NUMBER).setSize(BATCH_THRESHOLD_NUMBER);
+ List groupNameList = orderImportTempDataMapper.selectGroupNameList(groupNamePageReqVO);
+ for (OrderImportTempDataDO tempDataDO : groupNameList) {
+ int num = tempDataDO.getNum().intValue();
+ String detail = JsonUtils.unzipString(tempDataDO.getDetail());
+ OrderPlateImportExcelVO combination = JSON.parseObject(detail, OrderPlateImportExcelVO.class);
+ // 根据数量生成num个小板数据
+ for (int i = 0; i < num; i++) {
+ long plateNo = idWorker.nextId();
+ long obtainingTime = idWorker.obtainingTime();
+ long goodsId = Long.parseLong(tempDataDO.getInnerGoodsId());
+ // 成品宽
+ String width = combination.getWidth();
+ // 成品长
+ String height = combination.getHeight();
+ // 计算面积
+ BigDecimal area = BigDecimal.valueOf(Double.parseDouble(width))
+ .multiply(BigDecimal.valueOf(Double.parseDouble(height)))
+ .movePointLeft(6)
+ .setScale(2, RoundingMode.HALF_UP);
+ Long plateId = (Long) snowFlakeGenerator.nextId(null);
+ // 排版面 纹路 开门方向转换
+ DictDataRespDTO typographyDTO = dictDataApi.parseDictData(DictTypeConstants.TYPOGRAPHY_TYPE, combination.getTypographicFace()).getData();// 排版面
+ DictDataRespDTO grainDTO = dictDataApi.parseDictData(DictTypeConstants.GRAIN_TYPE, combination.getTexture()).getData();// 纹路
+ DictDataRespDTO doorDTO = dictDataApi.parseDictData(DictTypeConstants.DOOR_OPENING_DIRECTIONS, combination.getOpenDoorType()).getData();
+
+ PlateDO plateDO = PlateDO.builder()
+ .id(plateId)
+ .orderId(orderId)
+ .name(combination.getName())
+ .plateNo(combination.getPlateNo())
+ .type(OrderPlateTypeEnum.LAYERBOARD.getType())
+ .goodsId(goodsId)
+ .width(BigDecimal.valueOf(Double.parseDouble(width)))
+ .plateNo(((obtainingTime) + Long.toString(plateNo).substring(2)))
+ .height(BigDecimal.valueOf(Double.parseDouble(height)))
+ .thickness(BigDecimal.valueOf(Double.parseDouble(combination.getThickness())))
+ .splitWidth(BigDecimal.valueOf(Double.parseDouble(combination.getSplitWidth())))
+ .splitHeight(BigDecimal.valueOf(Double.parseDouble(combination.getSplitHeight())))
+ .splitThickness(BigDecimal.valueOf(Double.parseDouble(tempDataDO.getThickness())))
+ .sealLeft(BigDecimal.valueOf(Double.parseDouble(combination.getSealLeft())))
+ .sealRight(BigDecimal.valueOf(Double.parseDouble(combination.getSealRight())))
+ .sealUp(BigDecimal.valueOf(Double.parseDouble(combination.getSealUp())))
+ .sealDown(BigDecimal.valueOf(Double.parseDouble(combination.getSealDown())))
+ .holeFace(Integer.valueOf(typographyDTO.getValue()))
+ .texture(Integer.valueOf(grainDTO.getValue()))
+ .area(area)
+ .openDoorType(Integer.valueOf(doorDTO.getValue()))
+ .isSpecialShaped(false)
+ .isSculpt(false)
+ .remark(remarkExtract(combination.remarkJSON()))
+ .roomName(roomName)
+ .bodyName(bodyName)
+ .customPlateNoBuilder(new StringBuilder())
+ .organId(organId)
+ .holeArrange(0)
+ .holeFace(0)
+ .unregularPointCount(0)
+ .frontHoleCount(0)
+ .backHoleCount(0)
+ .sideHoleCount(0)
+ .frontModelCount(0)
+ .backModelCount(0)
+ .isDoor(false)
+ .offsetX(BIG_ZERO)
+ .offsetY(BIG_ZERO)
+ .isArcAcross(false)
+ .moduleTypeId(0L)
+ .isRowHole(false)
+ .isOptimized(false)
+ .isCutted(0)
+ .isCancel(false)
+ .filterType(EMPTY_STRING)
+ .deleted(false)
+ .build();
+ plateDO.setCreator(operatorName);
+ plateDO.setUpdater(operatorName);
+ LocalDateTime now = LocalDateTime.now();
+ plateDO.setCreateTime(now);
+ plateDO.setUpdateTime(now);
+ // 批量插入order_plate
+ plateDOS.add(plateDO);
+ orderInfoBatchInsertWithinThreshold(plateMapper, plateDOS, false);
+
+ OrderItemDO orderItemDO = OrderItemDO.builder()
+ .orderId(orderId)
+ .type(OrderItemTypeEnum.PLATE_ITEM.getStatus())
+ .roomId(orderBodyDO.getRoomId())
+ .bodyId(orderBodyDO.getId())
+ .plateId(plateId)
+ .num(1.0)
+ .groupId(StringUtils.isNotEmpty(groupTypeName) ? groupId : 0L)
+ .organId(organId)
+ .packageId(0L)
+ .partsId(0L)
+ .build();
+ // 批量插入order_item
+ orderItemDOS.add(orderItemDO);
+ orderInfoBatchInsertWithinThreshold(orderItemMapper, orderItemDOS, false);
+
+ // 批量插入CAD板件信息
+ OrderModelDO orderModelDO = OrderModelDO.builder()
+ .orderId(orderId)
+ .plateId(plateId)
+ .typographicFace(Integer.valueOf(typographyDTO.getValue()))
+ .texture(plateDO.getTexture())
+ .openDoorType(plateDO.getOpenDoorType())
+ .build();
+
+ // 查询大板id用于小板轮廓goodsId
+ GoodsDO goodsDO = goodsMapper.selectById(goodsId);
+ if (ObjectUtil.isNull(goodsDO)) {
+ throw ServiceExceptionUtil.exception(ORDER_IMPORT_PLATE_GOODS_NOT_EXISTS, orderId, goodsId);
+ }
+ orderModelDO.setGoodsId(goodsDO.getGoodsId());
+ orderModelDO.setPlateGoodsId(goodsId);
+ orderModelDO.setOrganId(organId);
+ orderModelDO.setCreator(operatorName);
+ orderModelDO.setUpdater(operatorName);
+ orderModelDOS.add(orderModelDO);
+
+ // 批量插入造型数据
+ orderModelsBatchInsertWithinThreshold(false);
+ }
+ }
+ }
+ }
+
+ /**
+ * 每达到阈值就批量插入一次生产单造型数据和压缩数据
+ *
+ * @param isLast 是否最后一次插入,不是就需要清理list
+ */
+ private void orderModelsBatchInsertWithinThreshold(boolean isLast) {
+ // 达到批量的阈值就做一次插入
+ if (CollUtil.isNotEmpty(orderModelDOS) && (orderModelDOS.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
+ // 保存生产单造型数据
+ orderInputProcessor.batchSaveModel(orderModelDOS);
+ if (!isLast) {
+ // 存储完成清理 list
+ orderModelDOS = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ }
+ }
+ }
+
+ /**
+ * 分页解析配件orderItem
+ *
+ * @param orderBodyDO
+ * @param groupTypeName
+ * @param groupName
+ * @param groupId
+ */
+ private void analyzePart(OrderBodyDO orderBodyDO, String groupTypeName, String groupName, Long groupId) {
+ String roomName = orderBodyDO.getRoomName();
+ String bodyName = orderBodyDO.getName();
+ Long itemGroupId = StringUtils.isNotEmpty(groupTypeName) ? groupId : 0L;
+ Long roomId = StringUtils.isNotEmpty(roomName) ? orderBodyDO.getRoomId() : 0L;
+ Long bodyId = StringUtils.isNotEmpty(bodyName) ? orderBodyDO.getId() : 0L;
+ OrderImportTempDataReqVO groupNameListReqVO = OrderImportTempDataReqVO.builder().type(PART_TYPE).taskId(taskId).roomName(roomName).bodyName(bodyName).groupTypeName(groupTypeName).groupName(groupName).build();
+ // 查询房间、柜体、加工组类型名称、加工组名称下的数量
+ int countGroupName = orderImportTempDataMapper.selectCountGroupName(groupNameListReqVO);
+ // 计算页码
+ int pageNum = PageUtil.totalPage(countGroupName, BATCH_THRESHOLD_NUMBER);
+ // 分页查询临时表
+ for (int page = 1; page <= pageNum; page++) {
+ OrderImportTempDataReqVO groupNamePageReqVO = groupNameListReqVO.setDoPaging(true).setOffset((page - 1) * BATCH_THRESHOLD_NUMBER).setSize(BATCH_THRESHOLD_NUMBER);
+ List groupNameList = orderImportTempDataMapper.selectGroupNameList(groupNamePageReqVO);
+ for (OrderImportTempDataDO tempDataDO : groupNameList) {
+ String detail = JsonUtils.unzipString(tempDataDO.getDetail());
+ OrderPlateImportExcelVO combination = JSON.parseObject(detail, OrderPlateImportExcelVO.class);
+ OrderItemDO orderItemDO = OrderItemDO.builder().orderId(orderId)
+ .type(OrderItemTypeEnum.PARTS_ITEM.getStatus())
+ .roomId(roomId)
+ .bodyId(bodyId)
+ .partsId(Long.parseLong(tempDataDO.getInnerGoodsId()))
+ .groupId(itemGroupId)
+ .num(Double.valueOf(combination.getGoodsNumber()))
+ .organId(organId)
+ .packageId(0L)
+ .plateId(0L)
+ .build();
+ // 批量插入order_item
+ orderItemDOS.add(orderItemDO);
+ orderInfoBatchInsertWithinThreshold(orderItemMapper, orderItemDOS, false);
+ }
+ }
+ }
+
+ /**
+ * 每达到阈值就批量插入一次
+ *
+ * @param baseBatchMapper
+ * @param list
+ * @param isLast 是否最后一次插入,不是就需要清理list
+ */
+ private void orderInfoBatchInsertWithinThreshold(BaseBatchMapper baseBatchMapper, List list, boolean isLast) {
+ // 达到批量的阈值就做一次插入
+ if (CollUtil.isNotEmpty(list) && (list.size() >= BATCH_THRESHOLD_NUMBER || isLast)) {
+ baseBatchMapper.insertBatchSomeColumn(list);
+ if (!isLast) {
+ // 存储完成清理 list
+ list = ListUtils.newArrayListWithExpectedSize(BATCH_THRESHOLD_NUMBER);
+ }
+ }
+ }
+
+ /**
+ * 创建生产单柜体orderBody
+ *
+ * @param roomName
+ * @param roomId
+ * @param groupDO
+ * @return
+ */
+ private OrderBodyDO createOrderBodyDO(String roomName, Long roomId, OrderImportTempDataGoodsGroupDO groupDO) {
+ OrderBodyDO orderBodyDO = OrderBodyDO.builder()
+ .id((Long) snowFlakeGenerator.nextId(null))
+ .orderId(orderId)
+ .roomId(roomId)
+ .roomName(roomName)
+ .name(groupDO.getBodyName())
+ .width(0.0)
+ .height(0.0)
+ .depth(0.0)
+ .multiNum(0)
+ .unregularNum(0)
+ .filename("无")
+ .remark("无")
+ .organId(organId)
+ .plateNum(groupDO.getBodyPlateNum())
+ .deleted(false)
+ .build();
+ orderBodyDO.setCreator(operatorName);
+ orderBodyDO.setUpdater(operatorName);
+ LocalDateTime now = LocalDateTime.now();
+ orderBodyDO.setCreateTime(now);
+ orderBodyDO.setUpdateTime(now);
+ return orderBodyDO;
+ }
+
+ /**
+ * 创建生产单加工组orderGroup
+ *
+ * @param bodyId
+ * @param groupTypeName
+ * @param groupTypeId
+ * @param groupDO
+ * @return
+ */
+ private OrderGroupDO createOrderGroupDO(Long bodyId, String groupTypeName, Long groupTypeId, OrderImportTempDataGoodsGroupDO groupDO) {
+ String groupName = groupDO.getGroupName();
+ OrderGroupDO orderGroupDO = OrderGroupDO.builder()
+ .id((Long) snowFlakeGenerator.nextId(null))
+ .orderId(orderId)
+ .organId(organId)
+ .bodyId(bodyId)
+ .groupTypeId(groupTypeId)
+ .groupTypeName(groupTypeName)
+ .name(StringUtils.isNotEmpty(groupName) ? groupName : groupTypeName)
+ .width(0.0)
+ .height(0.0)
+ .depth(0.0)
+ .multiNum(0)
+ .plateNum(groupDO.getGroupNameNum())
+ .unregularNum(0)
+ .filename("无")
+ .remark("无")
+ .deleted(false)
+ .build();
+ orderGroupDO.setCreator(operatorName);
+ orderGroupDO.setUpdater(operatorName);
+ LocalDateTime now = LocalDateTime.now();
+ orderGroupDO.setCreateTime(now);
+ orderGroupDO.setUpdateTime(now);
+ return orderGroupDO;
+ }
+
+ /**
+ * 创建生产单设计商品orderRawGoods
+ *
+ * @param goodsId
+ * @param groupDO
+ * @return
+ */
+ private RawGoodsDO createRawGoodsDO(String goodsId, OrderImportTempDataGoodsGroupDO groupDO) {
+ RawGoodsDO rawGoodsDO = RawGoodsDO.builder()
+ .id((Long) snowFlakeGenerator.nextId(null))
+ .orderId(orderId)
+ .organId(organId)
+ .rawGoodsId(goodsId)
+ .goodsName(groupDO.getGoodsName())
+ .material(groupDO.getMaterial())
+ .texture(Boolean.valueOf(groupDO.getWave()))
+ .color(groupDO.getColor())
+ .colorBlack(EMPTY_STRING)
+ .price(0.00)
+ .thickness(Double.valueOf(groupDO.getThickness()))
+ .spec(groupDO.getSpec())
+ .brand(StringUtils.isNotEmpty(groupDO.getBrand()) ? groupDO.getBrand() : EMPTY_STRING)
+ .deleted(false)
+ .build();
+ rawGoodsDO.setCreator(operatorName);
+ rawGoodsDO.setUpdater(operatorName);
+ LocalDateTime now = LocalDateTime.now();
+ rawGoodsDO.setCreateTime(now);
+ rawGoodsDO.setUpdateTime(now);
+ return rawGoodsDO;
+ }
+
+ /**
+ * 创建生产单商品orderGoods
+ *
+ * @param groupDO
+ * @return
+ */
+ private GoodsDO createGoodsDO(OrderImportTempDataGoodsGroupDO groupDO) {
+ GoodsDO goodsDO = GoodsDO.builder()
+ .id((Long) snowFlakeGenerator.nextId(null))
+ .orderId(orderId)
+ .organId(organId)
+ .goodsName(groupDO.getGoodsName())
+ .material(groupDO.getMaterial())
+ .texture(Boolean.valueOf(groupDO.getWave()))
+ .color(groupDO.getColor())
+ .width(BigDecimal.valueOf(Double.valueOf(groupDO.getWidth())))
+ .height(BigDecimal.valueOf(Double.valueOf(groupDO.getHeight())))
+ .thickness(BigDecimal.valueOf(Double.valueOf(groupDO.getThickness())))
+ .spec(groupDO.getSpec())
+ .brand(StringUtils.isNotEmpty(groupDO.getBrand()) ? groupDO.getBrand() : EMPTY_STRING)
+ .planId(0L)
+ .colorBlack(EMPTY_STRING)
+ .price(0.00)
+ .remark(EMPTY_STRING)
+ .deleted(false)
+ .build();
+ goodsDO.setCreator(operatorName);
+ goodsDO.setUpdater(operatorName);
+ LocalDateTime now = LocalDateTime.now();
+ goodsDO.setCreateTime(now);
+ goodsDO.setUpdateTime(now);
+ return goodsDO;
+ }
+
+ /**
+ * 创建生产单配件orderParts
+ *
+ * @param goodsId
+ * @param groupDO
+ * @return
+ */
+ private OrderPartsDO createOrderParts(String goodsId, OrderImportTempDataGoodsGroupDO groupDO) {
+ OrderPartsDO orderPartsDO = OrderPartsDO.builder()
+ .id((Long) snowFlakeGenerator.nextId(null))
+ .orderId(orderId)
+ .color(groupDO.getColor())
+ .category(groupDO.getCategory())
+ .type(StringUtils.isEmpty(groupDO.getSubType()) ? EMPTY_STRING: groupDO.getSubType())
+ .goodsId(goodsId)
+ .length(Double.valueOf(StringUtils.isEmpty(groupDO.getHeight()) ? "0" : groupDO.getHeight()))
+ .width(Double.valueOf(StringUtils.isEmpty(groupDO.getWidth()) ? "0" : groupDO.getWidth()))
+ .thickness(Double.valueOf(StringUtils.isEmpty(groupDO.getThickness()) ? "0" : groupDO.getThickness()))
+ .isComposite(Boolean.valueOf(groupDO.getIsComposite()))
+ .name(groupDO.getGoodsName())
+ .material(groupDO.getMaterial())
+ .model(StringUtils.isNotEmpty(groupDO.getModel()) ? groupDO.getModel() : EMPTY_STRING)
+ .spec(groupDO.getSpec())
+ .brand(StringUtils.isNotEmpty(groupDO.getBrand()) ? groupDO.getBrand() : EMPTY_STRING)
+ .factory(StringUtils.isNotEmpty(groupDO.getFactory()) ? groupDO.getFactory() : EMPTY_STRING)
+ .unit(groupDO.getUnit()).price(0.0)
+ .subparts(EMPTY_STRING)
+ .remark(EMPTY_STRING)
+ .deleted(false).organId(organId)
+ .build();
+ orderPartsDO.setCreator(operatorName);
+ orderPartsDO.setUpdater(operatorName);
+ LocalDateTime now = LocalDateTime.now();
+ orderPartsDO.setCreateTime(now);
+ orderPartsDO.setUpdateTime(now);
+ return orderPartsDO;
+ }
+
+ /**
+ * 生成备注
+ *
+ * @param remark
+ * @return
+ */
+ private String remarkExtract(String remark) {
+ JSONObject jsonObject = new JSONObject(remark);
+ List