.playwright-mcp/page-2026-08-04T07-44-03-300Z.yml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1 @@ - generic [active]: å·¥ä¸AIæºé å¹³å° .playwright-mcp/page-2026-08-04T07-44-19-942Z.yml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,237 @@ - generic [ref=e403]: - banner [ref=e404]: - generic [ref=e408]: - generic [ref=e409]: ç产工ä½å° - generic [ref=e410]: æä¸1å·å·¥ä½ç« - navigation [ref=e411]: - button "å·¥å详æ " [ref=e412] [cursor=pointer] - button "æ¥å·¥" [ref=e417] [cursor=pointer] - button "æ¥å·¥è®°å½" [active] [ref=e420] [cursor=pointer] - button "ç产记å½åæ°" [ref=e425] [cursor=pointer] - button "颿" [ref=e430] [cursor=pointer] - button "éæ" [ref=e435] [cursor=pointer] - button "è¿åç³»ç»" [ref=e440] [cursor=pointer] - generic [ref=e444]: - complementary [ref=e445]: - generic [ref=e446]: - generic [ref=e447]: - generic [ref=e448]: å·¥ä½ç« - button "忢" [ref=e454] [cursor=pointer] - generic [ref=e455]: - generic [ref=e456]: WS_002 - generic [ref=e457]: æä¸1å·å·¥ä½ç« - generic [ref=e458]: æä¸ - generic [ref=e459]: - generic [ref=e460]: - generic [ref=e461]: è½¦é´ - generic [ref=e462]: æµè¯æä¸è½¦é´ - generic [ref=e463]: - generic [ref=e464]: å°ç¹ - generic [ref=e465]: â - button "ä¸å·¥" [ref=e467] [cursor=pointer] - generic [ref=e470]: - generic [ref=e471]: - generic [ref=e472]: å·¥åå表 - generic [ref=e473]: "6" - textbox "订å/产å/å·¥åº" [ref=e475] - generic [ref=e476]: - generic [ref=e479] [cursor=pointer]: - generic [ref=e480]: - generic [ref=e481]: TK_20260729002 - generic [ref=e482]: è´¨æ£ - generic [ref=e483]: åå² - generic [ref=e484]: 0% - generic [ref=e485]: - generic [ref=e486]: æ¥å·¥è¿åº¦ - generic [ref=e487]: 0 / 234 - generic [ref=e489]: - generic [ref=e490]: - generic [ref=e491]: 订å - generic [ref=e492]: WO1784883668267 ç产工å-MPS20260724002 - generic [ref=e493]: - generic [ref=e494]: å·¥åº - generic [ref=e495]: æä¸ - generic [ref=e496]: - generic [ref=e497]: 产å - generic "éå线" [ref=e498]: ITEM_20260716005 éå线 - generic [ref=e499]: - generic [ref=e500]: 坿¥å·¥ - generic [ref=e501]: 224 åå - generic [ref=e504] [cursor=pointer]: - generic [ref=e505]: - generic [ref=e506]: TK_20260729001 - generic [ref=e507]: è´¨æ£ - generic [ref=e508]: åå² - generic [ref=e509]: 0% - generic [ref=e510]: - generic [ref=e511]: æ¥å·¥è¿åº¦ - generic [ref=e512]: 0 / 61 - generic [ref=e514]: - generic [ref=e515]: - generic [ref=e516]: 订å - generic [ref=e517]: WO_20260724003 é æ³ - generic [ref=e518]: - generic [ref=e519]: å·¥åº - generic [ref=e520]: æä¸ - generic [ref=e521]: - generic [ref=e522]: 产å - generic "éå线" [ref=e523]: ITEM_20260716005 éå线 - generic [ref=e524]: - generic [ref=e525]: 坿¥å·¥ - generic [ref=e526]: 61 åå - generic [ref=e529] [cursor=pointer]: - generic [ref=e530]: - generic [ref=e531]: TK_20260724001 - generic [ref=e532]: è´¨æ£ - generic [ref=e533]: åå² - generic [ref=e534]: 0% - generic [ref=e535]: - generic [ref=e536]: æ¥å·¥è¿åº¦ - generic [ref=e537]: 0 / 1 - generic [ref=e539]: - generic [ref=e540]: - generic [ref=e541]: 订å - generic [ref=e542]: WO_20260724003 é æ³ - generic [ref=e543]: - generic [ref=e544]: å·¥åº - generic [ref=e545]: æä¸ - generic [ref=e546]: - generic [ref=e547]: 产å - generic "éå线" [ref=e548]: ITEM_20260716005 éå线 - generic [ref=e549]: - generic [ref=e550]: 坿¥å·¥ - generic [ref=e551]: 0 åå - generic [ref=e554] [cursor=pointer]: - generic [ref=e555]: - generic [ref=e556]: TK_20260723001 - generic [ref=e557]: è´¨æ£ - generic [ref=e558]: åå² - generic [ref=e559]: 27% - generic [ref=e560]: - generic [ref=e561]: æ¥å·¥è¿åº¦ - generic [ref=e562]: 27 / 100 - generic [ref=e565]: - generic [ref=e566]: - generic [ref=e567]: 订å - generic [ref=e568]: WO_20260722009 é æ³ - generic [ref=e569]: - generic [ref=e570]: å·¥åº - generic [ref=e571]: æä¸ - generic [ref=e572]: - generic [ref=e573]: 产å - generic "éå线" [ref=e574]: ITEM_20260716005 éå线 - generic [ref=e575]: - generic [ref=e576]: 坿¥å·¥ - generic [ref=e577]: 73 åå - generic [ref=e580] [cursor=pointer]: - generic [ref=e581]: - generic [ref=e582]: TK_20260717001 - generic [ref=e583]: è´¨æ£ - generic [ref=e584]: åå² - generic [ref=e585]: 0.6% - generic [ref=e586]: - generic [ref=e587]: æ¥å·¥è¿åº¦ - generic [ref=e588]: 6 / 1000 - generic [ref=e591]: - generic [ref=e592]: - generic [ref=e593]: 订å - generic [ref=e594]: WO_20260716050 æµè¯è®¢å - generic [ref=e595]: - generic [ref=e596]: å·¥åº - generic [ref=e597]: æä¸ - generic [ref=e598]: - generic [ref=e599]: 产å - generic "éå线" [ref=e600]: ITEM_20260716005 éå线 - generic [ref=e601]: - generic [ref=e602]: 坿¥å·¥ - generic [ref=e603]: 994 åå - generic [ref=e606] [cursor=pointer]: - generic [ref=e607]: - generic [ref=e608]: TK_20260716001 - generic [ref=e609]: è´¨æ£ - generic [ref=e610]: åå² - generic [ref=e611]: 0% - generic [ref=e612]: - generic [ref=e613]: æ¥å·¥è¿åº¦ - generic [ref=e614]: 0 / 12000 - generic [ref=e616]: - generic [ref=e617]: - generic [ref=e618]: 订å - generic [ref=e619]: WO_20260716050 æµè¯è®¢å - generic [ref=e620]: - generic [ref=e621]: å·¥åº - generic [ref=e622]: æä¸ - generic [ref=e623]: - generic [ref=e624]: 产å - generic "é¢è¯éç»çº¿" [ref=e625]: ITEM_20260716006 é¢è¯éç»çº¿ - generic [ref=e626]: - generic [ref=e627]: 坿¥å·¥ - generic [ref=e628]: 10000 åå - main [ref=e631]: - generic [ref=e632]: - generic [ref=e633]: æ¥å·¥è®°å½ - generic [ref=e634]: å·¥å TK_20260729002 - generic [ref=e725]: - generic [ref=e727]: - generic [ref=e728]: æ¥å·¥è®°å½ - generic [ref=e731]: - button "î©" [ref=e732] [cursor=pointer] - button "î" [ref=e734] [cursor=pointer] - button "î" [ref=e736] [cursor=pointer] - generic [ref=e743]: - generic [ref=e744]: - table [ref=e748]: - rowgroup [ref=e762]: - row [ref=e763]: - columnheader "æ¥è®¢åå·" [ref=e764] - columnheader "ä»»å¡ç¼ç " [ref=e769] - columnheader "å·¥åº" [ref=e774] - columnheader "产å" [ref=e779] - columnheader "æ¥å·¥æ°é" [ref=e784] - columnheader "åæ ¼å" [ref=e789] - columnheader "ä¸è¯å" [ref=e794] - columnheader "æ¥å·¥äºº" [ref=e799] - columnheader "å®¡æ ¸äºº" [ref=e804] - columnheader "ç¶æ" [ref=e809] - columnheader "æ¥å·¥æ¶é´" [ref=e814] - table [ref=e822]: - rowgroup [ref=e836]: - row [ref=e837]: - cell [ref=e838]: - button "FB_20260804006" [ref=e841] [cursor=pointer] - cell "TK_20260729002" [ref=e843] - cell "æä¸" [ref=e847] - cell "éå线" [ref=e851] - cell "10" [ref=e855] - cell "0" [ref=e859] - cell "0" [ref=e863] - cell "èéæºç " [ref=e867] - cell "test01" [ref=e871] - cell "审æ¹ä¸" [ref=e875] - cell "2026-08-04 15:42:04" [ref=e879] - generic [ref=e883]: - table [ref=e886]: - rowgroup [ref=e900]: - row [ref=e901]: - columnheader "æä½" [ref=e902] - table [ref=e909]: - rowgroup [ref=e912]: - row [ref=e913]: - cell [ref=e914]: - generic [ref=e917]: - button "æ¥ç" [ref=e919] [cursor=pointer] - button "审æ¹éè¿" [ref=e922] [cursor=pointer] - button "驳å" [ref=e925] [cursor=pointer] - generic [ref=e933]: - generic [ref=e934]: å ± 1 æ¡è®°å½ - generic [ref=e936] [cursor=pointer]: - generic "20æ¡/页" [ref=e937]: - textbox "è¯·éæ©" [ref=e938]: 20æ¡/页 - generic [ref=e939]: î£ - button "ï" [ref=e942] - button "î¥" [ref=e944] - button "î" [ref=e946] - button "1" [ref=e949] [cursor=pointer] - button "î" [ref=e950] - button "î¦" [ref=e952] - button "î" [ref=e954] .playwright-mcp/page-2026-08-04T07-44-38-346Z.yml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,273 @@ - generic [ref=e403]: - banner [ref=e404]: - generic [ref=e408]: - generic [ref=e409]: ç产工ä½å° - generic [ref=e410]: æä¸1å·å·¥ä½ç« - navigation [ref=e411]: - button "å·¥å详æ " [ref=e412] [cursor=pointer] - button "æ¥å·¥" [active] [ref=e417] [cursor=pointer] - button "æ¥å·¥è®°å½" [ref=e420] [cursor=pointer] - button "ç产记å½åæ°" [ref=e425] [cursor=pointer] - button "颿" [ref=e430] [cursor=pointer] - button "éæ" [ref=e435] [cursor=pointer] - button "è¿åç³»ç»" [ref=e440] [cursor=pointer] - generic [ref=e444]: - complementary [ref=e445]: - generic [ref=e446]: - generic [ref=e447]: - generic [ref=e448]: å·¥ä½ç« - button "忢" [ref=e454] [cursor=pointer] - generic [ref=e455]: - generic [ref=e456]: WS_002 - generic [ref=e457]: æä¸1å·å·¥ä½ç« - generic [ref=e458]: æä¸ - generic [ref=e459]: - generic [ref=e460]: - generic [ref=e461]: è½¦é´ - generic [ref=e462]: æµè¯æä¸è½¦é´ - generic [ref=e463]: - generic [ref=e464]: å°ç¹ - generic [ref=e465]: â - button "ä¸å·¥" [ref=e467] [cursor=pointer] - generic [ref=e470]: - generic [ref=e471]: - generic [ref=e472]: å·¥åå表 - generic [ref=e473]: "6" - textbox "订å/产å/å·¥åº" [ref=e475] - generic [ref=e476]: - generic [ref=e479] [cursor=pointer]: - generic [ref=e480]: - generic [ref=e481]: TK_20260729002 - generic [ref=e482]: è´¨æ£ - generic [ref=e483]: åå² - generic [ref=e484]: 0% - generic [ref=e485]: - generic [ref=e486]: æ¥å·¥è¿åº¦ - generic [ref=e487]: 0 / 234 - generic [ref=e489]: - generic [ref=e490]: - generic [ref=e491]: 订å - generic [ref=e492]: WO1784883668267 ç产工å-MPS20260724002 - generic [ref=e493]: - generic [ref=e494]: å·¥åº - generic [ref=e495]: æä¸ - generic [ref=e496]: - generic [ref=e497]: 产å - generic "éå线" [ref=e498]: ITEM_20260716005 éå线 - generic [ref=e499]: - generic [ref=e500]: 坿¥å·¥ - generic [ref=e501]: 224 åå - generic [ref=e504] [cursor=pointer]: - generic [ref=e505]: - generic [ref=e506]: TK_20260729001 - generic [ref=e507]: è´¨æ£ - generic [ref=e508]: åå² - generic [ref=e509]: 0% - generic [ref=e510]: - generic [ref=e511]: æ¥å·¥è¿åº¦ - generic [ref=e512]: 0 / 61 - generic [ref=e514]: - generic [ref=e515]: - generic [ref=e516]: 订å - generic [ref=e517]: WO_20260724003 é æ³ - generic [ref=e518]: - generic [ref=e519]: å·¥åº - generic [ref=e520]: æä¸ - generic [ref=e521]: - generic [ref=e522]: 产å - generic "éå线" [ref=e523]: ITEM_20260716005 éå线 - generic [ref=e524]: - generic [ref=e525]: 坿¥å·¥ - generic [ref=e526]: 61 åå - generic [ref=e529] [cursor=pointer]: - generic [ref=e530]: - generic [ref=e531]: TK_20260724001 - generic [ref=e532]: è´¨æ£ - generic [ref=e533]: åå² - generic [ref=e534]: 0% - generic [ref=e535]: - generic [ref=e536]: æ¥å·¥è¿åº¦ - generic [ref=e537]: 0 / 1 - generic [ref=e539]: - generic [ref=e540]: - generic [ref=e541]: 订å - generic [ref=e542]: WO_20260724003 é æ³ - generic [ref=e543]: - generic [ref=e544]: å·¥åº - generic [ref=e545]: æä¸ - generic [ref=e546]: - generic [ref=e547]: 产å - generic "éå线" [ref=e548]: ITEM_20260716005 éå线 - generic [ref=e549]: - generic [ref=e550]: 坿¥å·¥ - generic [ref=e551]: 0 åå - generic [ref=e554] [cursor=pointer]: - generic [ref=e555]: - generic [ref=e556]: TK_20260723001 - generic [ref=e557]: è´¨æ£ - generic [ref=e558]: åå² - generic [ref=e559]: 27% - generic [ref=e560]: - generic [ref=e561]: æ¥å·¥è¿åº¦ - generic [ref=e562]: 27 / 100 - generic [ref=e565]: - generic [ref=e566]: - generic [ref=e567]: 订å - generic [ref=e568]: WO_20260722009 é æ³ - generic [ref=e569]: - generic [ref=e570]: å·¥åº - generic [ref=e571]: æä¸ - generic [ref=e572]: - generic [ref=e573]: 产å - generic "éå线" [ref=e574]: ITEM_20260716005 éå线 - generic [ref=e575]: - generic [ref=e576]: 坿¥å·¥ - generic [ref=e577]: 73 åå - generic [ref=e580] [cursor=pointer]: - generic [ref=e581]: - generic [ref=e582]: TK_20260717001 - generic [ref=e583]: è´¨æ£ - generic [ref=e584]: åå² - generic [ref=e585]: 0.6% - generic [ref=e586]: - generic [ref=e587]: æ¥å·¥è¿åº¦ - generic [ref=e588]: 6 / 1000 - generic [ref=e591]: - generic [ref=e592]: - generic [ref=e593]: 订å - generic [ref=e594]: WO_20260716050 æµè¯è®¢å - generic [ref=e595]: - generic [ref=e596]: å·¥åº - generic [ref=e597]: æä¸ - generic [ref=e598]: - generic [ref=e599]: 产å - generic "éå线" [ref=e600]: ITEM_20260716005 éå线 - generic [ref=e601]: - generic [ref=e602]: 坿¥å·¥ - generic [ref=e603]: 994 åå - generic [ref=e606] [cursor=pointer]: - generic [ref=e607]: - generic [ref=e608]: TK_20260716001 - generic [ref=e609]: è´¨æ£ - generic [ref=e610]: åå² - generic [ref=e611]: 0% - generic [ref=e612]: - generic [ref=e613]: æ¥å·¥è¿åº¦ - generic [ref=e614]: 0 / 12000 - generic [ref=e616]: - generic [ref=e617]: - generic [ref=e618]: 订å - generic [ref=e619]: WO_20260716050 æµè¯è®¢å - generic [ref=e620]: - generic [ref=e621]: å·¥åº - generic [ref=e622]: æä¸ - generic [ref=e623]: - generic [ref=e624]: 产å - generic "é¢è¯éç»çº¿" [ref=e625]: ITEM_20260716006 é¢è¯éç»çº¿ - generic [ref=e626]: - generic [ref=e627]: 坿¥å·¥ - generic [ref=e628]: 10000 åå - main [ref=e631]: - generic [ref=e632]: - generic [ref=e633]: æ¥å·¥ - generic [ref=e634]: å·¥å TK_20260729002 - generic [ref=e956]: - generic [ref=e957]: - heading "æ°å»ºæ¥å·¥" [level=3] [ref=e958] - generic [ref=e959]: "å·¥å: WO1784883668267 ç产工å-MPS20260724002" - generic [ref=e961]: - generic [ref=e962]: - generic [ref=e963]: - generic [ref=e964]: "*" - text: æ¥è®¢åå· - generic [ref=e968]: - textbox "* æ¥è®¢åå·" [ref=e969]: - /placeholder: 请è¾å ¥æ¥è®¢åå· - text: FB_20260804009 - button "ç æ" [ref=e971] [cursor=pointer] - generic [ref=e973]: - generic [ref=e974]: - generic [ref=e975]: "*" - text: æ¥å·¥ç±»å - generic [ref=e981] [cursor=pointer]: - combobox "* æ¥å·¥ç±»å" [ref=e983] - generic "èªè¡æ¥å·¥" [ref=e984] - generic [ref=e985]: - generic [ref=e986]: - generic [ref=e987]: "*" - text: ç产订å - textbox "è¯·éæ©è®¢å" [ref=e994]: WO1784883668267 - generic [ref=e1000]: - generic [ref=e1001]: - generic [ref=e1002]: "*" - text: çäº§ä»»å¡ - textbox "è¯·éæ©ä»»å¡" [ref=e1009]: TK_20260729002 - generic [ref=e1015]: - generic [ref=e1016]: - generic [ref=e1017]: "*" - text: å·¥ä½ç« - textbox "è¯·éæ©å·¥ä½ç«" [ref=e1024]: æä¸1å·å·¥ä½ç« - generic [ref=e1030]: - generic [ref=e1031]: 产åç¼ç - textbox "产åç¼ç " [disabled] [ref=e1036]: - /placeholder: 请è¾å ¥ - text: ITEM_20260716005 - generic [ref=e1037]: - generic [ref=e1038]: 产ååç§° - textbox "产ååç§°" [disabled] [ref=e1043]: - /placeholder: 请è¾å ¥ - text: éå线 - generic [ref=e1044]: - generic [ref=e1045]: åä½ - textbox "åä½" [disabled] [ref=e1050]: - /placeholder: 请è¾å ¥ - text: åå - generic [ref=e1051]: - generic [ref=e1052]: è§æ ¼ - textbox "è§æ ¼" [disabled] [ref=e1057]: - /placeholder: 请è¾å ¥ - text: L-1.72 - generic [ref=e1058]: - generic [ref=e1059]: - generic [ref=e1060]: "*" - text: æ¥å·¥æ°é - generic [ref=e1065]: - generic [ref=e1066]: - button "Increase Value" [ref=e1067] [cursor=pointer]: - img "up" [ref=e1068] - button "Decrease Value" [ref=e1071] [cursor=pointer]: - img "down" [ref=e1072] - spinbutton "* æ¥å·¥æ°é" [ref=e1076] - generic [ref=e1077]: - generic [ref=e1078]: - generic [ref=e1079]: "*" - text: æ¥å·¥äºº - generic [ref=e1085] [cursor=pointer]: - combobox "* æ¥å·¥äºº" [ref=e1087] - generic "èéæºç " [ref=e1088] - generic [ref=e1093]: - generic [ref=e1094]: - generic [ref=e1095]: "*" - text: æ¥å·¥æ¶é´ - generic [ref=e1101]: - textbox "* æ¥å·¥æ¶é´" [ref=e1102]: - /placeholder: è¯·éæ©æ¥å·¥æ¶é´ - text: Invalid Date - generic: - img "calendar" - button [ref=e1103] [cursor=pointer]: - img "close-circle" [ref=e1104] - generic [ref=e1107]: - generic [ref=e1108]: - generic [ref=e1109]: "*" - text: å®¡æ ¸äºº - generic [ref=e1115] [cursor=pointer]: - combobox "* å®¡æ ¸äºº" [ref=e1117] - generic: è¯·éæ©å®¡æ ¸äºº - generic [ref=e1118]: - generic [ref=e1119]: 夿³¨ - textbox "夿³¨" [ref=e1124]: - /placeholder: 请è¾å ¥å¤æ³¨ - generic [ref=e1125]: - button "ä¿ å" [ref=e1126] [cursor=pointer] - button "ä¿åå¹¶æäº¤" [ref=e1128] [cursor=pointer] yudao-module-ai/pom.xml
@@ -167,6 +167,13 @@ </exclusions> </dependency> <!-- Apache POIï¼è´è´£ .doc/.docx æä»¶å 容æåï¼æ¯ Tika å¯¹ä¸ææ¯ææ´å¥½ --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.4.0</version> </dependency> <!-- MCP ç¸å ³ --> <!-- ç¹æ®è¯´æï¼ä¸è½ä½¿ç¨ spring-ai-starter-mcp-server-webflux æ spring-ai-starter-mcp-client-webflux ï¼ï¼ï¼ yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeDocumentServiceImpl.java
@@ -28,6 +28,10 @@ import org.apache.tika.parser.Parser; import org.apache.tika.extractor.EmbeddedDocumentExtractor; import org.apache.tika.sax.BodyContentHandler; import org.apache.poi.xwpf.extractor.XWPFWordExtractor; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.extractor.WordExtractor; import org.xml.sax.ContentHandler; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -57,6 +61,8 @@ private AiKnowledgeSegmentService segmentService; @Resource private AiModelService modelService; @Resource private cn.iocoder.yudao.module.system.service.storage.SystemStorageBlobService storageBlobService; @Override @Transactional(rollbackFor = Exception.class) @@ -113,11 +119,28 @@ } } /** * ä» storage-blob URL è§£æåº fileName å token */ private static java.util.regex.Pattern STORAGE_URL_PATTERN = java.util.regex.Pattern.compile("/storage-blob/(?:preview|download)/([^?]+)\\?.*token=([^&]+)"); private byte[] downloadFile(String fileUrl) { // ä¼å éè¿ storage-blob æ¬å°è¯»åï¼é¿å HTTP 认è¯é®é¢ var matcher = STORAGE_URL_PATTERN.matcher(fileUrl); if (matcher.find()) { String fileName = matcher.group(1); String token = matcher.group(2); try { java.io.File file = storageBlobService.getFileByToken(fileName, token); return java.nio.file.Files.readAllBytes(file.toPath()); } catch (Exception e) { log.warn("æ¬å°è¯»ååå¨æä»¶å¤±è´¥ï¼åé HTTP ä¸è½½: {}", e.getMessage()); } } // åé HTTP ä¸è½½ try { // æå¨ç¼ç URL è·¯å¾ä¸çé ASCII å符ï¼é¿å URI æé 彿°æ¥é String encodedUrl = encodeUrlPath(fileUrl); URL url = URL.of(new URI(encodedUrl), null); URL url = URL.of(new URI(encodeUrlPath(fileUrl)), null); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(60000); @@ -184,7 +207,36 @@ if (ArrayUtil.contains(new String[]{"txt", "md", "json", "xml", "csv", "yaml", "yml"}, ext)) { return new String(fileBytes, StandardCharsets.UTF_8); } // ä½¿ç¨ AutoDetectParser + EmbeddedDocumentExtractor è·³è¿åµå ¥å¾çï¼é¿å æåå°äºè¿å¶ä¹±ç // .docx ä¼å ä½¿ç¨ POI æåï¼ä¸ææ¯ææ´å¥½ if ("docx".equals(ext)) { try (XWPFDocument doc = new XWPFDocument(new java.io.ByteArrayInputStream(fileBytes)); XWPFWordExtractor extractor = new XWPFWordExtractor(doc)) { String text = extractor.getText(); if (StrUtil.isNotEmpty(text)) return text.trim(); } catch (Exception e) { log.warn("POI è§£æ docx 失败ï¼åé Tika: {}", e.getMessage()); } } // .doc ä¼å ä½¿ç¨ POI æå if ("doc".equals(ext)) { try (HWPFDocument doc = new HWPFDocument(new java.io.ByteArrayInputStream(fileBytes)); WordExtractor extractor = new WordExtractor(doc)) { String text = extractor.getText(); if (StrUtil.isNotEmpty(text)) return text.trim(); } catch (Exception e) { log.warn("POI è§£æ doc 失败ï¼åé Tika: {}", e.getMessage()); } } // å ¶ä»æ ¼å¼æ POI 失败æ¶åé Tika return extractTextWithTika(fileBytes); } catch (Exception e) { log.warn("ææ¡£å 容æå失败ï¼å°è¯ UTF-8 ææ¬è¯»å: {}", e.getMessage()); return ""; } } private String extractTextWithTika(byte[] fileBytes) { try { Parser parser = new AutoDetectParser(); ParseContext context = new ParseContext(); context.set(EmbeddedDocumentExtractor.class, new EmbeddedDocumentExtractor() { @@ -203,7 +255,7 @@ } return handler.toString().trim(); } catch (Exception e) { log.warn("Tika è§£æææ¡£å¤±è´¥ï¼å°è¯ UTF-8 ææ¬è¯»å: {}", e.getMessage()); log.warn("Tika è§£æå¤±è´¥: {}", e.getMessage()); return ""; } } yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/service/knowledge/AiKnowledgeSegmentServiceImpl.java
@@ -217,7 +217,7 @@ try { for (int i = 0; i < documents.size(); i += batchSize) { int end = Math.min(i + batchSize, documents.size()); vectorStore.add(documents.subList(i, end)); vectorStore.add(new ArrayList<>(documents.subList(i, end))); } for (AiKnowledgeSegmentDO segment : segments) { segment.setVectorId(segment.getId().toString()); yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
@@ -19,6 +19,8 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -63,6 +65,8 @@ private CrmBusinessStatusService businessStatusService; @Resource private MdmItemApi mdmItemApi; @Resource private MdmUnitMeasureApi mdmUnitMeasureApi; @Resource private AdminUserApi adminUserApi; @@ -119,10 +123,19 @@ List<CrmBusinessProductDO> businessProducts = businessService.getBusinessProductListByBusinessId(businessVO.getId()); Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( convertSet(businessProducts, CrmBusinessProductDO::getItemId)); Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureMap( convertSet(businessProducts, CrmBusinessProductDO::getItemUnitId)); businessVO.setProducts(BeanUtils.toBean(businessProducts, CrmBusinessRespVO.Product.class, businessProductVO -> MapUtils.findAndThen(itemMap, businessProductVO.getItemId(), item -> businessProductVO.setItemName(item.getName()) .setItemCode(item.getCode()).setItemUnitId(item.getUnitMeasureId())))); .setItemCode(item.getCode()) .setBarCode(item.getBarCode()) .setItemSpecification(item.getSpecification())))); // å¡«å åä½åç§° businessVO.getProducts().forEach(product -> { MapUtils.findAndThen(unitMap, product.getItemUnitId(), unit -> product.setItemUnitName(unit.getName())); }); return businessVO; } yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java
@@ -132,6 +132,14 @@ private String itemCode; @Schema(description = "计éåä½ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Long itemUnitId; @Schema(description = "计éåä½åç§°", example = "个") private String itemUnitName; @Schema(description = "ç©ææ¡ç ", example = "12345678") private String barCode; @Schema(description = "è§æ ¼åå·", example = "M8*20") private String itemSpecification; @Schema(description = "ç©æåä»·", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") private BigDecimal itemPrice; yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/quotation/CrmSaleQuotationController.java
@@ -13,7 +13,9 @@ import cn.iocoder.yudao.module.crm.controller.admin.quotation.vo.CrmSaleQuotationSaveReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.quotation.CrmSaleQuotationDO; import cn.iocoder.yudao.module.crm.dal.dataobject.quotation.CrmSaleQuotationProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.quotation.CrmSaleQuotationService; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; @@ -66,6 +68,8 @@ private MdmUnitMeasureApi mdmUnitMeasureApi; @Resource private CrmCustomerService customerService; @Resource private CrmBusinessService businessService; @Resource private StorageAttachmentApi storageAttachmentApi; @@ -178,6 +182,13 @@ respVO.setCustomerName(customer.getName()); } } // 2.1 å¡«å åæºåç§° if (saleQuotation.getBusinessId() != null) { CrmBusinessDO business = businessService.getBusiness(saleQuotation.getBusinessId()); if (business != null) { respVO.setBusinessName(business.getName()); } } // 3. å¡«å å ³èä¿¡æ¯ fillSaleQuotationRelatedFields(respVO); // 4. å¡«å éä»¶å表 @@ -204,6 +215,9 @@ // 1.5 é¨é¨ä¿¡æ¯ Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap( convertSet(pageResult.getList(), CrmSaleQuotationDO::getOwnerUserId)); // 1.6 åæºä¿¡æ¯ï¼è¿æ»¤ nullï¼businessId 为å¯éåæ®µï¼ Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap( convertSet(pageResult.getList(), CrmSaleQuotationDO::getBusinessId, vo -> vo.getBusinessId() != null)); // 2. å¼å§æ¼æ¥ return BeanUtils.toBean(pageResult, CrmSaleQuotationRespVO.class, vo -> { @@ -213,6 +227,7 @@ MapUtils.findAndThen(customerMap, vo.getCustomerId(), customer -> vo.setCustomerName(customer.getName())); MapUtils.findAndThen(userMap, vo.getOwnerUserId(), user -> vo.setOwnerUserName(user.getNickname())); MapUtils.findAndThen(deptMap, vo.getOwnerUserId(), dept -> vo.setOwnerUserDeptName(dept.getName())); MapUtils.findAndThen(businessMap, vo.getBusinessId(), business -> vo.setBusinessName(business.getName())); }); } yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -257,6 +257,9 @@ if (product.getItemUnitId() == null) { product.setItemUnitId(old.getItemUnitId()); } } else { // æ°äº§åï¼æ¸ é¤å端çæçä¸´æ¶ IDï¼è®©æ°æ®åº AUTO_INCREMENT æ¥ç®¡ product.setId(null); } // ä¼å 使ç¨åç«¯ä¼ å ¥ç totalPriceï¼å¦åéè¿ businessPrice * count è®¡ç® if (o.getTotalPrice() != null) { yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseOrderController.java
@@ -19,6 +19,8 @@ import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseOrderService; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -56,6 +58,8 @@ @Resource private MdmItemApi mdmItemApi; @Resource private MdmUnitMeasureApi mdmUnitMeasureApi; @Resource private AdminUserApi adminUserApi; @Resource @@ -123,12 +127,16 @@ List<ErpPurchaseOrderItemDO> purchaseOrderItemList = purchaseOrderService.getPurchaseOrderItemListByOrderId(id); Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductId)); Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap( convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductUnitId)); return success(BeanUtils.toBean(purchaseOrder, ErpPurchaseOrderRespVO.class, purchaseOrderVO -> purchaseOrderVO.setItems(BeanUtils.toBean(purchaseOrderItemList, ErpPurchaseOrderRespVO.Item.class, item -> { // åºåä¿¡æ¯æä¸æ¥è¯¢ï¼ä»å¨ç©æµæ¨¡åï¼ item.setStockCount(BigDecimal.ZERO); MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) .setProductBarCode(mdmItem.getBarCode())); MapUtils.findAndThen(unitMeasureMap, item.getProductUnitId(), unit -> item.setProductUnitName(unit.getName())); })).setAttachmentList(storageAttachmentApi.listAttachments("erp_purchase_order", id)) .setSourceTypeName(ErpPurchaseOrderSourceTypeEnum.WORK_ORDER.getType() .equals(purchaseOrder.getSourceType()) ? "ç产工å" : null))); @@ -180,11 +188,18 @@ // 1.4 管çåä¿¡æ¯ Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( convertSet(pageResult.getList(), purchaseOrder -> Long.parseLong(purchaseOrder.getCreator()))); // 1.5 åä½ä¿¡æ¯ Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap( convertSet(purchaseOrderItemList, ErpPurchaseOrderItemDO::getProductUnitId)); // 2. å¼å§æ¼æ¥ return BeanUtils.toBean(pageResult, ErpPurchaseOrderRespVO.class, purchaseOrder -> { purchaseOrder.setItems(BeanUtils.toBean(purchaseOrderItemMap.get(purchaseOrder.getId()), ErpPurchaseOrderRespVO.Item.class, item -> MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) .setProductBarCode(mdmItem.getBarCode())))); item -> { MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) .setProductBarCode(mdmItem.getBarCode())); MapUtils.findAndThen(unitMeasureMap, item.getProductUnitId(), unit -> item.setProductUnitName(unit.getName())); })); purchaseOrder.setProductNames(CollUtil.join(purchaseOrder.getItems(), "ï¼", ErpPurchaseOrderRespVO.Item::getProductName)); MapUtils.findAndThen(supplierMap, purchaseOrder.getSupplierId(), supplier -> purchaseOrder.setSupplierName(supplier.getName())); MapUtils.findAndThen(userMap, Long.parseLong(purchaseOrder.getCreator()), user -> purchaseOrder.setCreatorName(user.getNickname())); yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java
@@ -18,6 +18,8 @@ import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseRequestService; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; @@ -56,6 +58,8 @@ @Resource private MdmItemApi mdmItemApi; @Resource private MdmUnitMeasureApi mdmUnitMeasureApi; @Resource private AdminUserApi adminUserApi; @Resource @@ -99,10 +103,14 @@ List<ErpPurchaseRequestItemDO> purchaseRequestItemList = purchaseRequestService.getPurchaseRequestItemListByRequestId(id); Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( convertSet(purchaseRequestItemList, ErpPurchaseRequestItemDO::getProductId)); Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap( convertSet(purchaseRequestItemList, ErpPurchaseRequestItemDO::getProductUnitId)); return success(BeanUtils.toBean(purchaseRequest, ErpPurchaseRequestRespVO.class, purchaseRequestVO -> purchaseRequestVO.setItems(BeanUtils.toBean(purchaseRequestItemList, ErpPurchaseRequestRespVO.Item.class, item -> { MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) .setProductBarCode(mdmItem.getBarCode())); MapUtils.findAndThen(unitMeasureMap, item.getProductUnitId(), unit -> item.setProductUnitName(unit.getName())); })).setAttachmentList(storageAttachmentApi.listAttachments("erp_purchase_request", id)))); } yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/order/ErpPurchaseOrderRespVO.java
@@ -2,6 +2,9 @@ import cn.idev.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelProperty; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import cn.iocoder.yudao.module.erp.enums.DictTypeConstants; import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @@ -25,7 +28,8 @@ private String no; @Schema(description = "éè´ç¶æ", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @ExcelProperty("éè´ç¶æ") @ExcelProperty(value = "éè´ç¶æ", converter = DictConvert.class) @DictFormat(DictTypeConstants.AUDIT_STATUS) private Integer status; @Schema(description = "ä¾åºåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1724") yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java
@@ -29,6 +29,9 @@ @ExcelProperty(value = "ç¶æ", converter = cn.iocoder.yudao.module.erp.convert.ErpPurchaseRequestStatusConvert.class) private Integer status; @Schema(description = "æµç¨å®ä¾ç¼å·", example = "1024") private String processInstanceId; @Schema(description = "ç³è¯·äººç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @ExcelProperty("ç³è¯·äººç¼å·") private Long requestUserId; yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpSaleOrderController.java
@@ -24,6 +24,7 @@ import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi; import cn.iocoder.yudao.module.mes.api.productsales.MesWmProductSalesLineApi; import cn.iocoder.yudao.module.mes.api.salesnotice.MesWmSalesNoticeApi; import cn.iocoder.yudao.module.mes.api.wms.MesWmStockApi; import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -72,6 +73,8 @@ private StorageAttachmentApi storageAttachmentApi; @Resource private MdmUnitMeasureApi mdmUnitMeasureApi; @Resource private MesWmStockApi mesWmStockApi; @PostMapping("/create") @Operation(summary = "å建éå®è®¢å") @@ -158,7 +161,7 @@ convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductUnitId)); // 3. 转æ¢è®¢å项 List<ErpSaleOrderRespVO.Item> itemVOList = BeanUtils.toBean(saleOrderItemList, ErpSaleOrderRespVO.Item.class, item -> { item.setStockCount(BigDecimal.ZERO); // åºåä¿¡æ¯æä¸æ¥è¯¢ï¼ä»å¨ç©æµæ¨¡åï¼ item.setStockCount(mesWmStockApi.getStockQuantity(item.getProductId())); item.setBatchCode(batchCodeMap.get(item.getId())); MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()).setProductBarCode(mdmItem.getBarCode()) yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
@@ -129,7 +129,7 @@ @Transactional(rollbackFor = Exception.class) public void updatePurchaseRequest(ErpPurchaseRequestSaveReqVO updateReqVO) { // 1. æ ¡éªåå¨ + èç¨¿ç¶æ ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestExistsAndDraft(updateReqVO.getId()); ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestCanModify(updateReqVO.getId()); // 2. æ ¡éªä¾åºåï¼å¦ææå®ï¼ if (updateReqVO.getSupplierId() != null) { supplierService.validateSupplier(updateReqVO.getSupplierId()); @@ -198,8 +198,9 @@ return; } purchaseRequests.forEach(purchaseRequest -> { // åªæèç¨¿ç¶ææè½å é¤ if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(purchaseRequest.getStatus())) { Integer status = purchaseRequest.getStatus(); if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(status) && !ErpPurchaseRequestStatusEnum.REJECT.getStatus().equals(status)) { throw exception(PURCHASE_REQUEST_DELETE_FAIL_NOT_DRAFT, purchaseRequest.getNo()); } }); @@ -246,7 +247,7 @@ @Transactional(rollbackFor = Exception.class) public void submitPurchaseRequest(Long id, String processDefinitionKey, Long userId) { // 1. æ ¡éªåå¨ + èç¨¿ç¶æ ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestExistsAndDraft(id); ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestCanModify(id); // 2. æ ¡éªæ¯å¦ææç» List<ErpPurchaseRequestItemDO> items = purchaseRequestItemMapper.selectListByRequestId(id); @@ -455,9 +456,11 @@ return purchaseRequest; } private ErpPurchaseRequestDO validatePurchaseRequestExistsAndDraft(Long id) { private ErpPurchaseRequestDO validatePurchaseRequestCanModify(Long id) { ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestExists(id); if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(purchaseRequest.getStatus())) { Integer status = purchaseRequest.getStatus(); if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(status) && !ErpPurchaseRequestStatusEnum.REJECT.getStatus().equals(status)) { throw exception(PURCHASE_REQUEST_UPDATE_FAIL_NOT_DRAFT, purchaseRequest.getNo()); } return purchaseRequest; yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java
@@ -11,14 +11,14 @@ import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO; import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO; import cn.iocoder.yudao.module.mdm.dal.dataobject.unit.MdmUnitMeasureDO; import cn.iocoder.yudao.module.mdm.dal.dataobject.warehouse.MdmWarehouseDO; import cn.iocoder.yudao.module.mdm.service.brand.MdmBrandService; import cn.iocoder.yudao.module.mdm.service.category.MdmItemCategoryService; import cn.iocoder.yudao.module.mdm.service.item.MdmItemBatchConfigService; import cn.iocoder.yudao.module.mdm.service.item.MdmItemService; import cn.iocoder.yudao.module.mdm.service.unit.MdmUnitMeasureService; import cn.iocoder.yudao.module.mdm.service.warehouse.MdmWarehouseService; import cn.iocoder.yudao.module.mes.api.item.MesMdItemApi; import cn.iocoder.yudao.module.mes.api.wm.warehouse.MesWmWarehouseApi; import cn.iocoder.yudao.module.mes.api.wm.warehouse.dto.MesWmWarehouseRespDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -51,7 +51,7 @@ @Resource private MdmUnitMeasureService unitMeasureService; @Resource private MdmWarehouseService warehouseService; private MesWmWarehouseApi mesWmWarehouseApi; @Resource private MdmBrandService brandService; @Resource @@ -139,14 +139,14 @@ }); Map<Long, MdmUnitMeasureDO> auxUnitMap = unitIds.isEmpty() ? Collections.emptyMap() : unitMeasureService.getUnitMeasureMap(unitIds); // æ¹éå ³èæ¥è¯¢ä»åºåç§° // æ¹éå ³èæ¥è¯¢ä»åºåç§°ï¼ä½¿ç¨ MES ä»åºï¼ Set<Long> warehouseIds = new HashSet<>(); respList.forEach(resp -> { if (resp.getWarehouseId() != null) warehouseIds.add(resp.getWarehouseId()); }); Map<Long, MdmWarehouseDO> warehouseMap = warehouseIds.isEmpty() ? Collections.emptyMap() : warehouseService.getWarehouseList(warehouseIds).stream() .collect(Collectors.toMap(MdmWarehouseDO::getId, w -> w)); Map<Long, MesWmWarehouseRespDTO> warehouseMap = warehouseIds.isEmpty() ? Collections.emptyMap() : mesWmWarehouseApi.getWarehouseList(warehouseIds).stream() .collect(Collectors.toMap(MesWmWarehouseRespDTO::getId, w -> w)); // èµå¼ respList.forEach(resp -> { // åç±»åç§° @@ -166,7 +166,7 @@ if (auxUnit2 != null) { resp.setUnitMeasureName3(auxUnit2.getName()); } MdmWarehouseDO warehouse = warehouseMap.get(resp.getWarehouseId()); MesWmWarehouseRespDTO warehouse = warehouseMap.get(resp.getWarehouseId()); if (warehouse != null) { resp.setWarehouseName(warehouse.getName()); } @@ -234,11 +234,11 @@ resp.setUnitMeasureName3(unit3.getName()); } } // é»è®¤ä»åºåç§° // é»è®¤ä»åºåç§°ï¼ä½¿ç¨ MES ä»åºï¼ if (resp.getWarehouseId() != null) { MdmWarehouseDO warehouse = warehouseService.getWarehouse(resp.getWarehouseId()); if (warehouse != null) { resp.setWarehouseName(warehouse.getName()); List<MesWmWarehouseRespDTO> warehouses = mesWmWarehouseApi.getWarehouseList(List.of(resp.getWarehouseId())); if (!warehouses.isEmpty()) { resp.setWarehouseName(warehouses.get(0).getName()); } } } yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/warehouse/MdmWarehouseController.java
@@ -89,9 +89,9 @@ @GetMapping("/list-all-simple") @Operation(summary = "è·å¾å ¨é¨å¯ç¨çä»åºå表") public CommonResult<List<MdmWarehouseRespVO>> getSimpleWarehouseList() { MdmWarehouseDO query = new MdmWarehouseDO(); query.setStatus(0); List<MdmWarehouseDO> list = warehouseService.getWarehousePage(new MdmWarehousePageReqVO()).getList(); MdmWarehousePageReqVO reqVO = new MdmWarehousePageReqVO(); reqVO.setStatus(0); List<MdmWarehouseDO> list = warehouseService.getWarehousePage(reqVO).getList(); return success(BeanUtils.toBean(list, MdmWarehouseRespVO.class)); } yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/wm/warehouse/MesWmWarehouseApi.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ package cn.iocoder.yudao.module.mes.api.wm.warehouse; import cn.iocoder.yudao.module.mes.api.wm.warehouse.dto.MesWmWarehouseRespDTO; import java.util.Collection; import java.util.List; /** * MES ä»åº API æ¥å£ */ public interface MesWmWarehouseApi { /** * è·åä»åºå表 * * @param ids ä»åºIDå表 * @return ä»åºå表 */ List<MesWmWarehouseRespDTO> getWarehouseList(Collection<Long> ids); } yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/wm/warehouse/dto/MesWmWarehouseRespDTO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,15 @@ package cn.iocoder.yudao.module.mes.api.wm.warehouse.dto; import lombok.Data; /** * MES ä»åº Response DTO */ @Data public class MesWmWarehouseRespDTO { private Long id; private String code; private String name; } yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/wms/MesWmStockApi.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ package cn.iocoder.yudao.module.mes.api.wms; import java.math.BigDecimal; /** * WMS åºåæ¥è¯¢ API æ¥å£ * * ä¾å ¶ä»æ¨¡åï¼å¦ ERPï¼æ¥è¯¢ç©æåºåæ°é */ public interface MesWmStockApi { /** * è·åç©æåºåæ»éï¼ææä»åºæ±æ»ï¼ * * @param itemId ç©æID * @return åºåæ°é */ BigDecimal getStockQuantity(Long itemId); } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/wm/warehouse/MesWmWarehouseApiImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,35 @@ package cn.iocoder.yudao.module.mes.api.wm.warehouse; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.api.wm.warehouse.dto.MesWmWarehouseRespDTO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.util.Collection; import java.util.Collections; import java.util.List; /** * MES ä»åº API å®ç°ç±» */ @Service @Validated public class MesWmWarehouseApiImpl implements MesWmWarehouseApi { @Resource private MesWmWarehouseMapper warehouseMapper; @Override public List<MesWmWarehouseRespDTO> getWarehouseList(Collection<Long> ids) { if (CollUtil.isEmpty(ids)) { return Collections.emptyList(); } List<MesWmWarehouseDO> list = warehouseMapper.selectListByIds(ids); return BeanUtils.toBean(list, MesWmWarehouseRespDTO.class); } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/wms/MesWmStockApiImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,37 @@ package cn.iocoder.yudao.module.mes.api.wms; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper; import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.math.BigDecimal; import java.util.List; /** * WMS åºå API å®ç°ç±» */ @Service @Validated public class MesWmStockApiImpl implements MesWmStockApi { @Resource private MesWmMaterialStockMapper materialStockMapper; @Override public BigDecimal getStockQuantity(Long itemId) { MesWmMaterialStockListReqVO reqVO = new MesWmMaterialStockListReqVO(); reqVO.setItemId(itemId); List<MesWmMaterialStockDO> stockList = materialStockMapper.selectList(reqVO); if (CollUtil.isEmpty(stockList)) { return BigDecimal.ZERO; } return stockList.stream() .map(MesWmMaterialStockDO::getQuantity) .reduce(BigDecimal.ZERO, BigDecimal::add); } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/MesProFeedbackController.java
@@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackApproveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackBatchCheckRespVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackBatchCreateReqVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackBatchCreateRespVO; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackPageReqVO; @@ -192,10 +194,17 @@ @PutMapping("/approve") @Operation(summary = "å®¡æ¹æ¥å·¥") @Parameter(name = "id", description = "ç¼å·", required = true) @PreAuthorize("@ss.hasPermission('mes:pro-feedback:approve')") public CommonResult<Boolean> approveFeedback(@RequestParam("id") Long id) { return success(feedbackService.approveFeedback(id)); public CommonResult<Boolean> approveFeedback(@Valid @RequestBody MesProFeedbackApproveReqVO reqVO) { return success(feedbackService.approveFeedback(reqVO)); } @GetMapping("/batch-requirements") @Operation(summary = "æ£æ¥æ¥å·¥å®¡æ¹åæ¯å¦éè¦å¡«åæ¹æ¬¡å±æ§") @Parameter(name = "id", description = "æ¥å·¥åç¼å·", required = true) @PreAuthorize("@ss.hasPermission('mes:pro-feedback:approve')") public CommonResult<MesProFeedbackBatchCheckRespVO> getBatchRequirements(@RequestParam("id") Long id) { return success(feedbackService.checkBatchRequirements(id)); } @PostMapping("/quick-create") yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackApproveReqVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,50 @@ package cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.Data; import java.time.LocalDateTime; @Schema(description = "管çåå° - MES ç产æ¥å·¥å®¡æ¹éè¿ Request VO") @Data public class MesProFeedbackApproveReqVO { @Schema(description = "æ¥å·¥åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "æ¥å·¥åIDä¸è½ä¸ºç©º") private Long id; @Schema(description = "çäº§æ¥æ") private LocalDateTime produceDate; @Schema(description = "è¿ææ¥æ") private LocalDateTime expireDate; @Schema(description = "å ¥åºæ¥æ") private LocalDateTime receiptDate; @Schema(description = "ä¾åºåID") private Long vendorId; @Schema(description = "客æ·ID") private Long clientId; @Schema(description = "éè´è®¢åç¼å·") private String purchaseOrderCode; @Schema(description = "éå®è®¢åç¼å·") private String salesOrderCode; @Schema(description = "å·¥å ·ID") private Long toolId; @Schema(description = "æ¨¡å ·ID") private Long moldId; @Schema(description = "ç产æ¹å·") private String lotNumber; @Schema(description = "è´¨éç¶æ") private Integer qualityStatus; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackBatchCheckRespVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,63 @@ package cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; @Schema(description = "管çåå° - MES ç产æ¥å·¥æ¹æ¬¡éæ±æ£æ¥ Response VO") @Data public class MesProFeedbackBatchCheckRespVO { @Schema(description = "æ¯å¦éè¦æ¹æ¬¡ä¿¡æ¯å¼¹çª") private Boolean needBatchInput; @Schema(description = "æ¯å¦å¯ç¨æ¹æ¬¡ç®¡ç") private Boolean isBatchManaged; @Schema(description = "çäº§æ¥æå¿ å¡«") private Boolean produceDateFlag; @Schema(description = "æææå¿ å¡«") private Boolean expireDateFlag; @Schema(description = "å ¥åºæ¥æå¿ å¡«") private Boolean receiptDateFlag; @Schema(description = "ä¾åºåå¿ å¡«") private Boolean vendorFlag; @Schema(description = "客æ·å¿ å¡«") private Boolean clientFlag; @Schema(description = "éå®è®¢åç¼å·å¿ å¡«") private Boolean salesOrderCodeFlag; @Schema(description = "éè´è®¢åç¼å·å¿ å¡«") private Boolean purchaseOrderCodeFlag; @Schema(description = "ç产工åå¿ å¡«") private Boolean workOrderFlag; @Schema(description = "ç产任å¡å¿ å¡«") private Boolean taskFlag; @Schema(description = "å·¥ä½ç«å¿ å¡«") private Boolean workstationFlag; @Schema(description = "å·¥å ·å¿ å¡«") private Boolean toolFlag; @Schema(description = "æ¨¡å ·å¿ å¡«") private Boolean moldFlag; @Schema(description = "ç产æ¹å·å¿ å¡«") private Boolean lotNumberFlag; @Schema(description = "è´¨éç¶æå¿ å¡«") private Boolean qualityStatusFlag; @Schema(description = "å·²èªå¨å¡«å çåæ®µåå表") private List<String> autoFilledFields; } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -18,7 +18,6 @@ ErrorCode MD_ITEM_TYPE_CODE_DUPLICATE = new ErrorCode(1_040_100_005, "åä¸ç¶åç±»ä¸å·²åå¨è¯¥ç¼ç çåç±»"); ErrorCode MD_ITEM_TYPE_PARENT_IS_CHILD = new ErrorCode(1_040_100_006, "ä¸è½è®¾ç½®èªå·±çåå类为ç¶åç±»"); ErrorCode MD_ITEM_TYPE_EXITS_ITEM = new ErrorCode(1_040_100_007, "该åç±»ä¸åå¨ç©æï¼æ æ³å é¤"); ErrorCode MD_ITEM_TYPE_NOT_LEAF = new ErrorCode(1_040_100_008, "åªè½å°ç©ææè½½å°å¶ååç±»ï¼è¯¥åç±»ä¸åå¨ååç±»ï¼"); // ========== MES åºç¡æ°æ®-计éåä½ï¼1-040-101-000ï¼ ========== ErrorCode MD_UNIT_MEASURE_NOT_EXISTS = new ErrorCode(1_040_101_000, "计éåä½ä¸åå¨"); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
@@ -213,11 +213,6 @@ if (itemTypeService.getItemType(itemTypeId) == null) { throw exception(MD_ITEM_TYPE_NOT_EXISTS); } // æ ¡éªå¿ é¡»æ¯å¶ååç±»ï¼æ²¡æååç±»ï¼ List<MesMdItemTypeDO> children = itemTypeService.getItemTypeChildrenList(itemTypeId); if (CollUtil.isNotEmpty(children)) { throw exception(MD_ITEM_TYPE_NOT_LEAF); } } private void validateUnitMeasureExists(Long unitMeasureId) { yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java
@@ -108,10 +108,18 @@ * </li> * </ol> * * @param id æ¥å·¥åç¼å· * @param reqVO 审æ¹è¯·æ±ï¼å«æ¥å·¥åç¼å·åå¯éæ¹æ¬¡å±æ§ï¼ * @return true=已宿, false=å¾ æ£éªï¼éçè´¨æ£åè°ï¼ */ boolean approveFeedback(Long id); boolean approveFeedback(@Valid MesProFeedbackApproveReqVO reqVO); /** * æ£æ¥æ¥å·¥å®¡æ¹åæ¯å¦éè¦å¡«åæ¹æ¬¡å±æ§ * * @param feedbackId æ¥å·¥åç¼å· * @return æ¹æ¬¡éæ±æ£æ¥ç»æ */ MesProFeedbackBatchCheckRespVO checkBatchRequirements(Long feedbackId); /** * IPQC 宿ååè°ï¼å®ææ¥å·¥åå¹¶æ´æ°ä»»å¡/å·¥åè¿åº¦ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
@@ -28,6 +28,10 @@ import cn.iocoder.yudao.module.mes.service.wm.itemconsume.MesWmItemConsumeService; import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService; import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceService; import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; import cn.iocoder.yudao.module.mdm.api.item.MdmItemBatchConfigApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemBatchConfigRespDTO; import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi; import cn.iocoder.yudao.module.mes.api.mps.dto.MesProMpsRespDTO; import cn.iocoder.yudao.module.mes.api.event.ProductionFinishedEvent; @@ -40,6 +44,7 @@ import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -80,6 +85,10 @@ private MesMdAutoCodeRecordService autoCodeRecordService; @Resource private ApplicationEventPublisher eventPublisher; @Resource private MesMdmItemService mdmItemService; @Resource private MdmItemBatchConfigApi itemBatchConfigApi; @Override public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { @@ -161,9 +170,9 @@ @Override @Transactional(rollbackFor = Exception.class) public boolean approveFeedback(Long id) { public boolean approveFeedback(MesProFeedbackApproveReqVO reqVO) { // 1.1 æ ¡éªåå¨ + 审æ¹ä¸ç¶æ MesProFeedbackDO feedback = validateFeedbackStatusApproving(id); MesProFeedbackDO feedback = validateFeedbackStatusApproving(reqVO.getId()); // 1.2 æ ¡éªæ¥å·¥æ°é > 0 if (feedback.getFeedbackQuantity() == null || feedback.getFeedbackQuantity().compareTo(BigDecimal.ZERO) <= 0) { @@ -201,7 +210,7 @@ } // 5. å æ´æ°æ¥å·¥ç¶æä¸ºå·²å®æï¼ç¡®ä¿ checkAndFinishMps æ£æ¥æ¶å½åæ¥å·¥å·²æ è®°å®æï¼ feedbackMapper.updateById(new MesProFeedbackDO().setId(id) feedbackMapper.updateById(new MesProFeedbackDO().setId(reqVO.getId()) .setStatus(MesProFeedbackStatusEnum.FINISHED.getStatus()) .setUncheckQuantity(BigDecimal.ZERO)); @@ -209,13 +218,13 @@ if (checkFlag) { // 6.1 éè¦æ£éªï¼çæäº§åºåï¼è´¨éç¶æ=å¾ æ£éªï¼ï¼æ´æ°æ¥å·¥ç¶æä¸ºå¾ æ£éªï¼çè´¨æ£å®æåè°ååå ¥åº // 宿æ¶åè°è§ï¼MesQcIpqcServiceImpl#finishIpqc â splitPendingAndFinishProduce + updateProFeedbackWhenIpqcFinish productProduceService.generateProductProduce(feedback, true); feedbackMapper.updateById(new MesProFeedbackDO().setId(id) productProduceService.generateProductProduce(feedback, true, reqVO); feedbackMapper.updateById(new MesProFeedbackDO().setId(reqVO.getId()) .setStatus(MesProFeedbackStatusEnum.UNCHECK.getStatus())); return false; } else { // 6.2 æ 鿣éªï¼çæäº§åºåï¼æåæ ¼/ä¸åæ ¼æè¡ï¼ï¼ç´æ¥å®æå ¥åº MesWmProductProduceDO produce = productProduceService.generateProductProduce(feedback, false); MesWmProductProduceDO produce = productProduceService.generateProductProduce(feedback, false, reqVO); productProduceService.finishProductProduce(produce.getId()); // å ³é®å·¥åºï¼æ´æ°ä»»å¡ + å·¥åçå·²ç产æ°éï¼éå ³é®å·¥åºï¼åªæ´æ°ä»»å¡çå·²ç产æ°éï¼å·¥ååªçå ³é®å·¥åºäº§åºï¼ if (keyFlag) { @@ -480,4 +489,70 @@ updateTaskAndWorkOrderByFeedback(feedback); } @Override public MesProFeedbackBatchCheckRespVO checkBatchRequirements(Long feedbackId) { MesProFeedbackDO feedback = validateFeedbackExists(feedbackId); MesProFeedbackBatchCheckRespVO respVO = new MesProFeedbackBatchCheckRespVO(); // 1. æ£æ¥ç©ææ¯å¦å¯ç¨æ¹æ¬¡ç®¡ç MesMdmItemDO item = mdmItemService.getItem(feedback.getItemId()); if (item == null || Boolean.FALSE.equals(item.getIsBatchManaged())) { respVO.setNeedBatchInput(false); respVO.setIsBatchManaged(false); return respVO; } respVO.setIsBatchManaged(true); // 2. è·åæ¹æ¬¡é ç½® MdmItemBatchConfigRespDTO config = itemBatchConfigApi.getItemBatchConfig(feedback.getItemId()); if (config == null) { respVO.setNeedBatchInput(false); return respVO; } // 3. å¡«å é ç½®æ å¿ respVO.setProduceDateFlag(config.getProduceDateFlag()); respVO.setExpireDateFlag(config.getExpireDateFlag()); respVO.setReceiptDateFlag(config.getReceiptDateFlag()); respVO.setVendorFlag(config.getVendorFlag()); respVO.setClientFlag(config.getClientFlag()); respVO.setSalesOrderCodeFlag(config.getSalesOrderCodeFlag()); respVO.setPurchaseOrderCodeFlag(config.getPurchaseOrderCodeFlag()); respVO.setWorkOrderFlag(config.getWorkOrderFlag()); respVO.setTaskFlag(config.getTaskFlag()); respVO.setWorkstationFlag(config.getWorkstationFlag()); respVO.setToolFlag(config.getToolFlag()); respVO.setMoldFlag(config.getMoldFlag()); respVO.setLotNumberFlag(config.getLotNumberFlag()); respVO.setQualityStatusFlag(config.getQualityStatusFlag()); // 4. 夿åªäºå段已èªå¨å¡«å ï¼æ¥å·¥åç产è¿ç¨ä¸å¿ ç¶æå¼çåæ®µï¼ List<String> autoFilled = new ArrayList<>(); // çäº§æ¥æï¼å®¡æ¹æ¶èªå¨åå½å¤© autoFilled.add("produceDate"); // ç产工åï¼ä»æ¥å·¥è®°å½è·å autoFilled.add("workOrderId"); // ç产任å¡ï¼ä»æ¥å·¥è®°å½è·å autoFilled.add("taskId"); // å·¥ä½ç«ï¼ä»æ¥å·¥è®°å½è·å autoFilled.add("workstationId"); respVO.setAutoFilledFields(autoFilled); // 5. 夿æ¯å¦éè¦å¼¹çªï¼åå¨å¿ 填使 æ³èªå¨å¡«å çåæ®µ boolean needBatchInput = false; if (Boolean.TRUE.equals(config.getExpireDateFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getReceiptDateFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getVendorFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getClientFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getSalesOrderCodeFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getPurchaseOrderCodeFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getToolFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getMoldFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getLotNumberFlag())) needBatchInput = true; if (Boolean.TRUE.equals(config.getQualityStatusFlag())) needBatchInput = true; respVO.setNeedBatchInput(needBatchInput); return respVO; } } yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productproduce/MesWmProductProduceService.java
@@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.mes.service.wm.productproduce; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackApproveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceDO; @@ -30,9 +31,11 @@ * * @param feedback æ¥å·¥è®°å½ * @param checkFlag æ¯å¦éè¦æ£éªï¼true=å¾ æ£éªï¼false=æåæ ¼/ä¸åæ ¼æåè¡ï¼ * @param approveReqVO 审æ¹è¯·æ±ï¼å«å¯éæ¹æ¬¡å±æ§ï¼å¯ä¸º nullï¼ * @return çæç产å产åºå */ MesWmProductProduceDO generateProductProduce(MesProFeedbackDO feedback, boolean checkFlag); MesWmProductProduceDO generateProductProduce(MesProFeedbackDO feedback, boolean checkFlag, MesProFeedbackApproveReqVO approveReqVO); /** * IPQC æ£éªå®æåè°ï¼å°å¾ æ£äº§åºæåä¸ºåæ ¼/ä¸åæ ¼è¡ãçææç»ãå®æå ¥åº yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productproduce/MesWmProductProduceServiceImpl.java
@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackApproveReqVO; import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchGenerateReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; @@ -110,7 +111,8 @@ @Override @Transactional(rollbackFor = Exception.class) public MesWmProductProduceDO generateProductProduce(MesProFeedbackDO feedback, boolean checkFlag) { public MesWmProductProduceDO generateProductProduce(MesProFeedbackDO feedback, boolean checkFlag, MesProFeedbackApproveReqVO approveReqVO) { // 0. æ¥è¯¢å ³èçå·¥åï¼ç¨äºè·å clientId çä¿¡æ¯ï¼ MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(feedback.getWorkOrderId()); @@ -122,16 +124,30 @@ .build(); productProduceMapper.insert(produce); // 2. è·åæçææ¹æ¬¡ // 2. è·åæçææ¹æ¬¡ï¼å®¡æ¹è¯·æ±ä¸çæ¹æ¬¡å±æ§ä¼å ï¼ MesWmBatchGenerateReqVO batchReqVO = new MesWmBatchGenerateReqVO() .setItemId(feedback.getItemId()) .setProduceDate(LocalDate.now().atStartOfDay()) // æªæå°å½å¤©é¶ç¹ï¼ç¡®ä¿åä¸å¤©çæ¥å·¥çæç¸åæ¹æ¬¡å· .setExpireDate(feedback.getExpireDate()) .setWorkOrderId(feedback.getWorkOrderId()) .setTaskId(feedback.getTaskId()) .setClientId(workOrder != null ? workOrder.getClientId() : null) .setSalesOrderCode(workOrder != null ? workOrder.getOrderSourceCode() : null) .setWorkstationId(feedback.getWorkstationId()) .setLotNumber(feedback.getLotNumber()); // å并审æ¹è¯·æ±ä¸ç¨æ·å¡«åçæ¹æ¬¡å±æ§ï¼ç¨æ·è¾å ¥å¼ä¼å ï¼ if (approveReqVO != null) { if (approveReqVO.getExpireDate() != null) batchReqVO.setExpireDate(approveReqVO.getExpireDate()); if (approveReqVO.getReceiptDate() != null) batchReqVO.setReceiptDate(approveReqVO.getReceiptDate()); if (approveReqVO.getVendorId() != null) batchReqVO.setVendorId(approveReqVO.getVendorId()); if (approveReqVO.getClientId() != null) batchReqVO.setClientId(approveReqVO.getClientId()); if (approveReqVO.getSalesOrderCode() != null) batchReqVO.setSalesOrderCode(approveReqVO.getSalesOrderCode()); if (approveReqVO.getPurchaseOrderCode() != null) batchReqVO.setPurchaseOrderCode(approveReqVO.getPurchaseOrderCode()); if (approveReqVO.getToolId() != null) batchReqVO.setToolId(approveReqVO.getToolId()); if (approveReqVO.getMoldId() != null) batchReqVO.setMoldId(approveReqVO.getMoldId()); if (approveReqVO.getLotNumber() != null) batchReqVO.setLotNumber(approveReqVO.getLotNumber()); if (approveReqVO.getQualityStatus() != null) batchReqVO.setQualityStatus(approveReqVO.getQualityStatus()); } MesWmBatchDO batch = batchService.getOrGenerateBatchCode(batchReqVO); Long batchId = batch != null ? batch.getId() : null; String batchCode = batch != null ? batch.getCode() : null; yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java
@@ -58,6 +58,9 @@ ErrorCode TENDER_BID_FORBIDDEN_WITHDRAW = new ErrorCode(1_040_500_028, "å½åç¶æä¸å è®¸æ¤æ "); ErrorCode TENDER_EVALUATION_FORBIDDEN = new ErrorCode(1_040_500_029, "å½åç¶æä¸å è®¸è¯æ æä½"); ErrorCode TENDER_AWARD_FORBIDDEN = new ErrorCode(1_040_500_030, "å½åç¶æä¸å è®¸å®æ æä½"); ErrorCode AWARD_BID_NOT_IN_PROJECT = new ErrorCode(1_040_500_031, "ææ è®°å½ä¸å±äºå½åææ é¡¹ç®"); ErrorCode AWARD_BID_WITHDRAWN = new ErrorCode(1_040_500_032, "ææ å·²æ¤æ ï¼ä¸å è®¸å®æ "); ErrorCode AWARD_SUPPLIER_NOT_MATCH_BID = new ErrorCode(1_040_500_033, "ä¾åºå䏿æ è®°å½ä¸ä¸è´"); // ========== éç¨ ========== ErrorCode QUOTE_MATERIAL_DUPLICATE = new ErrorCode(1_040_900_001, "è¯¥ææ å·²åå¨ç¸åç©æçæ¥ä»·"); yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java
@@ -22,6 +22,7 @@ import org.springframework.validation.annotation.Validated; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.*; import java.util.function.Function; @@ -76,17 +77,28 @@ if (existing != null) { throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_SUPPLIER_EXISTS); } // æ ¡éªææ è®°å½ï¼å¿ é¡»å±äºè¯¥é¡¹ç®ãæªè¢«æ¤æ ãä¸ä¾åºåä¸è´ SrmTenderBidDO bid = tenderBidMapper.selectById(createReqVO.getBidId()); if (bid == null) { throw ServiceExceptionUtil.exception(ErrorCodeConstants.BID_NOT_EXISTS); } if (!bid.getTenderProjectId().equals(createReqVO.getTenderProjectId())) { throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_BID_NOT_IN_PROJECT); } if (BidStatusEnum.WITHDRAWN.getCode().equals(bid.getBidStatus())) { throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_BID_WITHDRAWN); } if (!bid.getSupplierId().equals(createReqVO.getSupplierId())) { throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_SUPPLIER_NOT_MATCH_BID); } SrmBidAwardDO award = BeanUtils.toBean(createReqVO, SrmBidAwardDO.class); award.setAwardStatus(AwardStatusEnum.PENDING_APPROVAL.getCode()); award.setAwardTime(LocalDateTime.now()); bidAwardMapper.insert(award); // æ´æ°ææ ç¶æä¸ºä¸æ SrmTenderBidDO bid = tenderBidMapper.selectById(createReqVO.getBidId()); if (bid != null) { bid.setBidStatus(BidStatusEnum.WIN.getCode()); tenderBidMapper.updateById(bid); } bid.setBidStatus(BidStatusEnum.WIN.getCode()); tenderBidMapper.updateById(bid); return award.getId(); } @@ -175,7 +187,15 @@ Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemList(productIds).getCheckedData() .stream().collect(Collectors.toMap(MdmItemRespDTO::getId, Function.identity())); // 6. æå»ºè®¢å项 // 6. æå»ºè®¢åé¡¹ï¼æ¥ä»·ä¸ºæ»ä»·ï¼éé¤ä»¥æ°éå¾å°åä»·ï¼ BigDecimal totalQuoteAmount = quotes.stream() .map(SrmSupplierQuoteDO::getQuotePrice) .reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal awardAmount = award.getAwardAmount() != null ? award.getAwardAmount() : totalQuoteAmount; BigDecimal ratio = totalQuoteAmount.compareTo(BigDecimal.ZERO) > 0 ? awardAmount.divide(totalQuoteAmount, 8, RoundingMode.HALF_UP) : BigDecimal.ONE; List<ErpPurchaseOrderCreateReqDTO.Item> orderItems = new ArrayList<>(); for (SrmTenderMaterialDO material : materials) { SrmSupplierQuoteDO quote = quoteMap.get(material.getId()); @@ -186,10 +206,12 @@ if (mdmItem == null) { continue; } BigDecimal materialTotal = quote.getQuotePrice().multiply(ratio); BigDecimal unitPrice = materialTotal.divide(material.getQuantity(), 4, RoundingMode.HALF_UP); ErpPurchaseOrderCreateReqDTO.Item item = new ErpPurchaseOrderCreateReqDTO.Item(); item.setProductId(material.getProductId()); item.setProductUnitId(mdmItem.getUnitMeasureId()); item.setProductPrice(quote.getQuotePrice()); item.setProductPrice(unitPrice); item.setCount(material.getQuantity()); item.setTaxPercent(quote.getTaxRate()); item.setRemark("ææ ç¼å·: " + award.getAwardNo()); yudao-server/src/main/resources/application-test.yaml
@@ -227,7 +227,7 @@ milvus: initialize-schema: true database-name: test collection-name: knowledge_segment collection-name: knowledge_segment_test host: 36.213.180.217 port: 19530 @@ -282,7 +282,7 @@ storage: # æä»¶ä¸ä¼ é ç½® path: /data/javaWork/mom/file # æä»¶å卿 ¹ç®å½ url-prefix: /admin-api/system/storage-blob # URLè·¯å¾åç¼ domain: https://test.your-domain.com # åååç¼ï¼æå®é ååé ç½®ï¼ domain: http://36.213.180.217:9500 # åååç¼ï¼æå®é ååé ç½®ï¼ï¼å端é 置好åä¸å¤ªå¯¹ç°å¨æ¯ç´è¿åç«¯ï¼ææè¦åç«¯ç«¯å£ expired: 120 # tokenè¿ææ¶é´ï¼åéï¼ use-limit: 10 # tokenä½¿ç¨æ¬¡æ°ä¸é jwt-secret: abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG # JWTå¯é¥ yudao-server/src/main/resources/logback-spring.xml
@@ -8,7 +8,7 @@ <property name="ERROR_LOG_FILE" value="./logs/error/error.log"/> <!-- æ§å¶å° Appender --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">ããããã <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${CONSOLE_LOG_PATTERN}</pattern> </encoder>