YidaFieldMapper.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. package com.malk.eastar.util;
  2. import cn.hutool.core.annotation.Alias;
  3. import java.util.*;
  4. import java.util.stream.Collectors;
  5. /**
  6. * 宜搭表单字段映射工具
  7. * 根据阶段属性匹配表单字段,填充时间数据
  8. */
  9. public class YidaFieldMapper {
  10. /**
  11. * 阶段数据对象
  12. */
  13. public static class StageData {
  14. @Alias("textField_mgu5rm3f")
  15. private String stage; // 阶段:textField_mgu5rm3f
  16. @Alias("dateField_mgu5rm3g")
  17. private String planStartTime; // 计划开始时间:dateField_mgu5rm3g
  18. @Alias("dateField_mp4t9q5o")
  19. private String planStartTimeLatest; // 计划开始时间(最新):dateField_mp4t9q5o
  20. @Alias("dateField_mgu5rm3h")
  21. private String planEndTime; // 计划结束时间:dateField_mgu5rm3h
  22. @Alias("dateField_mp4t9q5p")
  23. private String planEndTimeLatest; // 计划结束时间(最新):dateField_mp4t9q5p
  24. @Alias("dateField_mp4t9q5q")
  25. private String actualStartTime; // 实际开始时间:dateField_mp4t9q5q
  26. @Alias("dateField_mp4t9q5r")
  27. private String actualEndTime; // 实际结束时间:dateField_mp4t9q5r
  28. public StageData() {}
  29. public StageData(String stage, String planStartTime, String planStartTimeLatest,
  30. String planEndTime, String planEndTimeLatest,
  31. String actualStartTime, String actualEndTime) {
  32. this.stage = stage;
  33. this.planStartTime = planStartTime;
  34. this.planStartTimeLatest = planStartTimeLatest;
  35. this.planEndTime = planEndTime;
  36. this.planEndTimeLatest = planEndTimeLatest;
  37. this.actualStartTime = actualStartTime;
  38. this.actualEndTime = actualEndTime;
  39. }
  40. // Getters and Setters
  41. public String getStage() { return stage; }
  42. public void setStage(String stage) { this.stage = stage; }
  43. public String getPlanStartTime() { return planStartTime; }
  44. public void setPlanStartTime(String planStartTime) { this.planStartTime = planStartTime; }
  45. public String getPlanStartTimeLatest() { return planStartTimeLatest; }
  46. public void setPlanStartTimeLatest(String planStartTimeLatest) { this.planStartTimeLatest = planStartTimeLatest; }
  47. public String getPlanEndTime() { return planEndTime; }
  48. public void setPlanEndTime(String planEndTime) { this.planEndTime = planEndTime; }
  49. public String getPlanEndTimeLatest() { return planEndTimeLatest; }
  50. public void setPlanEndTimeLatest(String planEndTimeLatest) { this.planEndTimeLatest = planEndTimeLatest; }
  51. public String getActualStartTime() { return actualStartTime; }
  52. public void setActualStartTime(String actualStartTime) { this.actualStartTime = actualStartTime; }
  53. public String getActualEndTime() { return actualEndTime; }
  54. public void setActualEndTime(String actualEndTime) { this.actualEndTime = actualEndTime; }
  55. }
  56. /**
  57. * 表单字段映射结果
  58. */
  59. static class FormFieldMapping {
  60. private Map<String, String> fieldValues = new HashMap<>();
  61. public void put(String fieldId, String value) {
  62. if (value != null && !value.isEmpty()) {
  63. fieldValues.put(fieldId, value);
  64. }
  65. }
  66. public Map<String, String> getFieldValues() {
  67. return fieldValues;
  68. }
  69. @Override
  70. public String toString() {
  71. return fieldValues.toString();
  72. }
  73. }
  74. /**
  75. * 阶段名称与表单字段前缀的映射关系
  76. * 根据之前获取的宜搭表单字段信息建立映射
  77. */
  78. private static final Map<String, String> STAGE_TO_FIELD_PREFIX = new HashMap<>();
  79. static {
  80. // 初始化阶段与字段前缀的映射关系
  81. // 格式:阶段名称 -> 表单字段名称中"-"之前的部分
  82. STAGE_TO_FIELD_PREFIX.put("立项", "立项");
  83. STAGE_TO_FIELD_PREFIX.put("白样", "白样");
  84. STAGE_TO_FIELD_PREFIX.put("制版", "制版");
  85. STAGE_TO_FIELD_PREFIX.put("产前样", "产前样");
  86. STAGE_TO_FIELD_PREFIX.put("大货样", "大货样");
  87. STAGE_TO_FIELD_PREFIX.put("大货", "大货");
  88. STAGE_TO_FIELD_PREFIX.put("包装", "包装");
  89. STAGE_TO_FIELD_PREFIX.put("出货", "出货");
  90. STAGE_TO_FIELD_PREFIX.put("结项", "结项");
  91. }
  92. /**
  93. * 表单字段ID映射表
  94. * 根据阶段前缀和时间类型获取对应的字段ID
  95. */
  96. private static final Map<String, Map<String, String>> FIELD_ID_MAP = new HashMap<>();
  97. static {
  98. // 立项阶段
  99. Map<String, String> lixiang = new HashMap<>();
  100. lixiang.put("planStartTime", "dateField_mgu5rm3g");
  101. lixiang.put("planStartTimeLatest", "dateField_mp4t9q5o");
  102. lixiang.put("planEndTime", "dateField_mgu5rm3h");
  103. lixiang.put("planEndTimeLatest", "dateField_mp4t9q5p");
  104. lixiang.put("actualStartTime", "dateField_mp4t9q5q");
  105. lixiang.put("actualEndTime", "dateField_mp4t9q5r");
  106. FIELD_ID_MAP.put("立项", lixiang);
  107. // 白样阶段
  108. Map<String, String> baiyang = new HashMap<>();
  109. baiyang.put("planStartTime", "dateField_mpqn6ucm");
  110. baiyang.put("planStartTimeLatest", "dateField_mpqn6uco");
  111. baiyang.put("planEndTime", "dateField_mpqn6ucq");
  112. baiyang.put("planEndTimeLatest", "dateField_mpqn6ucs");
  113. baiyang.put("actualStartTime", "dateField_mpqn6ucv");
  114. baiyang.put("actualEndTime", "dateField_mpqn6ucx");
  115. FIELD_ID_MAP.put("白样", baiyang);
  116. // 制版阶段
  117. Map<String, String> zhiban = new HashMap<>();
  118. zhiban.put("planStartTime", "dateField_mpqn6ud4");
  119. zhiban.put("planStartTimeLatest", "dateField_mpqn6ud6");
  120. zhiban.put("planEndTime", "dateField_mpqn6ud8");
  121. zhiban.put("planEndTimeLatest", "dateField_mpqn6uda");
  122. zhiban.put("actualStartTime", "dateField_mpqn6udd");
  123. zhiban.put("actualEndTime", "dateField_mpqn6udf");
  124. FIELD_ID_MAP.put("制版", zhiban);
  125. // 产前样阶段
  126. Map<String, String> chanqianyang = new HashMap<>();
  127. chanqianyang.put("planStartTime", "dateField_mpqn6udm");
  128. chanqianyang.put("planStartTimeLatest", "dateField_mpqn6udo");
  129. chanqianyang.put("planEndTime", "dateField_mpqn6udq");
  130. chanqianyang.put("planEndTimeLatest", "dateField_mpqn6uds");
  131. chanqianyang.put("actualStartTime", "dateField_mpqn6udv");
  132. chanqianyang.put("actualEndTime", "dateField_mpqn6udx");
  133. FIELD_ID_MAP.put("产前样", chanqianyang);
  134. // 大货样阶段
  135. Map<String, String> dahuoyang = new HashMap<>();
  136. dahuoyang.put("planStartTime", "dateField_mpqn6ue4");
  137. dahuoyang.put("planStartTimeLatest", "dateField_mpqn6ue6");
  138. dahuoyang.put("planEndTime", "dateField_mpqn6ue8");
  139. dahuoyang.put("planEndTimeLatest", "dateField_mpqn6uea");
  140. dahuoyang.put("actualStartTime", "dateField_mpqn6ued");
  141. dahuoyang.put("actualEndTime", "dateField_mpqn6uef");
  142. FIELD_ID_MAP.put("大货样", dahuoyang);
  143. // 大货阶段
  144. Map<String, String> dahuo = new HashMap<>();
  145. dahuo.put("planStartTime", "dateField_mpqn6uem");
  146. dahuo.put("planStartTimeLatest", "dateField_mpqn6ueo");
  147. dahuo.put("planEndTime", "dateField_mpqn6ueq");
  148. dahuo.put("planEndTimeLatest", "dateField_mpqn6ues");
  149. dahuo.put("actualStartTime", "dateField_mpqn6uev");
  150. dahuo.put("actualEndTime", "dateField_mpqn6uex");
  151. FIELD_ID_MAP.put("大货", dahuo);
  152. // 包装阶段
  153. Map<String, String> baozhuang = new HashMap<>();
  154. baozhuang.put("planStartTime", "dateField_mpqn6uf4");
  155. baozhuang.put("planStartTimeLatest", "dateField_mpqn6uf6");
  156. baozhuang.put("planEndTime", "dateField_mpqn6uf8");
  157. baozhuang.put("planEndTimeLatest", "dateField_mpqn6ufa");
  158. baozhuang.put("actualStartTime", "dateField_mpqn6ufd");
  159. baozhuang.put("actualEndTime", "dateField_mpqn6uff");
  160. FIELD_ID_MAP.put("包装", baozhuang);
  161. // 出货阶段
  162. Map<String, String> chuhuo = new HashMap<>();
  163. chuhuo.put("planStartTime", "dateField_mpqn6ufm");
  164. chuhuo.put("planStartTimeLatest", "dateField_mpqn6ufo");
  165. chuhuo.put("planEndTime", "dateField_mpqn6ufq");
  166. chuhuo.put("planEndTimeLatest", "dateField_mpqn6ufs");
  167. chuhuo.put("actualStartTime", "dateField_mpqn6ufv");
  168. chuhuo.put("actualEndTime", "dateField_mpqn6ufx");
  169. FIELD_ID_MAP.put("出货", chuhuo);
  170. // 结项阶段
  171. Map<String, String> jiexiang = new HashMap<>();
  172. jiexiang.put("planStartTime", "dateField_mpqn6ug4");
  173. jiexiang.put("planStartTimeLatest", "dateField_mpqn6ug6");
  174. jiexiang.put("planEndTime", "dateField_mpqn6ug8");
  175. jiexiang.put("planEndTimeLatest", "dateField_mpqn6uga");
  176. jiexiang.put("actualStartTime", "dateField_mpqn6ugd");
  177. jiexiang.put("actualEndTime", "dateField_mpqn6ugf");
  178. FIELD_ID_MAP.put("结项", jiexiang);
  179. }
  180. /**
  181. * 根据阶段数据列表生成表单字段映射
  182. *
  183. * @param stageDataList 阶段数据对象集合
  184. * @return 表单字段ID到值的映射Map
  185. */
  186. public static Map<String, String> mapStageDataToFormFields(List<StageData> stageDataList) {
  187. if (stageDataList == null || stageDataList.isEmpty()) {
  188. return new HashMap<>();
  189. }
  190. Map<String, String> result = new HashMap<>();
  191. for (StageData stageData : stageDataList) {
  192. String stage = stageData.getStage();
  193. if (stage == null || stage.isEmpty()) {
  194. continue;
  195. }
  196. // 查找匹配的阶段前缀
  197. String matchedPrefix = findMatchingStagePrefix(stage);
  198. if (matchedPrefix == null) {
  199. System.out.println("警告:未找到阶段 '" + stage + "' 对应的表单字段前缀");
  200. continue;
  201. }
  202. // 获取该阶段的字段ID映射
  203. Map<String, String> fieldIdMap = FIELD_ID_MAP.get(matchedPrefix);
  204. if (fieldIdMap == null) {
  205. System.out.println("警告:阶段 '" + matchedPrefix + "' 没有配置字段ID映射");
  206. continue;
  207. }
  208. // 填充时间数据到对应的字段
  209. fillTimeData(result, fieldIdMap, stageData);
  210. }
  211. return result;
  212. }
  213. /**
  214. * 查找匹配的阶段前缀
  215. *
  216. * @param stage 阶段值
  217. * @return 匹配的阶段前缀,未找到返回null
  218. */
  219. private static String findMatchingStagePrefix(String stage) {
  220. // 直接匹配
  221. if (STAGE_TO_FIELD_PREFIX.containsKey(stage)) {
  222. return stage;
  223. }
  224. // 尝试模糊匹配:检查阶段值是否包含某个已知阶段名称
  225. for (String knownStage : STAGE_TO_FIELD_PREFIX.keySet()) {
  226. if (stage.contains(knownStage) || knownStage.contains(stage)) {
  227. return knownStage;
  228. }
  229. }
  230. return null;
  231. }
  232. /**
  233. * 填充时间数据到结果Map
  234. *
  235. * @param result 结果Map
  236. * @param fieldIdMap 字段ID映射
  237. * @param stageData 阶段数据
  238. */
  239. private static void fillTimeData(Map<String, String> result,
  240. Map<String, String> fieldIdMap,
  241. StageData stageData) {
  242. // 计划开始时间
  243. if (stageData.getPlanStartTime() != null && !stageData.getPlanStartTime().isEmpty()) {
  244. String fieldId = fieldIdMap.get("planStartTime");
  245. if (fieldId != null) {
  246. result.put(fieldId, stageData.getPlanStartTime());
  247. }
  248. }
  249. // 计划开始时间(最新)
  250. if (stageData.getPlanStartTimeLatest() != null && !stageData.getPlanStartTimeLatest().isEmpty()) {
  251. String fieldId = fieldIdMap.get("planStartTimeLatest");
  252. if (fieldId != null) {
  253. result.put(fieldId, stageData.getPlanStartTimeLatest());
  254. }
  255. }
  256. // 计划结束时间
  257. if (stageData.getPlanEndTime() != null && !stageData.getPlanEndTime().isEmpty()) {
  258. String fieldId = fieldIdMap.get("planEndTime");
  259. if (fieldId != null) {
  260. result.put(fieldId, stageData.getPlanEndTime());
  261. }
  262. }
  263. // 计划结束时间(最新)
  264. if (stageData.getPlanEndTimeLatest() != null && !stageData.getPlanEndTimeLatest().isEmpty()) {
  265. String fieldId = fieldIdMap.get("planEndTimeLatest");
  266. if (fieldId != null) {
  267. result.put(fieldId, stageData.getPlanEndTimeLatest());
  268. }
  269. }
  270. // 实际开始时间
  271. if (stageData.getActualStartTime() != null && !stageData.getActualStartTime().isEmpty()) {
  272. String fieldId = fieldIdMap.get("actualStartTime");
  273. if (fieldId != null) {
  274. result.put(fieldId, stageData.getActualStartTime());
  275. }
  276. }
  277. // 实际结束时间
  278. if (stageData.getActualEndTime() != null && !stageData.getActualEndTime().isEmpty()) {
  279. String fieldId = fieldIdMap.get("actualEndTime");
  280. if (fieldId != null) {
  281. result.put(fieldId, stageData.getActualEndTime());
  282. }
  283. }
  284. }
  285. /**
  286. * 测试方法
  287. */
  288. public static void main(String[] args) {
  289. // 创建测试数据
  290. List<StageData> stageDataList = new ArrayList<>();
  291. // 立项阶段数据
  292. StageData lixiang = new StageData(
  293. "立项",
  294. "2024-01-01",
  295. "2024-01-02",
  296. "2024-01-10",
  297. "2024-01-11",
  298. "2024-01-03",
  299. "2024-01-09"
  300. );
  301. stageDataList.add(lixiang);
  302. // 白样阶段数据
  303. StageData baiyang = new StageData(
  304. "白样",
  305. "2024-01-15",
  306. "2024-01-16",
  307. "2024-01-25",
  308. "2024-01-26",
  309. "2024-01-17",
  310. "2024-01-24"
  311. );
  312. stageDataList.add(baiyang);
  313. // 制版阶段数据
  314. StageData zhiban = new StageData(
  315. "制版",
  316. "2024-02-01",
  317. "2024-02-02",
  318. "2024-02-10",
  319. "2024-02-11",
  320. "2024-02-03",
  321. "2024-02-09"
  322. );
  323. stageDataList.add(zhiban);
  324. // 执行映射
  325. Map<String, String> formFields = mapStageDataToFormFields(stageDataList);
  326. // 输出结果
  327. System.out.println("=== 表单字段映射结果 ===");
  328. System.out.println("共映射 " + formFields.size() + " 个字段\n");
  329. // 按阶段分组展示
  330. Map<String, List<Map.Entry<String, String>>> groupedByStage = new LinkedHashMap<>();
  331. for (Map.Entry<String, String> entry : formFields.entrySet()) {
  332. String fieldId = entry.getKey();
  333. String stage = getStageByFieldId(fieldId);
  334. groupedByStage.computeIfAbsent(stage, k -> new ArrayList<>()).add(entry);
  335. }
  336. for (Map.Entry<String, List<Map.Entry<String, String>>> entry : groupedByStage.entrySet()) {
  337. System.out.println("【" + entry.getKey() + "】");
  338. for (Map.Entry<String, String> field : entry.getValue()) {
  339. System.out.println(" " + field.getKey() + " = " + field.getValue());
  340. }
  341. System.out.println();
  342. }
  343. }
  344. /**
  345. * 根据字段ID获取阶段名称(用于展示)
  346. */
  347. private static String getStageByFieldId(String fieldId) {
  348. for (Map.Entry<String, Map<String, String>> entry : FIELD_ID_MAP.entrySet()) {
  349. if (entry.getValue().containsValue(fieldId)) {
  350. return entry.getKey();
  351. }
  352. }
  353. return "未知";
  354. }
  355. }