Selaa lähdekoodia

添加数据迁移重新上传接口

fengyanjie@sagacloud.cn 4 vuotta sitten
vanhempi
commit
37f040f215

+ 48 - 40
dmp-admin/src/main/java/com/persagy/dmp/admin/controller/TransObjectInfoController.java

@@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -26,49 +27,56 @@ import java.net.URLEncoder;
 @RequestMapping("/admin/dmp/rwd/trans/object/info")
 public class TransObjectInfoController {
 
-	@Autowired
-	private TransObjectInfoService service;
+    @Autowired
+    private TransObjectInfoService service;
 
-	@PostMapping("/query")
-	public PagedResponse<TransObjectInfo> query(@RequestBody JacksonCriteria criteria) {
-		return service.query(criteria);
-	}
+    @PostMapping("/query")
+    public PagedResponse<TransObjectInfo> query(@RequestBody JacksonCriteria criteria) {
+        return service.query(criteria);
+    }
 
-	@PostMapping("/deleteByProjectId")
-	public MapResponse deleteByProjectId(@RequestParam String projectId) {
-		return service.deleteByProjectId(projectId);
-	}
+    @PostMapping("/deleteByProjectId")
+    public MapResponse deleteByProjectId(@RequestParam String projectId) {
+        return service.deleteByProjectId(projectId);
+    }
 
-	@PostMapping("/download")
-	public void download(@RequestParam String projectId, HttpServletResponse response) {
-		DownloadModel result = service.download(projectId);
-		String fileName = result.getName();
-		downloadWorkbook(response, fileName, result.getWorkbook());
-	}
+    @PostMapping("/download")
+    public void download(@RequestParam String projectId, HttpServletResponse response) {
+        DownloadModel result = service.download(projectId);
+        String fileName = result.getName();
+        downloadWorkbook(response, fileName, result.getWorkbook());
+    }
 
-	private void downloadWorkbook(HttpServletResponse resp, String fileName, Workbook workbook) {
-		OutputStream out = null;
-		try {
-			resp.reset();// 清空输出流
-			String resultFileName = URLEncoder.encode(fileName, "UTF-8");
-			resp.setCharacterEncoding("UTF-8");
-			resp.setHeader("Content-disposition", "attachment; filename=" + resultFileName);// 设定输出文件头
-			resp.setContentType("application/msexcel");// 定义输出类型
-			out = resp.getOutputStream();
-			workbook.write(out);
-			out.flush();
-			log.info("download over: {}", fileName);
-		} catch (Exception e) {
-			e.printStackTrace();
-		} finally {
-			try {
-				if (out != null) {
-					out.close();
-				}
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-		}
-	}
+    @PostMapping("/upload")
+    public MapResponse upload(@RequestParam("groupCode") String groupCode,
+                              @RequestParam("projectId") String projectId,
+                              @RequestParam("file") MultipartFile file) {
+        return service.upload(groupCode, projectId, file);
+    }
+
+    private void downloadWorkbook(HttpServletResponse resp, String fileName, Workbook workbook) {
+        OutputStream out = null;
+        try {
+            resp.reset();// 清空输出流
+            String resultFileName = URLEncoder.encode(fileName, "UTF-8");
+            resp.setCharacterEncoding("UTF-8");
+            resp.setHeader("Content-disposition", "attachment; filename=" + resultFileName);// 设定输出文件头
+            resp.setContentType("application/msexcel");// 定义输出类型
+            out = resp.getOutputStream();
+            workbook.write(out);
+            out.flush();
+            log.info("download over: {}", fileName);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
 
 }

+ 7 - 3
dmp-admin/src/main/java/com/persagy/dmp/admin/repository/TransObjectInfoRepository.java

@@ -8,9 +8,13 @@ import org.springframework.data.querydsl.QuerydslPredicateExecutor;
 
 public interface TransObjectInfoRepository extends JpaRepository<TransObjectInfo, Integer>, QuerydslPredicateExecutor<TransObjectInfo> {
 
-	@Modifying
-	@Query(nativeQuery = true, value = "delete from admin_trans_object_info where project_id = ?")
-	int deleteByProjectId(String projectId);
+    @Modifying
+    @Query(nativeQuery = true, value = "delete from admin_trans_object_info where project_id = ?")
+    int deleteByProjectId(String projectId);
+
+    @Modifying
+    @Query(nativeQuery = true, value = "delete from admin_trans_object_info where project_id = ? and object_id is not null")
+    int deleteByProjectIdAndObjectId(String projectId);
 
 }
 

+ 257 - 213
dmp-admin/src/main/java/com/persagy/dmp/admin/service/DmpTransObjectService.java

@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.common.json.JacksonMapper;
 import com.persagy.common.web.MapResponse;
+import com.persagy.dmp.admin.entity.TransObjectInfo;
 import com.persagy.dmp.admin.repository.TransObjectInfoRepository;
 import com.persagy.dmp.admin.service.trans.RwdTransUtils;
 import com.persagy.dmp.admin.service.trans.TransObjectContext;
@@ -31,217 +32,260 @@ import java.util.concurrent.TimeUnit;
 @Service
 public class DmpTransObjectService {
 
-	private static final String KEY_TRANS = "admin_trans_";
-
-	@Autowired
-	private RwdTransUtils transUtils;
-
-	@Autowired
-	private HttpUtils httpUtils;
-
-	@Value("${persagy.dmp.server}")
-	private String dmpServer;
-
-	@Autowired
-	private StringRedisTemplate redis;
-
-	@Autowired
-	private TransObjectInfoRepository objectInfoRepository;
-
-	// 开始迁移
-	@Transactional
-	public MapResponse trans(Map<String, Object> param) {
-		MapResponse resp = new MapResponse();
-		String groupCode = MapUtils.getString(param, "groupCode");
-		if (groupCode == null) {
-			resp.setFail("groupCode is required");
-			return resp;
-		}
-		String projectId = MapUtils.getString(param, "projectId");
-		if (projectId == null) {
-			resp.setFail("projectId is required");
-			return resp;
-		}
-		String server = MapUtils.getString(param, "server");
-		if (server == null) {
-			resp.setFail("server is required");
-			return resp;
-		}
-		String secret = MapUtils.getString(param, "secret");
-		if (secret == null) {
-			resp.setFail("secret is required");
-			return resp;
-		}
-		log.info("object trans start: {}", JacksonMapper.toSimpleJson(param));
-
-		String key = KEY_TRANS + projectId;
-		Long flag = redis.opsForValue().increment(key, 1L);
-		if (flag > 1) {
-			resp.setFail("正在处理中...");
-			return resp;
-		}
-		redis.expire(key, 24, TimeUnit.HOURS);
-
-		objectInfoRepository.deleteByProjectId(projectId);
-
-		DmpMessage message = new DmpMessage("transObject", projectId);
-		message.setGroupCode(groupCode);
-		message.setProjectId(projectId);
-		message.setStr1(server);
-		message.setStr2(secret);
-		resp.add(message);
-		return resp;
-	}
-
-	// 开始标记
-	public void start(TransObjectContext ctx) {
-		transUtils.writeInfo(ctx, "info", "start");
-	}
-
-	// 初始化类型
-	public void initClass(TransObjectContext ctx) {
-		transUtils.initClass(ctx);
-	}
-
-	// 迁移项目
-	public void transProject(TransObjectContext ctx) {
-		transByType(ctx, "project", "Pj");
-	}
-
-	// 迁移建筑
-	public void transBuilding(TransObjectContext ctx) {
-		transByType(ctx, "building", "Bd");
-	}
-
-	// 迁移楼层
-	public void transFloor(TransObjectContext ctx) {
-		transByType(ctx, "floor", "Fl");
-	}
-
-	// 迁移竖井
-	public void transShaft(TransObjectContext ctx) {
-		transByType(ctx, "shaft", "Sh");
-	}
-
-	private void transByType(TransObjectContext ctx, String objType, String type) {
-		String classCode = ctx.getClassCodeMapping().get(type);
-		if (classCode == null) {
-			transUtils.writeInfo(ctx, "error", "类型[" + type + "]未定义");
-			return;
-		}
-		List<ObjectNode> list = transUtils.queryObject(ctx, type);
-		if (list == null) {
-			return;
-		}
-		// 加载信息点
-		transUtils.initFuncidCache(ctx, classCode);
-		List<ObjectNode> objects = transUtils.toDmpObject(ctx, list, objType, classCode);
-		transUtils.save(ctx, objects, type);
-	}
-
-	// 迁移空间
-	public void transSpace(TransObjectContext ctx) {
-		String objType = "space";
-		List<ObjectNode> list = transUtils.queryObject(ctx, "Sp");
-		if (list == null) {
-			return;
-		}
-		Set<String> businessTypes = new HashSet<>();
-		for (ObjectNode obj : list) {
-			businessTypes.add(obj.get("businessType").asText());
-		}
-
-		for (String classCode : businessTypes) {
-			// 加载信息点
-			transUtils.initFuncidCache(ctx, classCode);
-
-			List<ObjectNode> data = new LinkedList<>();
-			for (ObjectNode obj : list) {
-				String businessType = JacksonMapper.getString(obj, "businessType");
-				if (classCode.equalsIgnoreCase(businessType)) {
-					obj.remove("businessType");
-					data.add(obj);
-				}
-			}
-			List<ObjectNode> objects = transUtils.toDmpObject(ctx, data, objType, classCode);
-			transUtils.save(ctx, objects, classCode);
-		}
-	}
-
-	// 迁移系统设备部件
-	public void transEquipment(TransObjectContext ctx) {
-		String url = ctx.getServer() + "/data-platform-3/dict/query/equipment_all?project_id=" + ctx.getProjectId();
-		HttpUtils.HttpResult httpResult = httpUtils.get(url, 300 * 1000);
-		if (!httpResult.success()) {
-			transUtils.writeInfo(ctx, "error", "查询系统设备部件类型失败");
-			return;
-		}
-		String content = httpResult.getContent();
-		ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
-		String result = JacksonMapper.getString(objectNode, "Result");
-		if (!"success".equalsIgnoreCase(result)) {
-			transUtils.writeInfo(ctx, "error", "查询系统设备部件类型失败: " + JacksonMapper.getString(objectNode, "ResultMsg"));
-			return;
-		}
-		// 专业
-		ArrayNode array = JacksonMapper.getArray(objectNode, "Content");
-		for (JsonNode majorNode : array) {
-			ObjectNode major = (ObjectNode) majorNode;
-			String majorCode = JacksonMapper.getString(major, "code");
-			String majorName = JacksonMapper.getString(major, "class");
-			transUtils.writeInfo(ctx, "info", "专业迁移开始: " + majorCode + " " + majorName);
-
-			// 系统
-			ArrayNode systemArray = JacksonMapper.getArray(major, "content", JsonNodeFactory.instance.arrayNode());
-			for (JsonNode systemNode : systemArray) {
-				ObjectNode system = (ObjectNode) systemNode;
-				String systemCode = JacksonMapper.getString(system, "code");
-				String systemName = JacksonMapper.getString(system, "system");
-				transUtils.writeInfo(ctx, "info", "系统迁移开始: " + systemCode + " " + systemName);
-				transByType(ctx, "system", systemCode);
-				transUtils.writeInfo(ctx, "info", "系统迁移完成: " + systemCode + " " + systemName);
-
-				// 设备
-				ArrayNode equipArray = JacksonMapper.getArray(system, "content", JsonNodeFactory.instance.arrayNode());
-				for (JsonNode eqiupNode : equipArray) {
-					ObjectNode equip = (ObjectNode) eqiupNode;
-					String equipCode = JacksonMapper.getString(equip, "code");
-					String equipName = JacksonMapper.getString(equip, "facility");
-					transUtils.writeInfo(ctx, "info", "设备迁移开始: " + equipCode + " " + equipName);
-					transByType(ctx, "equipment", equipCode);
-					transUtils.writeInfo(ctx, "info", "设备迁移完成: " + equipCode + " " + equipName);
-
-					// 部件
-					ArrayNode componentArray = JacksonMapper.getArray(system, "components", JsonNodeFactory.instance.arrayNode());
-					for (JsonNode componentNode : componentArray) {
-						ObjectNode component = (ObjectNode) componentNode;
-						String componentCode = JacksonMapper.getString(equip, "code");
-						String componentName = JacksonMapper.getString(equip, "component");
-
-						transUtils.writeInfo(ctx, "info", "部件迁移开始: " + componentCode + " " + componentName);
-						transByType(ctx, "component", componentCode);
-						transUtils.writeInfo(ctx, "info", "部件迁移完成: " + componentCode + " " + componentName);
-					}
-				}
-			}
-			transUtils.writeInfo(ctx, "info", "专业迁移完成: " + majorCode + " " + majorName);
-		}
-	}
-
-	// 迁移关系
-	public void transRelation(TransObjectContext ctx) {
-		transUtils.transRelation(ctx);
-	}
-
-	// 处理失效数据
-	public void transInvalidObject(TransObjectContext ctx) {
-		transUtils.transInvalidObject(ctx);
-	}
-
-	public void over(TransObjectContext context) {
-		transUtils.writeInfo(context, "over", null);
-		String key = KEY_TRANS + context.getProjectId();
-		redis.delete(key);
-	}
-
+    private static final String KEY_TRANS = "admin_trans_";
+
+    @Autowired
+    private RwdTransUtils transUtils;
+
+    @Autowired
+    private HttpUtils httpUtils;
+
+    @Value("${persagy.dmp.server}")
+    private String dmpServer;
+
+    @Autowired
+    private StringRedisTemplate redis;
+
+    @Autowired
+    private TransObjectInfoRepository objectInfoRepository;
+
+    // 更新数据
+    @Transactional
+    public MapResponse againTrans(String groupCode, String projectId, List<TransObjectInfo> transObjectInfoList) {
+        MapResponse resp = new MapResponse();
+        log.info("object again trans start size: {}", transObjectInfoList.size());
+
+        Map<String, List<TransObjectInfo>> objectMap = new HashMap<>();
+        for (TransObjectInfo transObjectInfo : transObjectInfoList) {
+            String objectId = transObjectInfo.getObjectId();
+            if (objectId != null) {
+                objectMap.computeIfAbsent(objectId, k -> new ArrayList<>());
+                objectMap.get(objectId).add(transObjectInfo);
+            }
+        }
+        if (objectMap.size() == 0) {
+            return resp;
+        }
+
+        String key = KEY_TRANS + projectId;
+        Long flag = redis.opsForValue().increment(key, 1L);
+        if (flag > 1) {
+            resp.setFail("正在处理中...");
+            return resp;
+        }
+        redis.expire(key, 24, TimeUnit.HOURS);
+
+        objectInfoRepository.deleteByProjectIdAndObjectId(projectId);
+
+        TransObjectContext ctx = new TransObjectContext();
+        ctx.setAppId("datautils");
+        ctx.setUserId("system");
+        ctx.setGroupCode(groupCode);
+        ctx.setProjectId(projectId);
+        List<TransObjectInfo> logs = new ArrayList<>();
+        objectMap.values().forEach(logs::addAll);
+        //启动
+        start(ctx);
+        ctx.setLogs(logs);
+        initClass(ctx);
+        // 更新数据到中台
+        transUtils.updateObject(ctx, objectMap);
+        return resp;
+    }
+
+    // 开始迁移
+    @Transactional
+    public MapResponse trans(Map<String, Object> param) {
+        MapResponse resp = new MapResponse();
+        String groupCode = MapUtils.getString(param, "groupCode");
+        if (groupCode == null) {
+            resp.setFail("groupCode is required");
+            return resp;
+        }
+        String projectId = MapUtils.getString(param, "projectId");
+        if (projectId == null) {
+            resp.setFail("projectId is required");
+            return resp;
+        }
+        String server = MapUtils.getString(param, "server");
+        if (server == null) {
+            resp.setFail("server is required");
+            return resp;
+        }
+        String secret = MapUtils.getString(param, "secret");
+        if (secret == null) {
+            resp.setFail("secret is required");
+            return resp;
+        }
+        log.info("object trans start: {}", JacksonMapper.toSimpleJson(param));
+
+        String key = KEY_TRANS + projectId;
+        Long flag = redis.opsForValue().increment(key, 1L);
+        if (flag > 1) {
+            resp.setFail("正在处理中...");
+            return resp;
+        }
+        redis.expire(key, 24, TimeUnit.HOURS);
+
+        objectInfoRepository.deleteByProjectId(projectId);
+
+        DmpMessage message = new DmpMessage("transObject", projectId);
+        message.setGroupCode(groupCode);
+        message.setProjectId(projectId);
+        message.setStr1(server);
+        message.setStr2(secret);
+        resp.add(message);
+        return resp;
+    }
+
+    // 开始标记
+    public void start(TransObjectContext ctx) {
+        transUtils.writeInfo(ctx, "info", "start");
+    }
+
+    // 初始化类型
+    public void initClass(TransObjectContext ctx) {
+        transUtils.initClass(ctx);
+    }
+
+    // 迁移项目
+    public void transProject(TransObjectContext ctx) {
+        transByType(ctx, "project", "Pj");
+    }
+
+    // 迁移建筑
+    public void transBuilding(TransObjectContext ctx) {
+        transByType(ctx, "building", "Bd");
+    }
+
+    // 迁移楼层
+    public void transFloor(TransObjectContext ctx) {
+        transByType(ctx, "floor", "Fl");
+    }
+
+    // 迁移竖井
+    public void transShaft(TransObjectContext ctx) {
+        transByType(ctx, "shaft", "Sh");
+    }
+
+    private void transByType(TransObjectContext ctx, String objType, String type) {
+        String classCode = ctx.getClassCodeMapping().get(type);
+        if (classCode == null) {
+            transUtils.writeInfo(ctx, "error", "类型[" + type + "]未定义");
+            return;
+        }
+        List<ObjectNode> list = transUtils.queryObject(ctx, type);
+        if (list == null) {
+            return;
+        }
+        // 加载信息点
+        transUtils.initFuncidCache(ctx, classCode);
+        List<ObjectNode> objects = transUtils.toDmpObject(ctx, list, objType, classCode);
+        transUtils.save(ctx, objects, type);
+    }
+
+    // 迁移空间
+    public void transSpace(TransObjectContext ctx) {
+        String objType = "space";
+        List<ObjectNode> list = transUtils.queryObject(ctx, "Sp");
+        if (list == null) {
+            return;
+        }
+        Set<String> businessTypes = new HashSet<>();
+        for (ObjectNode obj : list) {
+            businessTypes.add(obj.get("businessType").asText());
+        }
+
+        for (String classCode : businessTypes) {
+            // 加载信息点
+            transUtils.initFuncidCache(ctx, classCode);
+
+            List<ObjectNode> data = new LinkedList<>();
+            for (ObjectNode obj : list) {
+                String businessType = JacksonMapper.getString(obj, "businessType");
+                if (classCode.equalsIgnoreCase(businessType)) {
+                    obj.remove("businessType");
+                    data.add(obj);
+                }
+            }
+            List<ObjectNode> objects = transUtils.toDmpObject(ctx, data, objType, classCode);
+            transUtils.save(ctx, objects, classCode);
+        }
+    }
+
+    // 迁移系统设备部件
+    public void transEquipment(TransObjectContext ctx) {
+        String url = ctx.getServer() + "/data-platform-3/dict/query/equipment_all?project_id=" + ctx.getProjectId();
+        HttpUtils.HttpResult httpResult = httpUtils.get(url, 300 * 1000);
+        if (!httpResult.success()) {
+            transUtils.writeInfo(ctx, "error", "查询系统设备部件类型失败");
+            return;
+        }
+        String content = httpResult.getContent();
+        ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
+        String result = JacksonMapper.getString(objectNode, "Result");
+        if (!"success".equalsIgnoreCase(result)) {
+            transUtils.writeInfo(ctx, "error", "查询系统设备部件类型失败: " + JacksonMapper.getString(objectNode, "ResultMsg"));
+            return;
+        }
+        // 专业
+        ArrayNode array = JacksonMapper.getArray(objectNode, "Content");
+        for (JsonNode majorNode : array) {
+            ObjectNode major = (ObjectNode) majorNode;
+            String majorCode = JacksonMapper.getString(major, "code");
+            String majorName = JacksonMapper.getString(major, "class");
+            transUtils.writeInfo(ctx, "info", "专业迁移开始: " + majorCode + " " + majorName);
+
+            // 系统
+            ArrayNode systemArray = JacksonMapper.getArray(major, "content", JsonNodeFactory.instance.arrayNode());
+            for (JsonNode systemNode : systemArray) {
+                ObjectNode system = (ObjectNode) systemNode;
+                String systemCode = JacksonMapper.getString(system, "code");
+                String systemName = JacksonMapper.getString(system, "system");
+                transUtils.writeInfo(ctx, "info", "系统迁移开始: " + systemCode + " " + systemName);
+                transByType(ctx, "system", systemCode);
+                transUtils.writeInfo(ctx, "info", "系统迁移完成: " + systemCode + " " + systemName);
+
+                // 设备
+                ArrayNode equipArray = JacksonMapper.getArray(system, "content", JsonNodeFactory.instance.arrayNode());
+                for (JsonNode eqiupNode : equipArray) {
+                    ObjectNode equip = (ObjectNode) eqiupNode;
+                    String equipCode = JacksonMapper.getString(equip, "code");
+                    String equipName = JacksonMapper.getString(equip, "facility");
+                    transUtils.writeInfo(ctx, "info", "设备迁移开始: " + equipCode + " " + equipName);
+                    transByType(ctx, "equipment", equipCode);
+                    transUtils.writeInfo(ctx, "info", "设备迁移完成: " + equipCode + " " + equipName);
+
+                    // 部件
+                    ArrayNode componentArray = JacksonMapper.getArray(system, "components", JsonNodeFactory.instance.arrayNode());
+                    for (JsonNode componentNode : componentArray) {
+                        ObjectNode component = (ObjectNode) componentNode;
+                        String componentCode = JacksonMapper.getString(equip, "code");
+                        String componentName = JacksonMapper.getString(equip, "component");
+
+                        transUtils.writeInfo(ctx, "info", "部件迁移开始: " + componentCode + " " + componentName);
+                        transByType(ctx, "component", componentCode);
+                        transUtils.writeInfo(ctx, "info", "部件迁移完成: " + componentCode + " " + componentName);
+                    }
+                }
+            }
+            transUtils.writeInfo(ctx, "info", "专业迁移完成: " + majorCode + " " + majorName);
+        }
+    }
+
+    // 迁移关系
+    public void transRelation(TransObjectContext ctx) {
+        transUtils.transRelation(ctx);
+    }
+
+    // 处理失效数据
+    public void transInvalidObject(TransObjectContext ctx) {
+        transUtils.transInvalidObject(ctx);
+    }
+
+    public void over(TransObjectContext context) {
+        transUtils.writeInfo(context, "over", null);
+        String key = KEY_TRANS + context.getProjectId();
+        redis.delete(key);
+    }
 }

+ 115 - 51
dmp-admin/src/main/java/com/persagy/dmp/admin/service/TransObjectInfoService.java

@@ -9,16 +9,21 @@ import com.persagy.dmp.admin.entity.TransObjectInfo;
 import com.persagy.dmp.admin.model.DownloadModel;
 import com.persagy.dmp.admin.repository.TransObjectInfoRepository;
 import com.persagy.dmp.common.excel.ExcelUtils;
+import com.persagy.dmp.common.excel.SheetReadInfo;
 import com.persagy.dmp.common.excel.SheetWriteInfo;
+import org.apache.commons.collections4.MapUtils;
 import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.transaction.Transactional;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author: yaoll
@@ -28,59 +33,118 @@ import java.util.List;
 @Service
 public class TransObjectInfoService {
 
-	@Autowired
-	private CriteriaUtils criteriaUtils;
+    @Autowired
+    private CriteriaUtils criteriaUtils;
 
-	@Autowired
-	private TransObjectInfoRepository objectInfoRepository;
+    @Autowired
+    private TransObjectInfoRepository objectInfoRepository;
 
-	public PagedResponse<TransObjectInfo> query(JacksonCriteria criteria) {
-		return criteriaUtils.query(QTransObjectInfo.transObjectInfo, null, criteria);
-	}
+    @Autowired
+    private DmpTransObjectService transObjectService;
 
-	@Transactional
-	public MapResponse deleteByProjectId(String projectId) {
-		MapResponse resp = new MapResponse();
-		if (projectId != null) {
-			objectInfoRepository.deleteByProjectId(projectId);
-		}
-		return resp;
-	}
+    public PagedResponse<TransObjectInfo> query(JacksonCriteria criteria) {
+        return criteriaUtils.query(QTransObjectInfo.transObjectInfo, null, criteria);
+    }
 
-	public DownloadModel download(String projectId) {
-		DownloadModel result = new DownloadModel();
-		result.setName("异常数据-" + projectId + ".xlsx");
-		List<SheetWriteInfo> list = new ArrayList<>(1);
-		SheetWriteInfo<TransObjectInfo> info = new SheetWriteInfo<>();
-		JacksonCriteria criteria = JacksonCriteria.newInstance();
-		criteria.setWithoutCount(true);
-		criteria.setOrders(Arrays.asList(new JacksonCriteria.Order("id", true)));
-		criteria.add("projectId", projectId);
-		criteria.add("type", "error");
-		info.setData(query(criteria).getData());
-		info.setSheetName("异常数据");
-		info.addColumn("项目ID", "projectId", "string", 30, HorizontalAlignment.CENTER);
-		info.addColumn("对象类型", "classCode", "string", 30, HorizontalAlignment.CENTER);
-		info.addColumn("对象ID", "objectId", "string", 80, HorizontalAlignment.CENTER);
-		info.addColumn("信息点编码", "infoCode", "string", 30, HorizontalAlignment.CENTER);
-		info.addColumn("信息点值", "infoCodeValue", "string", 130, HorizontalAlignment.CENTER);
-		info.addColumn("类型", "type", "string", 30, HorizontalAlignment.CENTER);
-		info.addColumn("异常信息", "message", "string", 200, HorizontalAlignment.LEFT);
-		info.setDataHandler((data, prop) -> {
-			switch (prop){
-				case "projectId": return data.getProjectId();
-				case "type": return data.getType();
-				case "classCode": return data.getClassCode();
-				case "objectId": return data.getObjectId();
-				case "infoCode": return data.getInfoCode();
-				case "infoCodeValue": return data.getInfoCodeValue();
-				case "message": return data.getMessage();
-			}
-			return null;
-		});
-		list.add(info);
-		Workbook workbook = ExcelUtils.createExcel(list);
-		result.setWorkbook(workbook);
-		return result;
-	}
+    @Transactional
+    public MapResponse deleteByProjectId(String projectId) {
+        MapResponse resp = new MapResponse();
+        if (projectId != null) {
+            objectInfoRepository.deleteByProjectId(projectId);
+        }
+        return resp;
+    }
+
+    public DownloadModel download(String projectId) {
+        DownloadModel result = new DownloadModel();
+        result.setName("异常数据-" + projectId + ".xlsx");
+        List<SheetWriteInfo> list = new ArrayList<>(1);
+        SheetWriteInfo<TransObjectInfo> info = new SheetWriteInfo<>();
+        JacksonCriteria criteria = JacksonCriteria.newInstance();
+        criteria.setWithoutCount(true);
+        criteria.setOrders(Arrays.asList(new JacksonCriteria.Order("id", true)));
+        criteria.add("projectId", projectId);
+        criteria.add("type", "error");
+        info.setData(query(criteria).getData());
+        info.setSheetName("异常数据");
+        info.addColumn("项目ID", "projectId", "string", 30, HorizontalAlignment.CENTER);
+        info.addColumn("对象类型", "classCode", "string", 30, HorizontalAlignment.CENTER);
+        info.addColumn("对象ID", "objectId", "string", 80, HorizontalAlignment.CENTER);
+        info.addColumn("信息点编码", "infoCode", "string", 30, HorizontalAlignment.CENTER);
+        info.addColumn("信息点值", "infoCodeValue", "string", 130, HorizontalAlignment.CENTER);
+        info.addColumn("类型", "type", "string", 30, HorizontalAlignment.CENTER);
+        info.addColumn("异常信息", "message", "string", 200, HorizontalAlignment.LEFT);
+        info.setDataHandler((data, prop) -> {
+            switch (prop) {
+                case "projectId":
+                    return data.getProjectId();
+                case "type":
+                    return data.getType();
+                case "classCode":
+                    return data.getClassCode();
+                case "objectId":
+                    return data.getObjectId();
+                case "infoCode":
+                    return data.getInfoCode();
+                case "infoCodeValue":
+                    return data.getInfoCodeValue();
+                case "message":
+                    return data.getMessage();
+            }
+            return null;
+        });
+        list.add(info);
+        Workbook workbook = ExcelUtils.createExcel(list);
+        result.setWorkbook(workbook);
+        return result;
+    }
+
+    public MapResponse upload(String groupCode, String projectId, MultipartFile file) {
+        List<TransObjectInfo> transObjectInfoList = null;
+        try {
+            transObjectInfoList = CompareDataExcelRead(file);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return transObjectService.againTrans(groupCode, projectId, transObjectInfoList);
+    }
+
+    public List<TransObjectInfo> CompareDataExcelRead(MultipartFile file) throws IOException {
+        SheetReadInfo info = new SheetReadInfo();
+        info.setStartRow(1);
+        info.add(0, "projectId", "string");
+        info.add(1, "classCode", "string");
+        info.add(2, "objectId", "string");
+        info.add(3, "infoCode", "string");
+        info.add(4, "infoCodeValue", "string");
+        info.add(5, "type", "string");
+        info.add(6, "message", "string");
+
+        List<Map<String, Object>> result = ExcelUtils.read(file.getInputStream(), info);
+
+        List<TransObjectInfo> transObjectInfoList = new ArrayList<>();
+        for (Map<String, Object> map : result) {
+            String projectId = MapUtils.getString(map, "projectId");
+            String classCode = MapUtils.getString(map, "classCode");
+            String objectId = MapUtils.getString(map, "objectId");
+            String infoCode = MapUtils.getString(map, "infoCode");
+            String infoCodeValue = MapUtils.getString(map, "infoCodeValue");
+            String type = MapUtils.getString(map, "type");
+            String message = MapUtils.getString(map, "message");
+            if (classCode != null) {
+                System.out.println();
+            }
+
+            TransObjectInfo transObjectInfo = new TransObjectInfo();
+            transObjectInfo.setProjectId(projectId);
+            transObjectInfo.setClassCode(classCode);
+            transObjectInfo.setObjectId(objectId);
+            transObjectInfo.setInfoCode(infoCode);
+            transObjectInfo.setInfoCodeValue(infoCodeValue);
+            transObjectInfo.setType(type);
+            transObjectInfo.setMessage(message);
+            transObjectInfoList.add(transObjectInfo);
+        }
+        return transObjectInfoList;
+    }
 }

+ 389 - 358
dmp-admin/src/main/java/com/persagy/dmp/admin/service/trans/RwdTransUtils.java

@@ -32,364 +32,395 @@ import java.util.*;
 @Component
 public class RwdTransUtils {
 
-	@Autowired
-	private HttpUtils httpUtils;
-
-	@Value("${persagy.dmp.server}")
-	private String dmpServer;
-
-	@Autowired
-	private StringRedisTemplate redis;
-
-	@Autowired
-	private InfoCodeParserFactory infoCodeParserFactory;
-
-	@Autowired
-	private TransObjectInfoRepository objectInfoRepository;
-
-	// 初始化类型
-	public void initClass(TransObjectContext ctx) {
-		ArrayNode classes = queryClass(ctx);
-		ctx.getObjTypeMapping().put("Bd", "building");
-		ctx.getObjTypeMapping().put("Fl", "floor");
-		ctx.getObjTypeMapping().put("Sp", "space");
-		ctx.getObjTypeMapping().put("Eq", "equipment");
-		ctx.getObjTypeMapping().put("Ec", "component");
-		ctx.getObjTypeMapping().put("Sh", "shaft");
-
-		ctx.getClassCodeMapping().put("Pj", "project");
-		ctx.getClassCodeMapping().put("Bd", "building");
-		ctx.getClassCodeMapping().put("Fl", "floor");
-		ctx.getClassCodeMapping().put("Sy", "system");
-		ctx.getClassCodeMapping().put("Sh", "shaft");
-
-		for (JsonNode cla : classes) {
-			ObjectNode obj = (ObjectNode) cla;
-			String parentCode = JacksonMapper.getString(obj, "parentCode", "");
-			String code = JacksonMapper.getString(obj, "code");
-			if ("equipment".equals(parentCode) || "system".equals(parentCode) || "component".equals(parentCode)) {
-				ctx.getClassCodeMapping().put(code.substring(2), code);
-			} else if ("space".equals(parentCode)) {
-				ctx.getClassCodeMapping().put(code, code);
-			}
-		}
-	}
-
-	private ArrayNode queryClass(TransObjectContext ctx) {
-		String url = dmpServer + "/rwd/def/class?" + getQueryString(ctx);
-		JacksonCriteria criteria = JacksonCriteria.newInstance();
-		HttpUtils.HttpResult result = httpUtils.post(url, JacksonMapper.toSimpleJson(criteria), 30000);
-		if (result.success()) {
-			String content = result.getContent();
-			ObjectNode object = JacksonMapper.toObject(content, ObjectNode.class);
-			ArrayNode data = JacksonMapper.getArray(object, "data");
-			return data;
-		} else {
-			log.error("query class error: {}", result.getContent());
-		}
-		return JsonNodeFactory.instance.arrayNode();
-	}
-
-	// 初始化信息点
-	public void initFuncidCache(TransObjectContext ctx, String classCode) {
-		if (!ctx.getFuncidModelCache().containsKey(classCode)) {
-			Map<String, FuncidDefModel> funcidCache = new HashMap<>();
-			String url = dmpServer + "/rwd/def/funcid?" + getQueryString(ctx);
-			JacksonCriteria criteria = JacksonCriteria.newInstance();
-			criteria.add("classCode", classCode);
-			HttpUtils.HttpResult result = httpUtils.post(url, JacksonMapper.toSimpleJson(criteria), 300000);
-			if (result.success()) {
-				String content = result.getContent();
-				ObjectNode object = JacksonMapper.toObject(content, ObjectNode.class);
-				ArrayNode data = JacksonMapper.getArray(object, "data", JsonNodeFactory.instance.arrayNode());
-
-				for (JsonNode datum : data) {
-					ObjectNode funcJson = (ObjectNode) datum;
-					FuncidDefModel funcidDefModel = JacksonMapper.toObject(funcJson.toString(), FuncidDefModel.class);
-					funcidCache.put(funcidDefModel.getOrigCode(), funcidDefModel);
-				}
-			}
-			ctx.getFuncidModelCache().put(classCode, funcidCache);
-		}
-	}
-
-	// 查询数据平台数据
-	public List<ObjectNode> queryObject(TransObjectContext context, String types) {
-		String url = context.getServer() + "/data-platform-3/object/subset_query?debug&projectId=" + context.getProjectId() + "&secret=" + context.getSecret();
-		String param = "{\"customInfo\": true, \"valid\": null, \"linkInfos\": false, \"criteria\":{\"type\": [ \"" + types + "\"]}}";
-		HttpUtils.HttpResult post = httpUtils.post(url, param, 3600 * 1000);
-		if (!post.success()) {
-			writeInfo(context, "error", "查询对象" + JacksonMapper.toSimpleJson(types) + "失败");
-			return null;
-		}
-		String content = post.getContent();
-		ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
-		String result = JacksonMapper.getString(objectNode, "Result");
-		if (!"success".equalsIgnoreCase(result)) {
-			writeInfo(context, "error", "查询对象" + JacksonMapper.toSimpleJson(types) + "失败:" + JacksonMapper.getString(objectNode, "ResultMsg"));
-			return null;
-		}
-		ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
-
-		List<ObjectNode> objects = new LinkedList<>();
-		for (JsonNode jsonNode : array) {
-			ObjectNode obj = (ObjectNode) jsonNode;
-			ObjectNode infos = JacksonMapper.getObject(obj, "infos");
-			infos.put("id", JacksonMapper.getString(obj, "id"));
+    @Autowired
+    private HttpUtils httpUtils;
+
+    @Value("${persagy.dmp.server}")
+    private String dmpServer;
+
+    @Autowired
+    private StringRedisTemplate redis;
+
+    @Autowired
+    private InfoCodeParserFactory infoCodeParserFactory;
+
+    @Autowired
+    private TransObjectInfoRepository objectInfoRepository;
+
+    // 初始化类型
+    public void initClass(TransObjectContext ctx) {
+        ArrayNode classes = queryClass(ctx);
+        ctx.getObjTypeMapping().put("Bd", "building");
+        ctx.getObjTypeMapping().put("Fl", "floor");
+        ctx.getObjTypeMapping().put("Sp", "space");
+        ctx.getObjTypeMapping().put("Eq", "equipment");
+        ctx.getObjTypeMapping().put("Ec", "component");
+        ctx.getObjTypeMapping().put("Sh", "shaft");
+
+        ctx.getClassCodeMapping().put("Pj", "project");
+        ctx.getClassCodeMapping().put("Bd", "building");
+        ctx.getClassCodeMapping().put("Fl", "floor");
+        ctx.getClassCodeMapping().put("Sy", "system");
+        ctx.getClassCodeMapping().put("Sh", "shaft");
+
+        for (JsonNode cla : classes) {
+            ObjectNode obj = (ObjectNode) cla;
+            String parentCode = JacksonMapper.getString(obj, "parentCode", "");
+            String code = JacksonMapper.getString(obj, "code");
+            if ("equipment".equals(parentCode) || "system".equals(parentCode) || "component".equals(parentCode)) {
+                ctx.getClassCodeMapping().put(code.substring(2), code);
+            } else if ("space".equals(parentCode)) {
+                ctx.getClassCodeMapping().put(code, code);
+            }
+        }
+    }
+
+    private ArrayNode queryClass(TransObjectContext ctx) {
+        String url = dmpServer + "/rwd/def/class?" + getQueryString(ctx);
+        JacksonCriteria criteria = JacksonCriteria.newInstance();
+        HttpUtils.HttpResult result = httpUtils.post(url, JacksonMapper.toSimpleJson(criteria), 30000);
+        if (result.success()) {
+            String content = result.getContent();
+            ObjectNode object = JacksonMapper.toObject(content, ObjectNode.class);
+            ArrayNode data = JacksonMapper.getArray(object, "data");
+            return data;
+        } else {
+            log.error("query class error: {}", result.getContent());
+        }
+        return JsonNodeFactory.instance.arrayNode();
+    }
+
+    public void updateObject(TransObjectContext ctx, Map<String, List<TransObjectInfo>> infoMap) {
+        List<Map<String, Object>> data = new ArrayList<>();
+        for (Map.Entry<String, List<TransObjectInfo>> entry : infoMap.entrySet()) {
+            Map<String, Object> obj = new HashMap<>();
+            String id = entry.getKey();
+            obj.put("id", id);
+            for (TransObjectInfo transObjectInfo : entry.getValue()) {
+                String infoCode = transObjectInfo.getInfoCode();
+                String infoCodeValue = transObjectInfo.getInfoCodeValue();
+                obj.put(infoCode, infoCodeValue);
+            }
+            data.add(obj);
+        }
+        String url = dmpServer + "/rwd/instance/object/update?" + getQueryString(ctx);
+        HttpUtils.HttpResult httpResult = httpUtils.post(url, JacksonMapper.toSimpleJson(data), 30000);
+        if (httpResult.success()) {
+            String content = httpResult.getContent();
+            ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
+            String result = JacksonMapper.getString(objectNode, "Result");
+            if ("success".equals(result)) {
+                writeInfo(ctx, "success", "更新对象信息点到中台: " + data.size() + ", " + httpResult.getContent());
+            } else {
+                log.error("query class error: {}", httpResult.getContent());
+                objectInfoRepository.saveAll(ctx.getLogs());
+            }
+        } else {
+            log.error("query class error: {}", httpResult.getContent());
+            objectInfoRepository.saveAll(ctx.getLogs());
+        }
+    }
+
+    // 初始化信息点
+    public void initFuncidCache(TransObjectContext ctx, String classCode) {
+        if (!ctx.getFuncidModelCache().containsKey(classCode)) {
+            Map<String, FuncidDefModel> funcidCache = new HashMap<>();
+            String url = dmpServer + "/rwd/def/funcid?" + getQueryString(ctx);
+            JacksonCriteria criteria = JacksonCriteria.newInstance();
+            criteria.add("classCode", classCode);
+            HttpUtils.HttpResult result = httpUtils.post(url, JacksonMapper.toSimpleJson(criteria), 300000);
+            if (result.success()) {
+                String content = result.getContent();
+                ObjectNode object = JacksonMapper.toObject(content, ObjectNode.class);
+                ArrayNode data = JacksonMapper.getArray(object, "data", JsonNodeFactory.instance.arrayNode());
+
+                for (JsonNode datum : data) {
+                    ObjectNode funcJson = (ObjectNode) datum;
+                    FuncidDefModel funcidDefModel = JacksonMapper.toObject(funcJson.toString(), FuncidDefModel.class);
+                    funcidCache.put(funcidDefModel.getOrigCode(), funcidDefModel);
+                }
+            }
+            ctx.getFuncidModelCache().put(classCode, funcidCache);
+        }
+    }
+
+    // 查询数据平台数据
+    public List<ObjectNode> queryObject(TransObjectContext context, String types) {
+        String url = context.getServer() + "/data-platform-3/object/subset_query?debug&projectId=" + context.getProjectId() + "&secret=" + context.getSecret();
+        String param = "{\"customInfo\": true, \"valid\": null, \"linkInfos\": false, \"criteria\":{\"type\": [ \"" + types + "\"]}}";
+        HttpUtils.HttpResult post = httpUtils.post(url, param, 3600 * 1000);
+        if (!post.success()) {
+            writeInfo(context, "error", "查询对象" + JacksonMapper.toSimpleJson(types) + "失败");
+            return null;
+        }
+        String content = post.getContent();
+        ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
+        String result = JacksonMapper.getString(objectNode, "Result");
+        if (!"success".equalsIgnoreCase(result)) {
+            writeInfo(context, "error", "查询对象" + JacksonMapper.toSimpleJson(types) + "失败:" + JacksonMapper.getString(objectNode, "ResultMsg"));
+            return null;
+        }
+        ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
+
+        List<ObjectNode> objects = new LinkedList<>();
+        for (JsonNode jsonNode : array) {
+            ObjectNode obj = (ObjectNode) jsonNode;
+            ObjectNode infos = JacksonMapper.getObject(obj, "infos");
+            infos.put("id", JacksonMapper.getString(obj, "id"));
 //			infos.put("category", JacksonMapper.getString(obj, "category"));
-			if (obj.has("businessType")) {
-				infos.put("businessType", JacksonMapper.getString(obj, "businessType"));
-			}
-			infos.put("create_time", JacksonMapper.getString(obj, "create_time"));
-			objects.add(infos);
-		}
-		return objects;
-	}
-
-	private Set<String> baseInfoCodes = new HashSet<>(Arrays.asList("id", "classCode", "create_time"));
-
-	// 转换为数据中台数据格式
-	public List<ObjectNode> toDmpObject(TransObjectContext ctx, List<ObjectNode> list, String objType, String classCode) {
-		List<ObjectNode> objects = new ArrayList<>(list.size());
-		for (ObjectNode objectNode : list) {
-			String id = JacksonMapper.getString(objectNode, "id");
-			String createTime = JacksonMapper.getString(objectNode, "create_time");
-			ObjectNode obj = JsonNodeFactory.instance.objectNode();
-			objects.add(obj);
-
-			obj.put("id", id);
-			obj.put("objType", objType);
-			obj.put("classCode", objectNode.has("classCode") ? JacksonMapper.getString(objectNode, "classCode") : classCode);
-			obj.put("createTime", createTime);
-			Iterator<String> iterator = objectNode.fieldNames();
-			while (iterator.hasNext()) {
-				String origInfoCode = iterator.next();
-				if (baseInfoCodes.contains(origInfoCode)) {
-					continue;
-				}
-				JsonNode infoValue = objectNode.get(origInfoCode);
-				// 基本字段
-				if (TransUtils.baseColumnMapping.containsKey(origInfoCode)) {
-					obj.put(TransUtils.baseColumnMapping.get(origInfoCode), infoValue.asText());
-					continue;
-				}
-
-				Map<String, FuncidDefModel> funcidCache = ctx.getFuncidModelCache().get(classCode);
-				FuncidDefModel funcidDefModel = funcidCache.get(origInfoCode);
-				if (funcidDefModel == null) {
-					writeInfo(ctx, "error", classCode, "信息点不存在", id, origInfoCode, infoValue.isTextual() ? infoValue.asText() : infoValue.toString());
-					continue;
-				}
-				if (funcidDefModel.getCategory() == FuncidCategory.STATIC) {
-					Boolean isMultiple = funcidDefModel.getIsMultiple();
-					Boolean isRegion = funcidDefModel.getIsRegion();
-					InfoCodeParser parser = infoCodeParserFactory.getParser(funcidDefModel.getDataType());
-					ParserContext parserContext = new ParserContext(funcidDefModel, objectNode.get(origInfoCode));
-					parser.checkValue(parserContext);
-					if (parserContext.isHasError()) {
-						writeInfo(ctx, "error", classCode, parserContext.getError().toString(), id, origInfoCode, infoValue.isTextual() ? infoValue.asText() : infoValue.toString());
-					} else {
-						if (isRegion) {
-							if (isMultiple) {
-								obj.putPOJO(funcidDefModel.getCode(), parserContext.getRegionArray());
-							} else {
-								obj.putPOJO(funcidDefModel.getCode(), parserContext.getRegionValue());
-							}
-						} else {
-							if (isMultiple) {
-								obj.putPOJO(funcidDefModel.getCode(), parserContext.getArrayValue());
-							} else {
-								obj.putPOJO(funcidDefModel.getCode(), parserContext.getValue());
-							}
-						}
-					}
-				} else {
-					// 动态信息点
-					obj.put(funcidDefModel.getCode(), infoValue.asText());
-				}
-			}
-		}
-		return objects;
-	}
-
-	// 保存到数据中台
-	public void save(TransObjectContext ctx, List<ObjectNode> objects, String type) {
-		int begin = 0;
-		while (begin < objects.size()) {
-			int end = begin + 10000;
-			if (end > objects.size()) {
-				end = objects.size();
-			}
-			List<ObjectNode> objectNodes = objects.subList(begin, end);
-			String url = dmpServer + "/rwd/instance/object/create?" + getQueryString(ctx);
-			HttpUtils.HttpResult response = httpUtils.post(url, JacksonMapper.toSimpleJson(objectNodes), 3600000);
-			if (response.success()) {
-				writeInfo(ctx, "success", "对象保存到中台: 类型: " + type + ", 数量: " + objectNodes.size());
-			} else {
-				writeInfo(ctx, "error", "保存到中台时出错: 类型: " + type + ", 信息: " + response.getContent());
-			}
-			begin = end;
-		}
-	}
-
-	// 迁移关系数据
-	public void transRelation(TransObjectContext ctx) {
-
-		writeInfo(ctx, "success", "迁移关系数据开始");
-		// 查询图实例
-		String url = ctx.getServer() + "/data-platform-3/relation/graph_instance/query?projectId=" + ctx.getProjectId() + "&secret" + ctx.getSecret();
-		String requestBody = "{\"criteria\":{}}";
-		HttpUtils.HttpResult post = httpUtils.post(url, requestBody, 300 * 1000);
-		if (!post.success()) {
-			writeInfo(ctx, "error", "查询图实例失败: " + post.getContent());
-			return;
-		}
-		String content = post.getContent();
-		ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
-		String result = JacksonMapper.getString(objectNode, "Result");
-		if (!"success".equalsIgnoreCase(result)) {
-			writeInfo(ctx, "error", "查询图实例失败: " + JacksonMapper.getString(objectNode, "ResultMsg"));
-			return;
-		}
-
-		// 遍历图实例,查询关系,迁移关系
-		ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
-		Set<String> sets = new HashSet<>();
-		for (JsonNode jsonNode : array) {
-			ObjectNode item = (ObjectNode) jsonNode;
-			String graphId = JacksonMapper.getString(item, "graph_id");
-			if (graphId == null) {
-				continue;
-			}
-			sets.add(graphId);
-		}
-		for (String graphId : sets) {
-			transRelationByGraphId(ctx, graphId);
-		}
-		writeInfo(ctx, "success", "迁移关系数据完成");
-	}
-
-	private void transRelationByGraphId(TransObjectContext ctx, String graphId) {
-		String url = ctx.getServer() + "/data-platform-3/relation/query?projectId=" + ctx.getProjectId() + "&secret" + ctx.getSecret();
-		String requestBody = "{\"criteria\":{\"graph_id\":\"" + graphId + "\"}}";
-		HttpUtils.HttpResult post = httpUtils.post(url, requestBody, 300 * 1000);
-		if (!post.success()) {
-			writeInfo(ctx, "error", "查询关系数据失败: " + graphId + ":" + post.getContent());
-			return;
-		}
-		String content = post.getContent();
-		ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
-		String result = JacksonMapper.getString(objectNode, "Result");
-		if (!"success".equalsIgnoreCase(result)) {
-			writeInfo(ctx, "error", "查询关系数据失败: " + graphId + ":" + JacksonMapper.getString(objectNode, "ResultMsg"));
-			return;
-		}
-
-		ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
-		List<RelationInstanceModel> relationInstanceModelList = new ArrayList<>();
-		for (JsonNode jsonNode : array) {
-			ObjectNode item = (ObjectNode) jsonNode;
-			String relType = JacksonMapper.getString(item, "rel_type");
-			String objFrom = JacksonMapper.getString(item, "from_id");
-			String objTo = JacksonMapper.getString(item, "to_id");
-
-			String graphCode = graphId.substring(2, graphId.length() - 3);
-			GraphMapping.Item mapping = GraphMapping.getMapping(graphCode, relType);
-			if (mapping != null) {
-				RelationInstanceModel relation = new RelationInstanceModel();
-				relation.setGraphCode(mapping.getNewGraph());
-				relation.setRelCode(mapping.getNewRelcode());
-				if (mapping.getSame()) {
-					relation.setObjFrom(objFrom);
-					relation.setObjTo(objTo);
-				} else {
-					relation.setObjFrom(objTo);
-					relation.setObjTo(objFrom);
-				}
-				relationInstanceModelList.add(relation);
-			} else {
-				item.put("error", "图类型或边类型错误");
-				writeInfo(ctx, "error", item.toString());
-			}
-		}
-		url = dmpServer + "/rwd/instance/relation/create?" + getQueryString(ctx);
-		HttpUtils.HttpResult response = httpUtils.post(url, JacksonMapper.toSimpleJson(relationInstanceModelList), 3600000);
-		if (response.success()) {
-			writeInfo(ctx, "success", "迁移关系数据到中台成功: 图实例: " + graphId + ", 数量: " + relationInstanceModelList.size());
-		} else {
-			writeInfo(ctx, "error", "迁移关系数据到中台失败: 图实例: " + graphId + ", 信息: " + response.getContent());
-		}
-	}
-
-	// 迁移失效数据
-	public void transInvalidObject(TransObjectContext context) {
-		writeInfo(context, "success", "处理失效对象开始");
-		transInvalidObject(context, "Bd");// 建筑
-		transInvalidObject(context, "Fl");//楼层
-		transInvalidObject(context, "Sp");// 空间
-		transInvalidObject(context, "Sy");// 系统
-		transInvalidObject(context, "Eq");// 设备
-		transInvalidObject(context, "Ec");// 部件
-		transInvalidObject(context, "Sh");// 竖井
-		writeInfo(context, "success", "处理失效对象完成");
-	}
-
-	// 迁移失效数据
-	private void transInvalidObject(TransObjectContext context, String type) {
-		String url = context.getServer() + "/data-platform-3/object/subset_query?debug&projectId=" + context.getProjectId() + "&secret=" + context.getSecret();
-		String requestBody = "{\"customInfo\":true,\"valid\":false,\"criteria\":{\"type\":[\"" + type + "\"]},\"returnInfos\":[]}";
-		HttpUtils.HttpResult post = httpUtils.post(url, requestBody, 3600 * 1000);
-		if (!post.success()) {
-			writeInfo(context, "error", "查询失效对象失败: " + type);
-			return;
-		}
-		String content = post.getContent();
-		ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
-		String result = JacksonMapper.getString(objectNode, "Result");
-		if (!"success".equalsIgnoreCase(result)) {
-			writeInfo(context, "error", "查询失效对象失败: " + type + ",  " + JacksonMapper.getString(objectNode, "ResultMsg"));
-			return;
-		}
-
-		ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
-		List<String> ids = new LinkedList<>();
-		for (JsonNode jsonNode : array) {
-			ObjectNode item = (ObjectNode) jsonNode;
-			String id = JacksonMapper.getString(item, "id");
-			if (id != null) {
-				ids.add(id);
-			}
-		}
-		if (ids.size() > 0) {
-			url = dmpServer + "/rwd/instance/object/delete?" + getQueryString(context);
-			HttpUtils.HttpResult resp = httpUtils.post(url, JacksonMapper.toSimpleJson(ids), 3600 * 1000);
-			writeInfo(context, "success", "处理失效对象成功: " + type + ", " + ids.size() + ", " + resp.getContent());
-		}
-	}
-
-	private String getQueryString(TransObjectContext context) {
-		return "groupCode=" + context.getGroupCode() + "&projectId=" + context.getProjectId() + "&appId=" + context.getAppId() + "&userId=" + context.getUserId();
-	}
-
-	public void writeInfo(TransObjectContext ctx, String type, String msg) {
-		writeInfo(ctx, type, null, msg, null, null, null);
-	}
-
-	public void writeInfo(TransObjectContext ctx, String type, String classCode, String msg, String objectId, String infoCode, String value) {
-		TransObjectInfo info = new TransObjectInfo();
-		info.setProjectId(ctx.getProjectId());
-		info.setType(type);
-		info.setClassCode(classCode);
-		info.setObjectId(objectId);
-		info.setInfoCode(infoCode);
-		info.setInfoCodeValue(value);
-		info.setMessage(msg);
-		ctx.getLogs().add(info);
-
-		if (!"error".equalsIgnoreCase(type) || ctx.getLogs().size() == TransObjectContext.LOGS_CACHE_SIZE) {
-			objectInfoRepository.saveAll(ctx.getLogs());
-			ctx.getLogs().clear();
-		}
-	}
+            if (obj.has("businessType")) {
+                infos.put("businessType", JacksonMapper.getString(obj, "businessType"));
+            }
+            infos.put("create_time", JacksonMapper.getString(obj, "create_time"));
+            objects.add(infos);
+        }
+        return objects;
+    }
+
+    private Set<String> baseInfoCodes = new HashSet<>(Arrays.asList("id", "classCode", "create_time"));
+
+    // 转换为数据中台数据格式
+    public List<ObjectNode> toDmpObject(TransObjectContext ctx, List<ObjectNode> list, String objType, String classCode) {
+        List<ObjectNode> objects = new ArrayList<>(list.size());
+        for (ObjectNode objectNode : list) {
+            String id = JacksonMapper.getString(objectNode, "id");
+            String createTime = JacksonMapper.getString(objectNode, "create_time");
+            ObjectNode obj = JsonNodeFactory.instance.objectNode();
+            objects.add(obj);
+
+            obj.put("id", id);
+            obj.put("objType", objType);
+            obj.put("classCode", objectNode.has("classCode") ? JacksonMapper.getString(objectNode, "classCode") : classCode);
+            obj.put("createTime", createTime);
+            Iterator<String> iterator = objectNode.fieldNames();
+            while (iterator.hasNext()) {
+                String origInfoCode = iterator.next();
+                if (baseInfoCodes.contains(origInfoCode)) {
+                    continue;
+                }
+                JsonNode infoValue = objectNode.get(origInfoCode);
+                // 基本字段
+                if (TransUtils.baseColumnMapping.containsKey(origInfoCode)) {
+                    obj.put(TransUtils.baseColumnMapping.get(origInfoCode), infoValue.asText());
+                    continue;
+                }
+
+                Map<String, FuncidDefModel> funcidCache = ctx.getFuncidModelCache().get(classCode);
+                FuncidDefModel funcidDefModel = funcidCache.get(origInfoCode);
+                if (funcidDefModel == null) {
+                    writeInfo(ctx, "error", classCode, "信息点不存在", id, origInfoCode, infoValue.isTextual() ? infoValue.asText() : infoValue.toString());
+                    continue;
+                }
+                if (funcidDefModel.getCategory() == FuncidCategory.STATIC) {
+                    Boolean isMultiple = funcidDefModel.getIsMultiple();
+                    Boolean isRegion = funcidDefModel.getIsRegion();
+                    InfoCodeParser parser = infoCodeParserFactory.getParser(funcidDefModel.getDataType());
+                    ParserContext parserContext = new ParserContext(funcidDefModel, objectNode.get(origInfoCode));
+                    parser.checkValue(parserContext);
+                    if (parserContext.isHasError()) {
+                        writeInfo(ctx, "error", classCode, parserContext.getError().toString(), id, origInfoCode, infoValue.isTextual() ? infoValue.asText() : infoValue.toString());
+                    } else {
+                        if (isRegion) {
+                            if (isMultiple) {
+                                obj.putPOJO(funcidDefModel.getCode(), parserContext.getRegionArray());
+                            } else {
+                                obj.putPOJO(funcidDefModel.getCode(), parserContext.getRegionValue());
+                            }
+                        } else {
+                            if (isMultiple) {
+                                obj.putPOJO(funcidDefModel.getCode(), parserContext.getArrayValue());
+                            } else {
+                                obj.putPOJO(funcidDefModel.getCode(), parserContext.getValue());
+                            }
+                        }
+                    }
+                } else {
+                    // 动态信息点
+                    obj.put(funcidDefModel.getCode(), infoValue.asText());
+                }
+            }
+        }
+        return objects;
+    }
+
+    // 保存到数据中台
+    public void save(TransObjectContext ctx, List<ObjectNode> objects, String type) {
+        int begin = 0;
+        while (begin < objects.size()) {
+            int end = begin + 10000;
+            if (end > objects.size()) {
+                end = objects.size();
+            }
+            List<ObjectNode> objectNodes = objects.subList(begin, end);
+            String url = dmpServer + "/rwd/instance/object/create?" + getQueryString(ctx);
+            HttpUtils.HttpResult response = httpUtils.post(url, JacksonMapper.toSimpleJson(objectNodes), 3600000);
+            if (response.success()) {
+                writeInfo(ctx, "success", "对象保存到中台: 类型: " + type + ", 数量: " + objectNodes.size());
+            } else {
+                writeInfo(ctx, "error", "保存到中台时出错: 类型: " + type + ", 信息: " + response.getContent());
+            }
+            begin = end;
+        }
+    }
+
+    // 迁移关系数据
+    public void transRelation(TransObjectContext ctx) {
+
+        writeInfo(ctx, "success", "迁移关系数据开始");
+        // 查询图实例
+        String url = ctx.getServer() + "/data-platform-3/relation/graph_instance/query?projectId=" + ctx.getProjectId() + "&secret" + ctx.getSecret();
+        String requestBody = "{\"criteria\":{}}";
+        HttpUtils.HttpResult post = httpUtils.post(url, requestBody, 300 * 1000);
+        if (!post.success()) {
+            writeInfo(ctx, "error", "查询图实例失败: " + post.getContent());
+            return;
+        }
+        String content = post.getContent();
+        ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
+        String result = JacksonMapper.getString(objectNode, "Result");
+        if (!"success".equalsIgnoreCase(result)) {
+            writeInfo(ctx, "error", "查询图实例失败: " + JacksonMapper.getString(objectNode, "ResultMsg"));
+            return;
+        }
+
+        // 遍历图实例,查询关系,迁移关系
+        ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
+        Set<String> sets = new HashSet<>();
+        for (JsonNode jsonNode : array) {
+            ObjectNode item = (ObjectNode) jsonNode;
+            String graphId = JacksonMapper.getString(item, "graph_id");
+            if (graphId == null) {
+                continue;
+            }
+            sets.add(graphId);
+        }
+        for (String graphId : sets) {
+            transRelationByGraphId(ctx, graphId);
+        }
+        writeInfo(ctx, "success", "迁移关系数据完成");
+    }
+
+    private void transRelationByGraphId(TransObjectContext ctx, String graphId) {
+        String url = ctx.getServer() + "/data-platform-3/relation/query?projectId=" + ctx.getProjectId() + "&secret" + ctx.getSecret();
+        String requestBody = "{\"criteria\":{\"graph_id\":\"" + graphId + "\"}}";
+        HttpUtils.HttpResult post = httpUtils.post(url, requestBody, 300 * 1000);
+        if (!post.success()) {
+            writeInfo(ctx, "error", "查询关系数据失败: " + graphId + ":" + post.getContent());
+            return;
+        }
+        String content = post.getContent();
+        ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
+        String result = JacksonMapper.getString(objectNode, "Result");
+        if (!"success".equalsIgnoreCase(result)) {
+            writeInfo(ctx, "error", "查询关系数据失败: " + graphId + ":" + JacksonMapper.getString(objectNode, "ResultMsg"));
+            return;
+        }
+
+        ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
+        List<RelationInstanceModel> relationInstanceModelList = new ArrayList<>();
+        for (JsonNode jsonNode : array) {
+            ObjectNode item = (ObjectNode) jsonNode;
+            String relType = JacksonMapper.getString(item, "rel_type");
+            String objFrom = JacksonMapper.getString(item, "from_id");
+            String objTo = JacksonMapper.getString(item, "to_id");
+
+            String graphCode = graphId.substring(2, graphId.length() - 3);
+            GraphMapping.Item mapping = GraphMapping.getMapping(graphCode, relType);
+            if (mapping != null) {
+                RelationInstanceModel relation = new RelationInstanceModel();
+                relation.setGraphCode(mapping.getNewGraph());
+                relation.setRelCode(mapping.getNewRelcode());
+                if (mapping.getSame()) {
+                    relation.setObjFrom(objFrom);
+                    relation.setObjTo(objTo);
+                } else {
+                    relation.setObjFrom(objTo);
+                    relation.setObjTo(objFrom);
+                }
+                relationInstanceModelList.add(relation);
+            } else {
+                item.put("error", "图类型或边类型错误");
+                writeInfo(ctx, "error", item.toString());
+            }
+        }
+        url = dmpServer + "/rwd/instance/relation/create?" + getQueryString(ctx);
+        HttpUtils.HttpResult response = httpUtils.post(url, JacksonMapper.toSimpleJson(relationInstanceModelList), 3600000);
+        if (response.success()) {
+            writeInfo(ctx, "success", "迁移关系数据到中台成功: 图实例: " + graphId + ", 数量: " + relationInstanceModelList.size());
+        } else {
+            writeInfo(ctx, "error", "迁移关系数据到中台失败: 图实例: " + graphId + ", 信息: " + response.getContent());
+        }
+    }
+
+    // 迁移失效数据
+    public void transInvalidObject(TransObjectContext context) {
+        writeInfo(context, "success", "处理失效对象开始");
+        transInvalidObject(context, "Bd");// 建筑
+        transInvalidObject(context, "Fl");//楼层
+        transInvalidObject(context, "Sp");// 空间
+        transInvalidObject(context, "Sy");// 系统
+        transInvalidObject(context, "Eq");// 设备
+        transInvalidObject(context, "Ec");// 部件
+        transInvalidObject(context, "Sh");// 竖井
+        writeInfo(context, "success", "处理失效对象完成");
+    }
+
+    // 迁移失效数据
+    private void transInvalidObject(TransObjectContext context, String type) {
+        String url = context.getServer() + "/data-platform-3/object/subset_query?debug&projectId=" + context.getProjectId() + "&secret=" + context.getSecret();
+        String requestBody = "{\"customInfo\":true,\"valid\":false,\"criteria\":{\"type\":[\"" + type + "\"]},\"returnInfos\":[]}";
+        HttpUtils.HttpResult post = httpUtils.post(url, requestBody, 3600 * 1000);
+        if (!post.success()) {
+            writeInfo(context, "error", "查询失效对象失败: " + type);
+            return;
+        }
+        String content = post.getContent();
+        ObjectNode objectNode = JacksonMapper.toObject(content, ObjectNode.class);
+        String result = JacksonMapper.getString(objectNode, "Result");
+        if (!"success".equalsIgnoreCase(result)) {
+            writeInfo(context, "error", "查询失效对象失败: " + type + ",  " + JacksonMapper.getString(objectNode, "ResultMsg"));
+            return;
+        }
+
+        ArrayNode array = JacksonMapper.getArray(objectNode, "Content", JsonNodeFactory.instance.arrayNode());
+        List<String> ids = new LinkedList<>();
+        for (JsonNode jsonNode : array) {
+            ObjectNode item = (ObjectNode) jsonNode;
+            String id = JacksonMapper.getString(item, "id");
+            if (id != null) {
+                ids.add(id);
+            }
+        }
+        if (ids.size() > 0) {
+            url = dmpServer + "/rwd/instance/object/delete?" + getQueryString(context);
+            HttpUtils.HttpResult resp = httpUtils.post(url, JacksonMapper.toSimpleJson(ids), 3600 * 1000);
+            writeInfo(context, "success", "处理失效对象成功: " + type + ", " + ids.size() + ", " + resp.getContent());
+        }
+    }
+
+    private String getQueryString(TransObjectContext context) {
+        return "groupCode=" + context.getGroupCode() + "&projectId=" + context.getProjectId() + "&appId=" + context.getAppId() + "&userId=" + context.getUserId();
+    }
+
+    public void writeInfo(TransObjectContext ctx, String type, String msg) {
+        writeInfo(ctx, type, null, msg, null, null, null);
+    }
+
+    public void writeInfo(TransObjectContext ctx, String type, String classCode, String msg, String objectId, String infoCode, String value) {
+        TransObjectInfo info = new TransObjectInfo();
+        info.setProjectId(ctx.getProjectId());
+        info.setType(type);
+        info.setClassCode(classCode);
+        info.setObjectId(objectId);
+        info.setInfoCode(infoCode);
+        info.setInfoCodeValue(value);
+        info.setMessage(msg);
+        ctx.getLogs().add(info);
+
+        if (!"error".equalsIgnoreCase(type) || ctx.getLogs().size() == TransObjectContext.LOGS_CACHE_SIZE) {
+            objectInfoRepository.saveAll(ctx.getLogs());
+            ctx.getLogs().clear();
+        }
+    }
 
 }