| | |
| | | { |
| | | "tool_name": "Read", |
| | | "tool_input_preview": "{\"file_path\":\"D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WMS\\\\WIDESEA_WMSClient_Vben_v2\\\\apps\\\\web-ele\\\\src\\\\views\\\\dashboard\\\\index.vue\"}", |
| | | "error": "File does not exist. Note: your current working directory is D:\\Git\\ShanMeiXinNengYuan\\Code.", |
| | | "timestamp": "2026-04-20T01:28:36.836Z", |
| | | "tool_name": "Bash", |
| | | "tool_input_preview": "{\"command\":\"cd \\\"D:/Git/ShanMeiXinNengYuan/Code\\\" && dotnet build WMS/WIDESEA_WMSServer/WIDESEA_WMSServer.sln 2>&1\",\"timeout\":120000,\"description\":\"Build WMS solution to verify changes\"}", |
| | | "error": "Exit code 1\n æ£å¨ç¡®å®è¦è¿åç项ç®â¦\r\n ææé¡¹ç®åæ¯ææ°çï¼æ æ³è¿åã\r\nD:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\AOP\\LogAOP.cs(169,123): warning CS8625: æ æ³å° null åé¢é转æ¢ä¸ºé null çå¼ç¨ç±»åã [D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\WIDESEA_Core.csproj]\r\nD:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\Authorization\\AuthorizationResponse.cs(21,30): warning CS8625: æ æ³å° null åé¢é转æ¢ä¸ºé null çå¼ç¨ç±»åã [D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_Core\\WIDES...", |
| | | "timestamp": "2026-04-20T16:56:32.862Z", |
| | | "retry_count": 1 |
| | | } |
| | |
| | | { |
| | | "updatedAt": "2026-04-20T02:13:36.765Z", |
| | | "updatedAt": "2026-04-20T17:02:18.624Z", |
| | | "missions": [ |
| | | { |
| | | "id": "session:9007b9ea-1eb6-4d24-8fe7-2c3a949eac88:none", |
| | |
| | | "sourceKey": "session-stop:a6eae12446c31bdfe" |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "id": "session:bce34684-82ff-42dd-b951-6194cfe1e77c:none", |
| | | "source": "session", |
| | | "name": "none", |
| | | "objective": "Session mission", |
| | | "createdAt": "2026-04-20T15:49:37.351Z", |
| | | "updatedAt": "2026-04-20T17:02:18.624Z", |
| | | "status": "done", |
| | | "workerCount": 30, |
| | | "taskCounts": { |
| | | "total": 30, |
| | | "pending": 0, |
| | | "blocked": 0, |
| | | "inProgress": 0, |
| | | "completed": 30, |
| | | "failed": 0 |
| | | }, |
| | | "agents": [ |
| | | { |
| | | "name": "general-purpose:af087f2", |
| | | "role": "general-purpose", |
| | | "ownership": "af087f2e64d433e39", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T17:02:18.624Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a151e5f", |
| | | "role": "general-purpose", |
| | | "ownership": "a151e5f87f0cbdac6", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:50:53.499Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a9435dc", |
| | | "role": "general-purpose", |
| | | "ownership": "a9435dc250bc7482e", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:50:38.393Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a32b075", |
| | | "role": "general-purpose", |
| | | "ownership": "a32b0751a039672ef", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:51:30.118Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:aaa2a0f", |
| | | "role": "general-purpose", |
| | | "ownership": "aaa2a0f6b2a25bec0", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:51:23.092Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a86b879", |
| | | "role": "general-purpose", |
| | | "ownership": "a86b879fb7a0801be", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:52:07.543Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a12823e", |
| | | "role": "general-purpose", |
| | | "ownership": "a12823e675f358745", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:52:29.208Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:ae97a4d", |
| | | "role": "general-purpose", |
| | | "ownership": "ae97a4de553f0b4c3", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:52:16.206Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a4a2d7d", |
| | | "role": "general-purpose", |
| | | "ownership": "a4a2d7dfcc130e3c8", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:53:19.832Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:afef0a2", |
| | | "role": "general-purpose", |
| | | "ownership": "afef0a2e4255227bd", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:53:08.591Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:ae1e2c3", |
| | | "role": "general-purpose", |
| | | "ownership": "ae1e2c3f798ee872a", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:53:36.457Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a66e87c", |
| | | "role": "general-purpose", |
| | | "ownership": "a66e87c9223005128", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:56:26.414Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a113f70", |
| | | "role": "general-purpose", |
| | | "ownership": "a113f704503b35113", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:54:23.336Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a7cc134", |
| | | "role": "general-purpose", |
| | | "ownership": "a7cc1344397da9324", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:58:27.436Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:aeac471", |
| | | "role": "general-purpose", |
| | | "ownership": "aeac471bcaec36af3", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:00:25.655Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a6c7e45", |
| | | "role": "general-purpose", |
| | | "ownership": "a6c7e458af6948696", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T15:57:35.457Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a5144b6", |
| | | "role": "general-purpose", |
| | | "ownership": "a5144b6e94595b89f", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:01:24.405Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:ac4bbba", |
| | | "role": "general-purpose", |
| | | "ownership": "ac4bbba9b05c57c6a", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:03:43.062Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:ad3b6fa", |
| | | "role": "general-purpose", |
| | | "ownership": "ad3b6fad5f339a4e5", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:02:27.528Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a72a84d", |
| | | "role": "general-purpose", |
| | | "ownership": "a72a84d56ec83e520", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:03:48.315Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a62f850", |
| | | "role": "general-purpose", |
| | | "ownership": "a62f85025e6fd117b", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:04:24.590Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a3265e6", |
| | | "role": "general-purpose", |
| | | "ownership": "a3265e63c320b7fb7", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:04:17.712Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a75fe8e", |
| | | "role": "general-purpose", |
| | | "ownership": "a75fe8e3716ab2841", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:05:07.601Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:ab70218", |
| | | "role": "general-purpose", |
| | | "ownership": "ab7021856484bc64e", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:18:18.639Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a9c7d87", |
| | | "role": "general-purpose", |
| | | "ownership": "a9c7d87d13a26caa1", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:18:25.585Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:ac4481c", |
| | | "role": "general-purpose", |
| | | "ownership": "ac4481cc8f2fd18cf", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:18:05.225Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:ad8e51b", |
| | | "role": "general-purpose", |
| | | "ownership": "ad8e51b3e49b68c5b", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:19:04.231Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a8d6992", |
| | | "role": "general-purpose", |
| | | "ownership": "a8d69927a9c24e9b5", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:36:32.273Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:a9f7c77", |
| | | "role": "general-purpose", |
| | | "ownership": "a9f7c771d702937f2", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:35:27.503Z" |
| | | }, |
| | | { |
| | | "name": "general-purpose:aaecb7b", |
| | | "role": "general-purpose", |
| | | "ownership": "aaecb7b0d7ead5188", |
| | | "status": "done", |
| | | "currentStep": null, |
| | | "latestUpdate": "completed", |
| | | "completedSummary": null, |
| | | "updatedAt": "2026-04-20T16:32:32.486Z" |
| | | } |
| | | ], |
| | | "timeline": [ |
| | | { |
| | | "id": "session-start:a8d69927a9c24e9b5:2026-04-20T16:31:25.163Z", |
| | | "at": "2026-04-20T16:31:25.163Z", |
| | | "kind": "update", |
| | | "agent": "general-purpose:a8d6992", |
| | | "detail": "started general-purpose:a8d6992", |
| | | "sourceKey": "session-start:a8d69927a9c24e9b5" |
| | | }, |
| | | { |
| | | "id": "session-start:a9f7c771d702937f2:2026-04-20T16:31:25.222Z", |
| | | "at": "2026-04-20T16:31:25.222Z", |
| | | "kind": "update", |
| | | "agent": "general-purpose:a9f7c77", |
| | | "detail": "started general-purpose:a9f7c77", |
| | | "sourceKey": "session-start:a9f7c771d702937f2" |
| | | }, |
| | | { |
| | | "id": "session-start:aaecb7b0d7ead5188:2026-04-20T16:31:25.289Z", |
| | | "at": "2026-04-20T16:31:25.289Z", |
| | | "kind": "update", |
| | | "agent": "general-purpose:aaecb7b", |
| | | "detail": "started general-purpose:aaecb7b", |
| | | "sourceKey": "session-start:aaecb7b0d7ead5188" |
| | | }, |
| | | { |
| | | "id": "session-stop:aaecb7b0d7ead5188:2026-04-20T16:32:32.486Z", |
| | | "at": "2026-04-20T16:32:32.486Z", |
| | | "kind": "completion", |
| | | "agent": "general-purpose:aaecb7b", |
| | | "detail": "completed", |
| | | "sourceKey": "session-stop:aaecb7b0d7ead5188" |
| | | }, |
| | | { |
| | | "id": "session-stop:a9f7c771d702937f2:2026-04-20T16:35:27.503Z", |
| | | "at": "2026-04-20T16:35:27.503Z", |
| | | "kind": "completion", |
| | | "agent": "general-purpose:a9f7c77", |
| | | "detail": "completed", |
| | | "sourceKey": "session-stop:a9f7c771d702937f2" |
| | | }, |
| | | { |
| | | "id": "session-stop:a8d69927a9c24e9b5:2026-04-20T16:36:32.273Z", |
| | | "at": "2026-04-20T16:36:32.273Z", |
| | | "kind": "completion", |
| | | "agent": "general-purpose:a8d6992", |
| | | "detail": "completed", |
| | | "sourceKey": "session-stop:a8d69927a9c24e9b5" |
| | | }, |
| | | { |
| | | "id": "session-stop:a02e13efa2a4d4a7d:2026-04-20T16:43:22.723Z", |
| | | "at": "2026-04-20T16:43:22.723Z", |
| | | "kind": "completion", |
| | | "agent": "general-purpose:af087f2", |
| | | "detail": "completed", |
| | | "sourceKey": "session-stop:a02e13efa2a4d4a7d" |
| | | }, |
| | | { |
| | | "id": "session-stop:a82856d42f4ef095b:2026-04-20T17:02:18.624Z", |
| | | "at": "2026-04-20T17:02:18.624Z", |
| | | "kind": "completion", |
| | | "agent": "general-purpose:af087f2", |
| | | "detail": "completed", |
| | | "sourceKey": "session-stop:a82856d42f4ef095b" |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T02:08:23.744Z", |
| | | "duration_ms": 81044 |
| | | }, |
| | | { |
| | | "agent_id": "af087f2e64d433e39", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:49:37.351Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:50:06.600Z", |
| | | "duration_ms": 29249 |
| | | }, |
| | | { |
| | | "agent_id": "a151e5f87f0cbdac6", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:50:24.517Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:50:53.498Z", |
| | | "duration_ms": 28981 |
| | | }, |
| | | { |
| | | "agent_id": "a9435dc250bc7482e", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:50:24.578Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:50:38.390Z", |
| | | "duration_ms": 13812 |
| | | }, |
| | | { |
| | | "agent_id": "a32b0751a039672ef", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:51:08.683Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:51:30.117Z", |
| | | "duration_ms": 21434 |
| | | }, |
| | | { |
| | | "agent_id": "aaa2a0f6b2a25bec0", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:51:08.748Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:51:23.091Z", |
| | | "duration_ms": 14343 |
| | | }, |
| | | { |
| | | "agent_id": "a86b879fb7a0801be", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:51:49.188Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:52:07.541Z", |
| | | "duration_ms": 18353 |
| | | }, |
| | | { |
| | | "agent_id": "a12823e675f358745", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:51:49.202Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:52:29.206Z", |
| | | "duration_ms": 40004 |
| | | }, |
| | | { |
| | | "agent_id": "ae97a4de553f0b4c3", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:51:49.272Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:52:16.205Z", |
| | | "duration_ms": 26933 |
| | | }, |
| | | { |
| | | "agent_id": "a4a2d7dfcc130e3c8", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:52:54.548Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:53:19.831Z", |
| | | "duration_ms": 25283 |
| | | }, |
| | | { |
| | | "agent_id": "afef0a2e4255227bd", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:52:54.560Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:53:08.589Z", |
| | | "duration_ms": 14029 |
| | | }, |
| | | { |
| | | "agent_id": "ae1e2c3f798ee872a", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:52:54.621Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:53:36.456Z", |
| | | "duration_ms": 41835 |
| | | }, |
| | | { |
| | | "agent_id": "a66e87c9223005128", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:53:53.740Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:56:26.413Z", |
| | | "duration_ms": 152673 |
| | | }, |
| | | { |
| | | "agent_id": "a113f704503b35113", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:53:53.756Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:54:23.335Z", |
| | | "duration_ms": 29579 |
| | | }, |
| | | { |
| | | "agent_id": "a7cc1344397da9324", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:56:59.419Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:58:27.434Z", |
| | | "duration_ms": 88015 |
| | | }, |
| | | { |
| | | "agent_id": "aeac471bcaec36af3", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:56:59.484Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:00:25.654Z", |
| | | "duration_ms": 206170 |
| | | }, |
| | | { |
| | | "agent_id": "a6c7e458af6948696", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T15:56:59.548Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T15:57:35.456Z", |
| | | "duration_ms": 35908 |
| | | }, |
| | | { |
| | | "agent_id": "a5144b6e94595b89f", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:00:50.066Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:01:24.403Z", |
| | | "duration_ms": 34337 |
| | | }, |
| | | { |
| | | "agent_id": "ad3b6fad5f339a4e5", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:01:46.364Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:02:27.526Z", |
| | | "duration_ms": 41162 |
| | | }, |
| | | { |
| | | "agent_id": "ac4bbba9b05c57c6a", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:01:46.304Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:03:43.060Z", |
| | | "duration_ms": 116756 |
| | | }, |
| | | { |
| | | "agent_id": "a72a84d56ec83e520", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:01:46.423Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:03:48.313Z", |
| | | "duration_ms": 121890 |
| | | }, |
| | | { |
| | | "agent_id": "a62f85025e6fd117b", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:04:06.835Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:04:24.588Z", |
| | | "duration_ms": 17753 |
| | | }, |
| | | { |
| | | "agent_id": "a3265e63c320b7fb7", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:04:06.894Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:04:17.711Z", |
| | | "duration_ms": 10817 |
| | | }, |
| | | { |
| | | "agent_id": "a75fe8e3716ab2841", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:04:35.938Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:05:07.599Z", |
| | | "duration_ms": 31661 |
| | | }, |
| | | { |
| | | "agent_id": "ab7021856484bc64e", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:15:18.619Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:18:18.637Z", |
| | | "duration_ms": 180018 |
| | | }, |
| | | { |
| | | "agent_id": "a9c7d87d13a26caa1", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:15:18.684Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:18:25.584Z", |
| | | "duration_ms": 186900 |
| | | }, |
| | | { |
| | | "agent_id": "ac4481cc8f2fd18cf", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:15:18.748Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:18:05.224Z", |
| | | "duration_ms": 166476 |
| | | }, |
| | | { |
| | | "agent_id": "ad8e51b3e49b68c5b", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:18:33.453Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:19:04.229Z", |
| | | "duration_ms": 30776 |
| | | }, |
| | | { |
| | | "agent_id": "a8d69927a9c24e9b5", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:31:25.163Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:36:32.272Z", |
| | | "duration_ms": 307109 |
| | | }, |
| | | { |
| | | "agent_id": "a9f7c771d702937f2", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:31:25.222Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:35:27.501Z", |
| | | "duration_ms": 242279 |
| | | }, |
| | | { |
| | | "agent_id": "aaecb7b0d7ead5188", |
| | | "agent_type": "general-purpose", |
| | | "started_at": "2026-04-20T16:31:25.289Z", |
| | | "parent_mode": "none", |
| | | "status": "completed", |
| | | "completed_at": "2026-04-20T16:32:32.484Z", |
| | | "duration_ms": 67195 |
| | | } |
| | | ], |
| | | "total_spawned": 118, |
| | | "total_completed": 127, |
| | | "total_spawned": 135, |
| | | "total_completed": 157, |
| | | "total_failed": 0, |
| | | "last_updated": "2026-04-20T02:13:36.867Z" |
| | | "last_updated": "2026-04-20T17:02:18.739Z" |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | //æ¤jsæä»¶æ¯ç¨æ¥èªå®ä¹æ©å±ä¸å¡ä»£ç ï¼å¯ä»¥æ©å±ä¸äºèªå®ä¹é¡µé¢æè
éæ°é
ç½®çæç代ç
|
| | |
|
| | | let extension = {
|
| | | components: {
|
| | | //æ¥è¯¢ç颿©å±ç»ä»¶
|
| | | gridHeader: "",
|
| | | gridBody: "",
|
| | | gridFooter: "",
|
| | | //æ°å»ºãç¼è¾å¼¹åºæ¡æ©å±ç»ä»¶
|
| | | modelHeader: "",
|
| | | modelBody: "",
|
| | | modelFooter: "",
|
| | | },
|
| | | tableAction: "", //æå®æå¼ 表çæé(è¿éå¡«å表å,é»è®¤ä¸ç¨å¡«å)
|
| | | buttons: { view: [], box: [], detail: [] }, //æ©å±çæé®
|
| | | methods: {
|
| | | //ä¸é¢è¿äºæ¹æ³å¯ä»¥ä¿çä¹å¯ä»¥å é¤
|
| | | onInit() {},
|
| | | onInited() {
|
| | | //æ¡æ¶åå§åé
ç½®å
|
| | | //妿è¦é
ç½®æç»è¡¨,卿¤æ¹æ³æä½
|
| | | //this.detailOptions.columns.forEach(column=>{ });
|
| | | },
|
| | | searchBefore(param) {
|
| | | //ç颿¥è¯¢å,å¯ä»¥ç»param.wheresæ·»å æ¥è¯¢åæ°
|
| | | //è¿åfalseï¼åä¸ä¼æ§è¡æ¥è¯¢
|
| | | |
| | | // 第ä¸ä¸ªè¿æ»¤æ¡ä»¶
|
| | | const roadwayFilter1 = {
|
| | | name: "roadway",
|
| | | value: "ZJ1",
|
| | | displayType: "like",
|
| | | };
|
| | | |
| | | // 第äºä¸ªè¿æ»¤æ¡ä»¶
|
| | | const roadwayFilter2 = {
|
| | | name: "roadway",
|
| | | value: "FJ1",
|
| | | displayType: "like",
|
| | | };
|
| | |
|
| | | if (!param.wheres) {
|
| | | param.wheres = [];
|
| | | }
|
| | | |
| | | // å°ä¸¤ä¸ªè¿æ»¤æ¡ä»¶æ·»å å°æ¥è¯¢åæ°ä¸
|
| | | param.wheres.push(roadwayFilter1);
|
| | | param.wheres.push(roadwayFilter2);
|
| | | |
| | | return true;
|
| | | },
|
| | | searchAfter(result) {
|
| | | //æ¥è¯¢åï¼resultè¿åçæ¥è¯¢æ°æ®,å¯ä»¥å¨æ¾ç¤ºå°è¡¨æ ¼åå¤çè¡¨æ ¼çå¼
|
| | | return true;
|
| | | },
|
| | | addBefore(formData) {
|
| | | //æ°å»ºä¿ååformData为对象ï¼å
æ¬æç»è¡¨ï¼å¯ä»¥ç»ç»è¡¨å设置å¼ï¼èªå·±è¾åºçformDataçå¼
|
| | | return true;
|
| | | },
|
| | | updateBefore(formData) {
|
| | | //ç¼è¾ä¿ååformData为对象ï¼å
æ¬æç»è¡¨ãå é¤è¡çId
|
| | | return true;
|
| | | },
|
| | | rowClick({ row, column, event }) {
|
| | | //æ¥è¯¢çé¢ç¹å»è¡äºä»¶
|
| | | this.$refs.table.$refs.table.toggleRowSelection(row); //åå»è¡æ¶éä¸å½åè¡;
|
| | | },
|
| | | modelOpenAfter(row) {
|
| | | //ç¹å»ç¼è¾ãæ°å»ºæé®å¼¹åºæ¡åï¼å¯ä»¥å¨æ¤å¤åé»è¾ï¼å¦ï¼ä»åå°è·åæ°æ®
|
| | | //(1)夿æ¯ç¼è¾è¿æ¯æ°å»ºæä½ï¼ this.currentAction=='Add';
|
| | | //(2)ç»å¼¹åºæ¡è®¾ç½®é»è®¤å¼
|
| | | //(3)this.editFormFields.åæ®µ='xxx';
|
| | | //妿éè¦ç»ä¸ææ¡è®¾ç½®é»è®¤å¼ï¼è¯·éåthis.editFormOptionsæ¾å°å段é
置对åºdata屿§çkeyå¼
|
| | | //ç䏿就æè¾åºçï¼console.log(this.editFormOptions)
|
| | | },
|
| | | },
|
| | | };
|
| | | export default extension;
|
| | |
| | | path: '/task', |
| | | name: 'task', |
| | | component: () => import('@/views/taskinfo/task.vue') |
| | | },{ |
| | | path: '/agvTask', |
| | | name: 'agvTask', |
| | | component: () => import('@/views/taskinfo/agvTask.vue') |
| | | }, |
| | | { |
| | | path: '/taskHty', |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | |
|
| | | <template>
|
| | | <view-grid
|
| | | ref="grid"
|
| | | :columns="columns"
|
| | | :detail="detail"
|
| | | :editFormFields="editFormFields"
|
| | | :editFormOptions="editFormOptions"
|
| | | :searchFormFields="searchFormFields"
|
| | | :searchFormOptions="searchFormOptions"
|
| | | :table="table"
|
| | | :extend="extend"
|
| | | >
|
| | | </view-grid>
|
| | | </template>
|
| | | <script>
|
| | | import extend from "@/extension/taskinfo/agvTask.jsx";
|
| | | import { ref, defineComponent } from "vue";
|
| | | export default defineComponent({
|
| | | setup() {
|
| | | const table = ref({
|
| | | key: "taskId",
|
| | | footer: "Foots",
|
| | | cnName: "ä»»å¡ä¿¡æ¯",
|
| | | name: "task",
|
| | | url: "/Task/",
|
| | | sortName: "CreateDate",
|
| | | });
|
| | | const editFormFields = ref({});
|
| | | const editFormOptions = ref([]);
|
| | | const searchFormFields = ref({
|
| | | taskNum: "",
|
| | | palletCode: "",
|
| | | roadway: "",
|
| | | sourceAddress: "",
|
| | | targetAddress: "",
|
| | | currentAddress: "",
|
| | | nextAddress: "",
|
| | | creater: "",
|
| | | createDate: "",
|
| | | });
|
| | | const searchFormOptions = ref([
|
| | | [
|
| | | { title: "ä»»å¡å·", field: "taskNum", type: "int" },
|
| | | { title: "æçç¼å·", field: "palletCode", type: "like" },
|
| | | {
|
| | | title: "ä»»å¡ç±»å",
|
| | | field: "taskType",
|
| | | type: "selectList",
|
| | | dataKey: "taskType",
|
| | | data: [],
|
| | | },
|
| | | {
|
| | | title: "ä»»å¡ç¶æ",
|
| | | field: "taskStatus",
|
| | | type: "selectList",
|
| | | dataKey: "taskState",
|
| | | data: [],
|
| | | },
|
| | | ],
|
| | | [
|
| | | { title: "èµ·å§å°å", field: "sourceAddress", type: "like" },
|
| | | { title: "ç®æ å°å", field: "targetAddress", type: "like" },
|
| | | { title: "å½åä½ç½®", field: "currentAddress", type: "like" },
|
| | | { title: "ä¸ä¸ä½ç½®", field: "nextAddress", type: "like" },
|
| | | ],
|
| | | [
|
| | | { title: "å··éå·", field: "roadway", type: "like" },
|
| | | { title: "å建人", field: "creater", type: "like" },
|
| | | { title: "å建æ¶é´", field: "createDate", type: "datetime" },
|
| | | ],
|
| | | ]);
|
| | | const columns = ref([
|
| | | {
|
| | | field: "taskId",
|
| | | title: "TaskId",
|
| | | type: "int",
|
| | | width: 90,
|
| | | hidden: true,
|
| | | readonly: true,
|
| | | require: true,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "taskNum",
|
| | | title: "ä»»å¡å·",
|
| | | type: "int",
|
| | | width: 90,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "palletCode",
|
| | | title: "æçç¼å·",
|
| | | type: "string",
|
| | | width: 200,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "roadway",
|
| | | title: "å··éå·",
|
| | | type: "string",
|
| | | width: 90,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "taskType",
|
| | | title: "ä»»å¡ç±»å",
|
| | | type: "int",
|
| | | width: 90,
|
| | | align: "left",
|
| | | bind: { key: "taskType", data: [] },
|
| | | },
|
| | | {
|
| | | field: "taskStatus",
|
| | | title: "ä»»å¡ç¶æ",
|
| | | type: "int",
|
| | | width: 150,
|
| | | align: "left",
|
| | | bind: { key: "taskState", data: [] },
|
| | | },
|
| | | {
|
| | | field: "sourceAddress",
|
| | | title: "èµ·å§å°å",
|
| | | type: "int",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "targetAddress",
|
| | | title: "ç®æ å°å",
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "currentAddress",
|
| | | title: "å½åä½ç½®",
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "nextAddress",
|
| | | title: "ä¸ä¸ä½ç½®",
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "exceptionMessage",
|
| | | title: "å¼å¸¸ä¿¡æ¯",
|
| | | type: "string",
|
| | | width: 90,
|
| | | align: "left",
|
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | field: "grade",
|
| | | title: "ä¼å
级",
|
| | | type: "int",
|
| | | width: 80,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "dispatchertime",
|
| | | title: "ä»»å¡ä¸åæ¶é´",
|
| | | type: "datetime",
|
| | | width: 150,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "wMSId",
|
| | | title: "WMSä»»å¡ä¸»é®",
|
| | | type: "int",
|
| | | width: 120,
|
| | | align: "left",
|
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | field: "creater",
|
| | | title: "å建人",
|
| | | type: "string",
|
| | | width: 90,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "createDate",
|
| | | title: "å建æ¶é´",
|
| | | type: "datetime",
|
| | | width: 150,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "modifier",
|
| | | title: "ä¿®æ¹äºº",
|
| | | type: "string",
|
| | | width: 100,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "modifyDate",
|
| | | title: "ä¿®æ¹æ¶é´",
|
| | | type: "datetime",
|
| | | width: 160,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "remark",
|
| | | title: "夿³¨",
|
| | | type: "string",
|
| | | width: 100,
|
| | | align: "left",
|
| | | hidden: true,
|
| | | },
|
| | | ]);
|
| | | const detail = ref({
|
| | | cnName: "",
|
| | | table: "",
|
| | | columns: [],
|
| | | sortName: "",
|
| | | key: "",
|
| | | });
|
| | | return {
|
| | | table,
|
| | | extend,
|
| | | editFormFields,
|
| | | editFormOptions,
|
| | | searchFormFields,
|
| | | searchFormOptions,
|
| | | columns,
|
| | | detail,
|
| | | };
|
| | | },
|
| | | });
|
| | | </script>
|
| | | |
| | |
| | | using Quartz.Spi; |
| | | using Quartz; |
| | | using System; |
| | | using System.Collections.Concurrent; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | |
| | | namespace WIDESEAWCS_QuartzJob |
| | | { |
| | | /// <summary> |
| | | /// Job注å
¥ |
| | | /// Job注å
¥å·¥åï¼ç®¡ç Job å®ä¾ç DI ä½ç¨åçå½å¨æ |
| | | /// </summary> |
| | | public class JobFactory : IJobFactory |
| | | { |
| | |
| | | private readonly IServiceProvider _serviceProvider; |
| | | |
| | | /// <summary> |
| | | /// Job å®ä¾ä¸å¯¹åºç DI ä½ç¨åæ å°ï¼ç¨äºå¨ ReturnJob æ¶æ£ç¡®éæ¾èµæº |
| | | /// </summary> |
| | | private readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new(); |
| | | |
| | | /// <summary> |
| | | /// Job注å
¥ |
| | | /// </summary> |
| | | /// <param name="serviceProvider"></param> |
| | | /// <param name="serviceProvider">æå¡æä¾è
</param> |
| | | public JobFactory(IServiceProvider serviceProvider) |
| | | { |
| | | _serviceProvider = serviceProvider; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å®ç°æ¥å£Job |
| | | /// å建 Job å®ä¾ï¼å¹¶ä¸ºæ¯ä¸ª Job å建ç¬ç«ç DI ä½ç¨å |
| | | /// </summary> |
| | | /// <param name="bundle"></param> |
| | | /// <param name="scheduler"></param> |
| | | /// <returns></returns> |
| | | /// <param name="bundle">触åå¨è§¦åä¸ä¸æ</param> |
| | | /// <param name="scheduler">è°åº¦å¨å®ä¾</param> |
| | | /// <returns>Job å®ä¾</returns> |
| | | public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) |
| | | { |
| | | try |
| | | { |
| | | if (App.ExpDateTime != null && (DateTime.Now - App.ExpDateTime.GetValueOrDefault()).Seconds > 0) |
| | | // éªè¯æææï¼ä½¿ç¨ TotalSeconds é¿å
.Seconds 忍¡å¯¼è´é´ææ§å¤æé误 |
| | | if (App.ExpDateTime != null && (DateTime.Now - App.ExpDateTime.GetValueOrDefault()).TotalSeconds > 0) |
| | | { |
| | | throw new InvalidOperationException($"éªè¯é误"); |
| | | } |
| | | |
| | | // 为æ¯ä¸ª Job å建ç¬ç«ç DI ä½ç¨åï¼ç¡®ä¿ Scoped æå¡æ£ç¡®éæ¾ |
| | | IServiceScope serviceScope = _serviceProvider.CreateScope(); |
| | | IJob? job = serviceScope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob; |
| | | |
| | | if (job == null) |
| | | { |
| | | // Job è§£æå¤±è´¥æ¶ç«å³éæ¾ä½ç¨åï¼é¿å
æ³æ¼ |
| | | serviceScope.Dispose(); |
| | | throw new InvalidOperationException($"æ æ³è§£æ Job ç±»å: {bundle.JobDetail.JobType.Name}"); |
| | | } |
| | | |
| | | // ä¿å scope å¼ç¨ï¼ä»¥ä¾¿ ReturnJob æ¶éæ¾ |
| | | _scopes[job] = serviceScope; |
| | | return job; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.Out.WriteLine(ex.ToString()); |
| | | throw new Exception(ex.Message); |
| | | throw; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Job注å
¥ |
| | | /// éæ¾ Job å®ä¾åå
¶å
³èç DI ä½ç¨å |
| | | /// </summary> |
| | | /// <param name="job"></param> |
| | | /// <param name="job">å¾
éæ¾ç Job å®ä¾</param> |
| | | public void ReturnJob(IJob job) |
| | | { |
| | | IDisposable? disposable = job as IDisposable; |
| | | disposable?.Dispose(); |
| | | // å
éæ¾å
³èç DI ä½ç¨åï¼å
æ¬å
¶ä¸ææ Scoped æå¡ï¼ |
| | | if (_scopes.TryRemove(job, out IServiceScope? scope)) |
| | | { |
| | | scope.Dispose(); |
| | | } |
| | | |
| | | // åéæ¾ Job æ¬èº« |
| | | (job as IDisposable)?.Dispose(); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | deviceInfos.ForEach(x => |
| | | { |
| | | if (!Storage.Devices.Exists(d => d.DeviceCode == x.DeviceCode)) |
| | | if (!Storage.Devices.Any(d => d.DeviceCode == x.DeviceCode)) |
| | | { |
| | | try |
| | | { |
| | |
| | | WebResponseContent result = new WebResponseContent(); |
| | | try |
| | | { |
| | | if (_scheduler.IsShutdown && _scheduler.IsStarted) |
| | | if (_scheduler.IsShutdown || !_scheduler.IsStarted) |
| | | { |
| | | // ä»Factoryä¸è·åSchedulerå®ä¾ |
| | | NameValueCollection collection = new NameValueCollection |
| | |
| | | } |
| | | else |
| | | { |
| | | await _scheduler.Shutdown(); |
| | | // è°åº¦å¨å·²å¨è¿è¡ï¼ç´æ¥è¿åæç¤º |
| | | result = WebResponseContent.Instance.Error(QuartzJobInfoMessage.JobHasStart); |
| | | return result; |
| | | } |
| | |
| | | //çå¾
ä»»å¡è¿è¡å®æ |
| | | await _scheduler.Shutdown(false); |
| | | |
| | | await Console.Out.WriteLineAsync(QuartzJobInfoMessage.StopJobSuccess); |
| | | QuartzLogger.Info(QuartzJobInfoMessage.StopJobSuccess); |
| | | result = WebResponseContent.Instance.OK(QuartzJobInfoMessage.StopJobSuccess); |
| | | return result; |
| | | } |
| | | else |
| | | { |
| | | IReadOnlyCollection<string> jobGroupNames = await _scheduler.GetJobGroupNames(); |
| | | |
| | | await _scheduler.PauseAll(); |
| | | |
| | | // è°åº¦å¨å·²åæ¢ï¼ç´æ¥è¿åæç¤ºï¼ä¸å对已 shutdown ç scheduler è°ç¨ PauseAllï¼ |
| | | result = WebResponseContent.Instance.Error(QuartzJobInfoMessage.JobHasStop); |
| | | return result; |
| | | } |
| | |
| | | { |
| | | try |
| | | { |
| | | if (_scheduler.IsShutdown && _scheduler.IsStarted) |
| | | if (_scheduler.IsShutdown || !_scheduler.IsStarted) |
| | | { |
| | | // ä»Factoryä¸è·åSchedulerå®ä¾ |
| | | NameValueCollection collection = new NameValueCollection |
| | |
| | | using HslCommunication; |
| | | using System.ComponentModel; |
| | | using System.Reflection; |
| | | using System.Threading; |
| | | using WIDESEAWCS_Communicator; |
| | | using WIDESEAWCS_QuartzJob.DeviceBase; |
| | | using WIDESEAWCS_QuartzJob.DTO; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane.Common; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane.Enum; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | |
| | | namespace WIDESEAWCS_QuartzJob |
| | | { |
| | |
| | | /// </summary> |
| | | private int _lastTaskNum; |
| | | |
| | | private bool _isChecked = false; |
| | | /// <summary> |
| | | /// æ è®°æ¯å¦æ£å¨æ£æ¥ä»»å¡å®æç¶æï¼volatile ä¿è¯å¤çº¿ç¨å¯è§æ§ï¼ |
| | | /// </summary> |
| | | private volatile bool _isChecked = false; |
| | | |
| | | private bool _heartStatr = true; |
| | | |
| | |
| | | { |
| | | OperateResult<TimeSpan> operateResult = new OperateResult<TimeSpan>(); |
| | | TypeCode typeCode = SiemensDBDataType.GetTypeCode(devicePro.DeviceDataType); |
| | | |
| | | // è¶
æ¶ä» 10*6000ms (60s) éä½å° 10*1000ms (10s)ï¼é²æ¢æè¿æ¶é¿æ¶é´é»å¡ |
| | | int timeout = 10 * 1000; |
| | | switch (typeCode) |
| | | { |
| | | case TypeCode.Boolean: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue)); |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToBoolean(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | |
| | | case TypeCode.Byte: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue)); |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToByte(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | |
| | | case TypeCode.Int16: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue)); |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToInt16(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | |
| | | case TypeCode.Int32: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue)); |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToInt32(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | |
| | | case TypeCode.UInt16: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue)); |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToUInt16(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | |
| | | case TypeCode.UInt32: |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, 10 * 6000, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue)); |
| | | operateResult = Communicator.Wait(devicePro.DeviceProAddress, 500, timeout, Convert.ToUInt32(deviceProtocolDetail.ProtocalDetailValue)); |
| | | break; |
| | | |
| | | default: |
| | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | // è®°å½å¼å¸¸ï¼é¿å
é误被éé»åæ |
| | | QuartzLogger.Error($"CheckStackerCraneTaskCompleted: è®¾å¤ {_deviceCode} æ£æ¥å¼å¸¸", "CommonStackerCrane", ex); |
| | | } |
| | | finally |
| | | { |
| | |
| | | using Quartz; |
| | | using SqlSugar; |
| | | using System; |
| | | using System.Collections.Concurrent; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | | using System.Drawing; |
| | |
| | | namespace WIDESEAWCS_QuartzJob |
| | | { |
| | | /// <summary> |
| | | /// éæåè¸åå¨åºï¼å¯ä½¿ç¨éæåéï¼ä¹å¯æ³¨å
¥ä½¿ç¨ |
| | | /// éæåéåå¨åºï¼å¯ä½¿ç¨éæåéï¼ä¹å¯æ³¨å
¥ä½¿ç¨ |
| | | /// </summary> |
| | | public class Storage |
| | | { |
| | | /// <summary> |
| | | /// å·²è¿æ¥è®¾å¤å¯¹è±¡éå |
| | | /// å·²è¿æ¥è®¾å¤å¯¹è±¡éåï¼çº¿ç¨å®å
¨ï¼ |
| | | /// </summary> |
| | | public static List<IDevice> Devices = new List<IDevice>(); |
| | | public static ConcurrentBag<IDevice> Devices = new ConcurrentBag<IDevice>(); |
| | | |
| | | /// <summary> |
| | | /// 设å¤å¯¹è±¡ |
| | |
| | | /// <summary> |
| | | /// è·åè®¾å¤ |
| | | /// </summary> |
| | | /// <param name="deviceCode"></param> |
| | | /// <returns></returns> |
| | | /// <param name="deviceCode">设å¤ç¼ç </param> |
| | | /// <returns>设å¤å®ä¾ï¼æªæ¾å°è¿å null</returns> |
| | | public IDevice? GetDevice(string deviceCode) |
| | | { |
| | | return Pro_Devices.FirstOrDefault(x => x.DeviceCode == deviceCode); |
| | |
| | | /// <summary> |
| | | /// è·åè®¾å¤ |
| | | /// </summary> |
| | | /// <param name="deviceCodes"></param> |
| | | /// <returns></returns> |
| | | /// <param name="deviceCodes">设å¤ç¼ç å表</param> |
| | | /// <returns>å¹é
ç设å¤å表</returns> |
| | | public List<IDevice> GetDevices(List<string> deviceCodes) |
| | | { |
| | | return Pro_Devices.Where(x => deviceCodes.Contains(x.DeviceCode)).ToList(); |
| | |
| | | .Enrich.WithProperty("Application", "WCS") |
| | | // 设置Microsoftå½å空é´çæ¥å¿çº§å«ä¸ºInformation |
| | | // è¿æ ·å¯ä»¥åå°Microsoftæ¡æ¶æ¬èº«çè¯¦ç»æ¥å¿ï¼é¿å
è¿å¤çDebugæ¥å¿ |
| | | .MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
| | | .MinimumLevel.Override("Microsoft", LogEventLevel.Debug) |
| | | .WriteTo.Console() // æ·»å æ§å¶å°è¾åºæ¥æ¶å¨ï¼æ¥å¿å°æ¾ç¤ºå¨æ§å¶å°çªå£ä¸ |
| | | // æ·»å æä»¶è¾åºæ¥æ¶å¨ï¼å°æ¥å¿åå
¥æä»¶ç³»ç» |
| | | .WriteTo.File( |
| | |
| | | "Logging": { |
| | | "LogLevel": { |
| | | "Default": "Information", |
| | | "Microsoft.AspNetCore": "Warning" |
| | | "Microsoft.AspNetCore": "Warning", |
| | | "Quartz": "Debug" |
| | | } |
| | | }, |
| | | "dics": "deviceType,devicePlcType,jobAssembly,jobClassName,deviceStatus,taskType,taskState,inOutType,dispatchId", |
| | |
| | | //è·¨å |
| | | "Cors": { |
| | | "PolicyName": "CorsIpAccess", //çç¥åç§° |
| | | "EnableAllIPs": false, //å½ä¸ºtrueæ¶ï¼å¼æ¾ææIPåå¯è®¿é®ã |
| | | "EnableAllIPs": true, //å½ä¸ºtrueæ¶ï¼å¼æ¾ææIPåå¯è®¿é®ã |
| | | // æ¯æå¤ä¸ªåå端å£ï¼æ³¨æç«¯å£å·åä¸è¦å¸¦/ææï¼æ¯å¦localhost:8000/ï¼æ¯éç |
| | | // 注æï¼http://127.0.0.1:1818 å http://localhost:1818 æ¯ä¸ä¸æ ·ç |
| | | "IPs": "http://127.0.0.1:8080,http://localhost:8080,http://localhost:8081" |
| | |
| | | using WIDESEAWCS_Communicator; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob; |
| | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | // è®°å½å¼å¸¸ï¼é¿å
é误被éé»åæ |
| | | QuartzLogger.Error("CommonConveyorLineJob Execute å¼å¸¸", "CommonConveyorLineJob", ex); |
| | | } |
| | | return Task.CompletedTask; |
| | | } |
| | |
| | | using MapsterMapper; |
| | | using Masuit.Tools; |
| | | using Microsoft.Extensions.Configuration; |
| | | using Microsoft.Extensions.Logging; |
| | | using Newtonsoft.Json; |
| | | using Quartz; |
| | | using Serilog; |
| | | using SqlSugar; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_DTO.TaskInfo; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | |
| | | /// ä»»å¡æå¡ |
| | | /// </summary> |
| | | private readonly ITaskService _taskService; |
| | | |
| | | |
| | | /// <summary> |
| | | /// æºå¨äººä»»å¡æå¡ |
| | |
| | | /// <summary> |
| | | /// æ¥å¿è®°å½å¨ |
| | | /// </summary> |
| | | private readonly ILogger<CommonConveyorLineNewJob> _logger; |
| | | private readonly ILogger _logger; |
| | | |
| | | /// <summary> |
| | | /// ç®æ å°åå°è®¾å¤ç±»åçæ å° |
| | |
| | | /// <remarks> |
| | | /// </remarks> |
| | | private static List<string> AddressToDeviceType = new List<string> { "11020", "11028" }; |
| | | |
| | | /// <summary> |
| | | /// æçæ£æ¥ä½ç½®çæè¿æ§è¡æ¶é´ï¼ç¨äº30ç§é´ééå¶ï¼ |
| | | /// </summary> |
| | | private static readonly Dictionary<string, DateTime> _lastPalletCheckTime = new(); |
| | | |
| | | /// <summary> |
| | | /// æé 彿° |
| | |
| | | /// <param name="mapper">对象æ å°å¨</param> |
| | | /// <param name="httpClientHelper">HTTP 客æ·ç«¯å¸®å©ç±»</param> |
| | | /// <param name="logger">æ¥å¿è®°å½å¨</param> |
| | | public CommonConveyorLineNewJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, HttpClientHelper httpClientHelper, ILogger<CommonConveyorLineNewJob> logger, IRobotTaskService robotTaskService) |
| | | public CommonConveyorLineNewJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, HttpClientHelper httpClientHelper, ILogger logger, IRobotTaskService robotTaskService) |
| | | { |
| | | _taskService = taskService; |
| | | _taskExecuteDetailService = taskExecuteDetailService; |
| | |
| | | // 妿å½å设å¤å¨æ£æ¥åè¡¨ä¸ |
| | | if (checkPalletPositions.Any(x => x.Code == childDeviceCode)) |
| | | { |
| | | // 30ç§é´ééå¶ |
| | | if (_lastPalletCheckTime.TryGetValue(childDeviceCode, out var lastTime) && |
| | | (DateTime.Now - lastTime).TotalSeconds < 30) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | // æ£æ¥è¾éçº¿ç¶æï¼æ¯å¦ææçï¼ |
| | | if (command.CV_State == 2) |
| | | { |
| | |
| | | TargetAddress = childDeviceCode |
| | | }.Serialize()); |
| | | |
| | | _lastPalletCheckTime[childDeviceCode] = DateTime.Now; |
| | | |
| | | // å¦æè¯·æ±æåï¼æ¥æ¶ WMS è¿åçä»»å¡ |
| | | if (responseResult.IsSuccess && responseResult.Data.Status) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | #endregion æ£æµæ¯å¦éè¦ç©ºæç |
| | | |
| | | // ========== æ£æ¥ PLC_STB æ å¿ ========== |
| | | // åªæå½ PLC_STB 为 1 æ¶æå¤çä»»å¡ |
| | |
| | | RobotTargetAddressLineCode = childDeviceCode, |
| | | RobotTaskNum = num, // çæä»»å¡å· |
| | | RobotDispatchertime = DateTime.Now, |
| | | |
| | | }; |
| | | if (_robotTaskService.AddData(robotTask).Status) |
| | | { |
| | |
| | | using MapsterMapper; |
| | | using Microsoft.Extensions.Logging; |
| | | using Serilog; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob; |
| | |
| | | Dt_Task? task = _taskFilter.QueryExecutingTask(command.TaskNo, childDeviceCode); |
| | | if (task != null) |
| | | { |
| | | |
| | | // æ´æ°ä»»å¡ç¶æå°ä¸ä¸é¶æ®µï¼é常æ¯å®æï¼ |
| | | if (_taskService.UpdateTaskStatusToNext(task).Status) |
| | | { |
| | |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | QuartzLogHelper.LogInfo(_logger, "ConveyorLineInFinishï¼å
¥åºå®æï¼ä»»å¡å·: {TaskNum}ï¼å设å¤: {ChildDeviceCode}", $"å
¥åºå®æï¼ä»»å¡å·: {task.TaskNum}", conveyorLine.DeviceCode, task.TaskNum, childDeviceCode); |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using Serilog; |
| | | using WIDESEAWCS_QuartzJob; |
| | | |
| | | namespace WIDESEAWCS_Tasks |
| | |
| | | if (device == null) |
| | | { |
| | | // è®¾å¤æªæ¾å°æ¶è®°å½è°è¯æ¥å¿ï¼æ¹ä¾¿ææ¥é
ç½®é®é¢ |
| | | _logger.LogDebug("FindDeviceï¼æªæ¾å° {DeviceName}", deviceName); |
| | | _logger.Debug("FindDeviceï¼æªæ¾å° {DeviceName}", deviceName); |
| | | } |
| | | return device; // å¯è½ä¸º nullï¼ç±è°ç¨æ¹è´è´£ null æ£æ¥ |
| | | } |
| | |
| | | QuartzLogHelper.LogDebug(_logger, "Handle{Scenario}ï¼å设å¤: {ChildDeviceCode}ï¼ç®æ å°å: {NextAddress}", $"Handle{scenario}ï¼å设å¤: {childDeviceCode}ï¼ç®æ å°å: {nextAddress}", conveyorLine.DeviceCode, scenario, childDeviceCode, nextAddress); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using Serilog; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | |
| | |
| | | return result.Status; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using Serilog; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | |
| | | namespace WIDESEAWCS_Tasks; |
| | |
| | | /// <param name="args">ILogger ç»æåæ¥å¿çåæ°</param> |
| | | public static void LogError(ILogger logger, Exception ex, string loggerMessage, string quartzMessage, string deviceCode, params object[] args) |
| | | { |
| | | logger.LogError(ex, loggerMessage, args); |
| | | logger.Error(ex, loggerMessage, args); |
| | | QuartzLogger.Error(quartzMessage, deviceCode, ex); |
| | | } |
| | | |
| | |
| | | /// <param name="args">ILogger ç»æåæ¥å¿çåæ°</param> |
| | | public static void LogError(ILogger logger, string loggerMessage, string quartzMessage, string deviceCode, params object[] args) |
| | | { |
| | | logger.LogError(loggerMessage, args); |
| | | logger.Error(loggerMessage, args); |
| | | QuartzLogger.Error(quartzMessage, deviceCode); |
| | | } |
| | | |
| | |
| | | /// <param name="args">ILogger ç»æåæ¥å¿çåæ°</param> |
| | | public static void LogInfo(ILogger logger, string loggerMessage, string quartzMessage, string deviceCode, params object[] args) |
| | | { |
| | | logger.LogInformation(loggerMessage, args); |
| | | logger.Information(loggerMessage, args); |
| | | QuartzLogger.Info(quartzMessage, deviceCode); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è®°å½ä¿¡æ¯æ¥å¿ |
| | | /// </summary> |
| | | /// <param name="logger">ILogger å®ä¾</param> |
| | | /// <param name="loggerMessage">ILogger çç»æåæ¥å¿æ¨¡æ¿</param> |
| | | /// <param name="quartzMessage">QuartzLogger çæ¥å¿æ¶æ¯</param> |
| | | /// <param name="deviceCode">设å¤ç¼ç </param> |
| | | public static void LogInfo(ILogger logger, string loggerMessage, string deviceCode) |
| | | { |
| | | logger.Information(loggerMessage); |
| | | QuartzLogger.Info(loggerMessage, deviceCode); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <param name="args">ILogger ç»æåæ¥å¿çåæ°</param> |
| | | public static void LogWarn(ILogger logger, string loggerMessage, string quartzMessage, string deviceCode, params object[] args) |
| | | { |
| | | logger.LogWarning(loggerMessage, args); |
| | | logger.Warning(loggerMessage, args); |
| | | QuartzLogger.Warn(quartzMessage, deviceCode); |
| | | } |
| | | |
| | |
| | | /// <param name="args">ILogger ç»æåæ¥å¿çåæ°</param> |
| | | public static void LogDebug(ILogger logger, string loggerMessage, string quartzMessage, string deviceCode, params object[] args) |
| | | { |
| | | logger.LogDebug(loggerMessage, args); |
| | | logger.Debug(loggerMessage, args); |
| | | QuartzLogger.Debug(quartzMessage, deviceCode); |
| | | } |
| | | } |
| | | } |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | //using Microsoft.Extensions.Logging; |
| | | using Quartz; |
| | | using Serilog; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Common.Constants; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoRepository; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | |
| | | using WIDESEAWCS_QuartzJob.Service; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane.Enum; |
| | | using WIDESEAWCS_Common.Constants; |
| | | using WIDESEAWCS_Tasks.StackerCraneJob; |
| | | |
| | | namespace WIDESEAWCS_Tasks |
| | |
| | | /// <summary> |
| | | /// æ¥å¿è®°å½å¨ |
| | | /// </summary> |
| | | private readonly ILogger<CommonStackerCraneJob> _logger; |
| | | private readonly ILogger _logger; |
| | | |
| | | /// <summary> |
| | | /// å åæºè®¾å¤ç¼ç |
| | |
| | | ITaskRepository taskRepository, |
| | | IRouterService routerService, |
| | | HttpClientHelper httpClientHelper, |
| | | ILogger<CommonStackerCraneJob> logger) |
| | | ILogger logger) |
| | | { |
| | | _taskService = taskService; |
| | | _taskExecuteDetailService = taskExecuteDetailService; |
| | |
| | | _logger = logger; |
| | | |
| | | // å è½½é
ç½®æä»¶ |
| | | _config = LoadConfig(); |
| | | //_config = LoadConfig(); |
| | | |
| | | // åå§åä»»å¡éæ©å¨ |
| | | _taskSelector = new StackerCraneTaskSelector(taskService, routerService, httpClientHelper, _logger); |
| | | |
| | | // åå§åå½ä»¤æå»ºå¨ |
| | | _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _config, _logger); |
| | | _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _logger); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | try |
| | | { |
| | | //QuartzLogger.Info($"CommonStackerCraneJob Executeï¼å¼å§æ§è¡å åæºä»»å¡è°åº¦ ã{DateTime.Now.ToString("F")}ã", "CommonStackerCraneJob Execute "); |
| | | // ä» JobDataMap è·åå åæºè®¾å¤åæ° |
| | | bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value); |
| | | if (!flag || value is not CommonStackerCrane commonStackerCrane) |
| | | { |
| | | _logger.Information("Executeï¼åæ°æ æï¼æªæ¾å° JobParams æç±»åä¸å¹é
"); |
| | | // åæ°æ æï¼ç´æ¥è¿å |
| | | QuartzLogHelper.LogWarn(_logger, "Executeï¼åæ°æ æ", "Executeï¼åæ°æ æ", "CommonStackerCraneJob"); |
| | | return Task.CompletedTask; |
| | |
| | | |
| | | // ========== æ£æ¥æ¯å¦å¯ä»¥åéæ°ä»»å¡ ========== |
| | | //if (!commonStackerCrane.IsCanSendTask(commonStackerCrane.Communicator, commonStackerCrane.DeviceProDTOs, commonStackerCrane.DeviceProtocolDetailDTOs)) |
| | | if (commonStackerCrane.StackerCraneStatusValue != StackerCraneStatus.Normal ) |
| | | if (commonStackerCrane.StackerCraneStatusValue != StackerCraneStatus.Normal) |
| | | { |
| | | // å åæºä¸å¯ç¨ï¼å¦æ£å¨æ§è¡ä¸ä¸ä»»å¡ï¼ï¼ç´æ¥è¿å |
| | | return Task.CompletedTask; |
| | |
| | | bool sendFlag = SendStackerCraneCommand(commonStackerCrane, stackerCraneTaskCommand); |
| | | if (sendFlag) |
| | | { |
| | | Task.Delay(1000).Wait(); |
| | | Thread.Sleep(1000); |
| | | commonStackerCrane.SetValue(StackerCraneDBName.WorkAction, (short)StackerCraneWorkActionEnum.StartTask); |
| | | // åéæåï¼æ´æ°ç¶æ |
| | | commonStackerCrane.LastTaskType = task.TaskType; |
| | |
| | | // è®°å½å¼å¸¸ |
| | | QuartzLogHelper.LogError(_logger, ex, "Executeï¼æ§è¡å¼å¸¸ï¼è®¾å¤: {DeviceCode}", $"æ§è¡å¼å¸¸: {ex.Message}", _deviceCode, _deviceCode); |
| | | } |
| | | finally |
| | | { |
| | | QuartzLogHelper.LogInfo(_logger, $"CommonStackerCraneJob Executeï¼å åæºä»»å¡è°åº¦æ§è¡å®æ ã{DateTime.Now.ToString("F")}ã", _deviceCode); |
| | | } |
| | | |
| | | return Task.CompletedTask; |
| | | } |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using System; |
| | | using Serilog; |
| | | using System.Diagnostics.CodeAnalysis; |
| | | using WIDESEAWCS_Common.Constants; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob.Models; |
| | |
| | | private readonly IRouterService _routerService; |
| | | |
| | | /// <summary> |
| | | /// å åæºå½ä»¤é
ç½® |
| | | /// </summary> |
| | | private readonly StackerCraneCommandConfig _config; |
| | | |
| | | /// <summary> |
| | | /// æ¥å¿è®°å½å¨ |
| | | /// </summary> |
| | | private readonly ILogger _logger; |
| | |
| | | public StackerCraneCommandBuilder( |
| | | ITaskService taskService, |
| | | IRouterService routerService, |
| | | StackerCraneCommandConfig config, |
| | | ILogger logger) |
| | | { |
| | | _taskService = taskService; |
| | | _routerService = routerService; |
| | | _config = config; |
| | | _logger = logger; |
| | | } |
| | | |
| | |
| | | /// <returns>å åæºå½ä»¤å¯¹è±¡ï¼è½¬æ¢å¤±è´¥è¿å null</returns> |
| | | public object? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task) |
| | | { |
| | | return BuildCommand(task, CreateStandardCommand(task)); |
| | | return BuildCommand(task, CreateStandardCommand(task)); |
| | | // æ ¹æ®å··éè·åå½ä»¤ç±»å |
| | | //string commandType = GetCommandType(task.Roadway); |
| | | |
| | |
| | | /// </remarks> |
| | | /// <param name="roadway">å··éç¼ç </param> |
| | | /// <returns>å½ä»¤ç±»åï¼Standard æ Formationï¼</returns> |
| | | private string GetCommandType(string roadway) |
| | | { |
| | | foreach (var mapping in _config.RoadwayCommandMapping) |
| | | { |
| | | if (roadway.Contains(mapping.Key)) |
| | | { |
| | | QuartzLogHelper.LogDebug(_logger, "GetCommandTypeï¼å¹é
å··é {Roadway}ï¼å½ä»¤ç±»å: {CommandType}", $"GetCommandTypeï¼å¹é
å··é {roadway}ï¼å½ä»¤ç±»å: {mapping.Value}", roadway, roadway, mapping.Value); |
| | | return mapping.Value; |
| | | } |
| | | } |
| | | //private string GetCommandType(string roadway) |
| | | //{ |
| | | // foreach (var mapping in _config.RoadwayCommandMapping) |
| | | // { |
| | | // if (roadway.Contains(mapping.Key)) |
| | | // { |
| | | // QuartzLogHelper.LogDebug(_logger, "GetCommandTypeï¼å¹é
å··é {Roadway}ï¼å½ä»¤ç±»å: {CommandType}", $"GetCommandTypeï¼å¹é
å··é {roadway}ï¼å½ä»¤ç±»å: {mapping.Value}", roadway, roadway, mapping.Value); |
| | | // return mapping.Value; |
| | | // } |
| | | // } |
| | | |
| | | QuartzLogHelper.LogDebug(_logger, "GetCommandTypeï¼å··é {Roadway} æªå¹é
ï¼ä½¿ç¨é»è®¤å½ä»¤ç±»å: {DefaultType}", $"GetCommandTypeï¼å··é {roadway} æªå¹é
ï¼ä½¿ç¨é»è®¤å½ä»¤ç±»å: {_config.DefaultCommandType}", roadway, roadway, _config.DefaultCommandType); |
| | | return _config.DefaultCommandType; |
| | | } |
| | | // QuartzLogHelper.LogDebug(_logger, "GetCommandTypeï¼å··é {Roadway} æªå¹é
ï¼ä½¿ç¨é»è®¤å½ä»¤ç±»å: {DefaultType}", $"GetCommandTypeï¼å··é {roadway} æªå¹é
ï¼ä½¿ç¨é»è®¤å½ä»¤ç±»å: {_config.DefaultCommandType}", roadway, roadway, _config.DefaultCommandType); |
| | | // return _config.DefaultCommandType; |
| | | //} |
| | | |
| | | /// <summary> |
| | | /// å建æ åå½ä»¤ |
| | |
| | | { |
| | | taskType = StackerCraneConst.EmptyPalletTaskType; |
| | | } |
| | | else if(task.TaskType == (int)TaskInboundTypeEnum.InEmpty) |
| | | else if (task.TaskType == (int)TaskInboundTypeEnum.InEmpty) |
| | | { |
| | | taskType = StackerCraneConst.EmptyInPalletTaskType; |
| | | } |
| | |
| | | && short.TryParse(parts[2], out layer); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | using Microsoft.Extensions.Logging; |
| | | using Newtonsoft.Json; |
| | | using Serilog; |
| | | using System.Diagnostics.CodeAnalysis; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_Common.Constants; |
| | | using WIDESEAWCS_Common.HttpEnum; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob; |
| | |
| | | return isOccupied; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | let loadingInstance; |
| | | let loadingStatus = false; |
| | | if (process.env.NODE_ENV == 'development') { |
| | | axios.defaults.baseURL = 'http://127.0.0.1:9291/'; |
| | | axios.defaults.baseURL = window.webConfig.webApiProduction; |
| | | } |
| | | else if (process.env.NODE_ENV == 'debug') { |
| | | axios.defaults.baseURL = window.webConfig.webApiBaseUrl; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | //æ¤jsæä»¶æ¯ç¨æ¥èªå®ä¹æ©å±ä¸å¡ä»£ç ï¼å¯ä»¥æ©å±ä¸äºèªå®ä¹é¡µé¢æè
éæ°é
ç½®çæç代ç
|
| | |
|
| | | let extension = {
|
| | | components: {
|
| | | //æ¥è¯¢ç颿©å±ç»ä»¶
|
| | | gridHeader: '',
|
| | | gridBody: '',
|
| | | gridFooter: '',
|
| | | //æ°å»ºãç¼è¾å¼¹åºæ¡æ©å±ç»ä»¶
|
| | | modelHeader: '',
|
| | | modelBody: '',
|
| | | modelFooter: ''
|
| | | },
|
| | | tableAction: '',
|
| | | buttons: { view: [], box: [], detail: [] },
|
| | | methods: {
|
| | | onInit() {
|
| | | // æ·»å MESæä½å
|
| | | this.columns.push({
|
| | | title: 'æä½',
|
| | | field: 'æä½',
|
| | | align: 'center',
|
| | | width: 200,
|
| | | fixed: 'right',
|
| | | render: (h, { row, column, index }) => {
|
| | | return (
|
| | | <div>
|
| | | <el-button
|
| | | type="primary"
|
| | | size="small"
|
| | | onClick={($e) => { this.handleInbound(row); }}
|
| | | >è¿ç«</el-button>
|
| | | <el-button
|
| | | type="success"
|
| | | size="small"
|
| | | style="margin-left: 8px"
|
| | | onClick={($e) => { this.handleOutbound(row); }}
|
| | | >åºç«</el-button>
|
| | | </div>
|
| | | );
|
| | | }
|
| | | });
|
| | | },
|
| | |
|
| | | // æçè¿ç«æä½
|
| | | async handleInbound(row) {
|
| | | try {
|
| | | await this.$confirm(`确认æ§è¡æçè¿ç«æä½ï¼\næçç¼å·ï¼${row.palletCode}`, "è¿ç«ç¡®è®¤", {
|
| | | confirmButtonText: "确认",
|
| | | cancelButtonText: "åæ¶",
|
| | | type: "warning"
|
| | | });
|
| | |
|
| | | const result = await this.http.post("/api/StockInfo/inboundInContainer", {
|
| | | palletCode: row.palletCode,
|
| | | stockId: row.id
|
| | | }, "æ£å¨è°ç¨MESæ¥å£...");
|
| | |
|
| | | if (result.status) {
|
| | | this.$Message.success(result.message || "æçè¿ç«æå");
|
| | | this.$refs.table.load();
|
| | | } else {
|
| | | this.$error(result.message || "æçè¿ç«å¤±è´¥");
|
| | | }
|
| | | } catch (error) {
|
| | | if (error !== "cancel") {
|
| | | this.$error(error.message || "ç½ç»é误ï¼è¯·ç¨åéè¯");
|
| | | }
|
| | | }
|
| | | },
|
| | |
|
| | | // æçåºç«æä½
|
| | | async handleOutbound(row) {
|
| | | try {
|
| | | await this.$confirm(`确认æ§è¡æçåºç«æä½ï¼\næçç¼å·ï¼${row.palletCode}`, "åºç«ç¡®è®¤", {
|
| | | confirmButtonText: "确认",
|
| | | cancelButtonText: "åæ¶",
|
| | | type: "warning"
|
| | | });
|
| | |
|
| | | const result = await this.http.post("/api/StockInfo/outboundInContainer", {
|
| | | palletCode: row.palletCode,
|
| | | stockId: row.id
|
| | | }, "æ£å¨è°ç¨MESæ¥å£...");
|
| | |
|
| | | if (result.status) {
|
| | | this.$Message.success(result.message || "æçåºç«æå");
|
| | | this.$refs.table.load();
|
| | | } else {
|
| | | this.$error(result.message || "æçåºç«å¤±è´¥");
|
| | | }
|
| | | } catch (error) {
|
| | | if (error !== "cancel") {
|
| | | this.$error(error.message || "ç½ç»é误ï¼è¯·ç¨åéè¯");
|
| | | }
|
| | | }
|
| | | },
|
| | |
|
| | | onInited() {
|
| | | // æ¡æ¶åå§åé
ç½®å
|
| | | },
|
| | | searchBefore(param) {
|
| | | const locationCodeFilter = {
|
| | | name: "stockStatus",
|
| | | value: "1",
|
| | | displayType: "int"
|
| | | };
|
| | | if (!param.wheres) {
|
| | | param.wheres = [];
|
| | | }
|
| | | // å°è¿æ»¤æ¡ä»¶æ·»å å°æ¥è¯¢åæ°ä¸
|
| | | param.wheres.push(locationCodeFilter);
|
| | | return true;
|
| | | },
|
| | | searchAfter(result) {
|
| | | return true;
|
| | | },
|
| | | addBefore(formData) {
|
| | | return true;
|
| | | },
|
| | | updateBefore(formData) {
|
| | | return true;
|
| | | },
|
| | | rowClick({ row, column, event }) {
|
| | | this.$refs.table.$refs.table.toggleRowSelection(row);
|
| | | },
|
| | | modelOpenAfter(row) {
|
| | | // ç¹å»ç¼è¾ãæ°å»ºæé®å¼¹åºæ¡å
|
| | | }
|
| | | }
|
| | | };
|
| | |
|
| | | export default extension;
|
| | |
| | | // 页颿©å±é
ç½®ï¼é¢çç»åºå页é¢äºæ¬¡å¼åã |
| | | // 页颿©å±é
ç½®ï¼åºå页é¢ç»ç/æçæé®æ©å± |
| | | let extension = { |
| | | components: { |
| | | gridHeader: "", |
| | |
| | | modelBody: "", |
| | | modelFooter: "", |
| | | }, |
| | | tableAction: "", |
| | | tableAction: "stock", |
| | | buttons: { view: [], box: [], detail: [] }, |
| | | methods: { |
| | | onInit() { |
| | | return true; |
| | | }, |
| | | onInited() { |
| | | // 注å
¥ç»çãæçæé®å°æä½å |
| | | this.editTableButtons = [ |
| | | { name: "ç»ç", onClick: this.onGroupPallet }, |
| | | { name: "æç", onClick: this.onSplitPallet } |
| | | ]; |
| | | return true; |
| | | }, |
| | | async onGroupPallet({ row }) { |
| | | // è°ç¨ç»çæ¥å£ |
| | | let result = await this.$api.post("/Stock/GroupPalletConfirm", { palletCode: row.palletCode }); |
| | | if (result.status) { |
| | | this.$Message.success("ç»çæåï¼MESæ°æ®å·²å¼æ¥ä¸ä¼ "); |
| | | this.$refs.grid.search(); |
| | | } else { |
| | | this.$Message.error(result.message || "ç»ç失败"); |
| | | } |
| | | }, |
| | | async onSplitPallet({ row }) { |
| | | // è°ç¨æçæ¥å£ |
| | | let result = await this.$api.post("/Stock/SplitPalletConfirm", { palletCode: row.palletCode }); |
| | | if (result.status) { |
| | | this.$Message.success("æçæåï¼MESæ°æ®å·²å¼æ¥ä¸ä¼ "); |
| | | this.$refs.grid.search(); |
| | | } else { |
| | | this.$Message.error(result.message || "æç失败"); |
| | | } |
| | | }, |
| | | searchBefore(param) { |
| | | return true; |
| | |
| | | }, |
| | | }; |
| | | |
| | | export default extension; |
| | | export default extension; |
| | |
| | | <el-button |
| | | type="primary" |
| | | size="small" |
| | | onClick={($e) => { this.handleBind(row); }} |
| | | >ç»å®</el-button> |
| | | <el-button |
| | | type="primary" |
| | | size="small" |
| | | onClick={($e) => { this.handleInbound(row); }} |
| | | >è¿ç«</el-button> |
| | | <el-button |
| | |
| | | style="margin-left: 8px" |
| | | onClick={($e) => { this.handleOutbound(row); }} |
| | | >åºç«</el-button> |
| | | <el-button |
| | | type="success" |
| | | size="small" |
| | | style="margin-left: 8px" |
| | | onClick={($e) => { this.handleUnbind(row); }} |
| | | >è§£ç»</el-button> |
| | | </div> |
| | | ); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // æçç»çæä½ |
| | | async handleBind(row) { |
| | | try { |
| | | await this.$confirm(`确认æ§è¡æçç»çæä½ï¼\næçç¼å·ï¼${row.palletCode}`, "ç»ç确认", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }); |
| | | |
| | | const result = await this.http.post("/api/StockInfoDetail/BindContainer", { |
| | | palletCode: row.palletCode |
| | | }, "æ£å¨è°ç¨MESæ¥å£..."); |
| | | |
| | | if (result.status) { |
| | | this.$Message.success(result.message || "æçç»çæå"); |
| | | this.$refs.table.load(); |
| | | } else { |
| | | this.$error(result.message || "æçç»ç失败"); |
| | | } |
| | | } catch (error) { |
| | | if (error !== "cancel") { |
| | | this.$error(error.message || "ç½ç»é误ï¼è¯·ç¨åéè¯"); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | // æçè¿ç«æä½ |
| | |
| | | } |
| | | }, |
| | | |
| | | // æçæçæä½ |
| | | async handleUnbind(row) { |
| | | try { |
| | | await this.$confirm(`确认æ§è¡æçæçæä½ï¼\næçç¼å·ï¼${row.palletCode}`, "æç确认", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning" |
| | | }); |
| | | |
| | | const result = await this.http.post("/api/StockInfoDetail/UnbindContainer", { |
| | | palletCode: row.palletCode, |
| | | }, "æ£å¨è°ç¨MESæ¥å£..."); |
| | | |
| | | if (result.status) { |
| | | this.$Message.success(result.message || "æçæçæå"); |
| | | this.$refs.table.load(); |
| | | } else { |
| | | this.$error(result.message || "æçæç失败"); |
| | | } |
| | | } catch (error) { |
| | | if (error !== "cancel") { |
| | | this.$error(error.message || "ç½ç»é误ï¼è¯·ç¨åéè¯"); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | onInited() { |
| | | // æ¡æ¶åå§åé
ç½®å |
| | | }, |
| | |
| | | return true; |
| | | }, |
| | | searchAfter(result) { |
| | | return true; |
| | | return result; |
| | | }, |
| | | addBefore(formData) { |
| | | return true; |
| | |
| | | this.showJsonDetail(row, 'request'); |
| | | } else if (column.property === 'responseJson' && row.responseJson) { |
| | | this.showJsonDetail(row, 'response'); |
| | | } else if (column.property === 'errorMessage' && row.errorMessage) { |
| | | this.showJsonDetail(row, 'errorMessage'); |
| | | } |
| | | }, |
| | | |
| | | // æ¾ç¤º JSON 详æ
æ½å± |
| | | showJsonDetail(row, type = 'request') { |
| | | const jsonContent = type === 'request' ? row.requestJson : row.responseJson; |
| | | const title = type === 'request' ? 'ð è¯·æ± JSON' : 'ð¥ ååº JSON'; |
| | | const jsonContent = type === 'request' ? row.requestJson : type === 'response' ? row.responseJson : row.errorMessage; |
| | | const title = type === 'request' ? 'ð è¯·æ± JSON' : type === 'response' ? 'ð è¯·æ± JSON': 'ð¥ éè¯¯æ¶æ¯'; |
| | | |
| | | // è§£æ JSON 对象ï¼è§£æå¤±è´¥åä¿çåå§å符串 |
| | | let jsonData; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | //æ¤jsæä»¶æ¯ç¨æ¥èªå®ä¹æ©å±ä¸å¡ä»£ç ï¼å¯ä»¥æ©å±ä¸äºèªå®ä¹é¡µé¢æè
éæ°é
ç½®çæç代ç
|
| | |
|
| | | let extension = {
|
| | | components: {
|
| | | //æ¥è¯¢ç颿©å±ç»ä»¶
|
| | | gridHeader: "",
|
| | | gridBody: "",
|
| | | gridFooter: "",
|
| | | //æ°å»ºãç¼è¾å¼¹åºæ¡æ©å±ç»ä»¶
|
| | | modelHeader: "",
|
| | | modelBody: "",
|
| | | modelFooter: "",
|
| | | },
|
| | | tableAction: "", //æå®æå¼ 表çæé(è¿éå¡«å表å,é»è®¤ä¸ç¨å¡«å)
|
| | | buttons: { view: [], box: [], detail: [] }, //æ©å±çæé®
|
| | | methods: {
|
| | | //ä¸é¢è¿äºæ¹æ³å¯ä»¥ä¿çä¹å¯ä»¥å é¤
|
| | | onInit() {},
|
| | | onInited() {
|
| | | //æ¡æ¶åå§åé
ç½®å
|
| | | //妿è¦é
ç½®æç»è¡¨,卿¤æ¹æ³æä½
|
| | | //this.detailOptions.columns.forEach(column=>{ });
|
| | | },
|
| | | searchBefore(param) {
|
| | | //ç颿¥è¯¢å,å¯ä»¥ç»param.wheresæ·»å æ¥è¯¢åæ°
|
| | | //è¿åfalseï¼åä¸ä¼æ§è¡æ¥è¯¢
|
| | | |
| | | // 第ä¸ä¸ªè¿æ»¤æ¡ä»¶
|
| | | const roadwayFilter1 = {
|
| | | name: "roadway",
|
| | | value: "ZJ1",
|
| | | displayType: "like",
|
| | | };
|
| | | |
| | | // 第äºä¸ªè¿æ»¤æ¡ä»¶
|
| | | const roadwayFilter2 = {
|
| | | name: "roadway",
|
| | | value: "FJ1",
|
| | | displayType: "like",
|
| | | };
|
| | |
|
| | | if (!param.wheres) {
|
| | | param.wheres = [];
|
| | | }
|
| | | |
| | | // å°ä¸¤ä¸ªè¿æ»¤æ¡ä»¶æ·»å å°æ¥è¯¢åæ°ä¸
|
| | | param.wheres.push(roadwayFilter1);
|
| | | param.wheres.push(roadwayFilter2);
|
| | | |
| | | return true;
|
| | | },
|
| | | searchAfter(result) {
|
| | | //æ¥è¯¢åï¼resultè¿åçæ¥è¯¢æ°æ®,å¯ä»¥å¨æ¾ç¤ºå°è¡¨æ ¼åå¤çè¡¨æ ¼çå¼
|
| | | return true;
|
| | | },
|
| | | addBefore(formData) {
|
| | | //æ°å»ºä¿ååformData为对象ï¼å
æ¬æç»è¡¨ï¼å¯ä»¥ç»ç»è¡¨å设置å¼ï¼èªå·±è¾åºçformDataçå¼
|
| | | return true;
|
| | | },
|
| | | updateBefore(formData) {
|
| | | //ç¼è¾ä¿ååformData为对象ï¼å
æ¬æç»è¡¨ãå é¤è¡çId
|
| | | return true;
|
| | | },
|
| | | rowClick({ row, column, event }) {
|
| | | //æ¥è¯¢çé¢ç¹å»è¡äºä»¶
|
| | | this.$refs.table.$refs.table.toggleRowSelection(row); //åå»è¡æ¶éä¸å½åè¡;
|
| | | },
|
| | | modelOpenAfter(row) {
|
| | | //ç¹å»ç¼è¾ãæ°å»ºæé®å¼¹åºæ¡åï¼å¯ä»¥å¨æ¤å¤åé»è¾ï¼å¦ï¼ä»åå°è·åæ°æ®
|
| | | //(1)夿æ¯ç¼è¾è¿æ¯æ°å»ºæä½ï¼ this.currentAction=='Add';
|
| | | //(2)ç»å¼¹åºæ¡è®¾ç½®é»è®¤å¼
|
| | | //(3)this.editFormFields.åæ®µ='xxx';
|
| | | //妿éè¦ç»ä¸ææ¡è®¾ç½®é»è®¤å¼ï¼è¯·éåthis.editFormOptionsæ¾å°å段é
置对åºdata屿§çkeyå¼
|
| | | //ç䏿就æè¾åºçï¼console.log(this.editFormOptions)
|
| | | },
|
| | | },
|
| | | };
|
| | | export default extension;
|
| | |
| | | path: '/task_hty', |
| | | name: 'task_hty', |
| | | component: () => import('@/views/taskinfo/task_hty.vue') |
| | | }, { |
| | | },{ |
| | | path: '/task_agv', |
| | | name: 'task_agv', |
| | | component: () => import('@/views/taskinfo/task_agv.vue') |
| | | }, |
| | | { |
| | | path: '/groupPalle', |
| | | name: 'groupPalle', |
| | | component: () => import('@/views/stock/groupPalle.vue') |
| | | }, |
| | | { |
| | | path: '/stockView', |
| | | name: 'stockView', |
| | | component: () => import('@/views/stock/stockView.vue') |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template>
|
| | | <view-grid
|
| | | ref="grid"
|
| | | :columns="columns"
|
| | | :detail="detail"
|
| | | :editFormFields="editFormFields"
|
| | | :editFormOptions="editFormOptions"
|
| | | :searchFormFields="searchFormFields"
|
| | | :searchFormOptions="searchFormOptions"
|
| | | :table="table"
|
| | | :tableExpand="tableExpand"
|
| | | :extend="extend"
|
| | | >
|
| | | </view-grid>
|
| | | </template>
|
| | |
|
| | | <script>
|
| | | import extend from "@/extension/stock/groupPalle.jsx";
|
| | | import {
|
| | | defineComponent,
|
| | | getCurrentInstance,
|
| | | h,
|
| | | reactive,
|
| | | ref,
|
| | | resolveComponent,
|
| | | } from "vue";
|
| | |
|
| | | const TEXT = {
|
| | | pageName: "åºåä¿¡æ¯",
|
| | | palletCode: "æçç¼å·",
|
| | | stockStatus: "åºåç¶æ",
|
| | | locationCode: "è´§ä½ç¼å·",
|
| | | warehouse: "ä»åº",
|
| | | creator: "å建人",
|
| | | createDate: "å建æ¶é´",
|
| | | modifier: "ä¿®æ¹äºº",
|
| | | modifyDate: "ä¿®æ¹æ¶é´",
|
| | | detailName: "åºåæç»",
|
| | | materielName: "ç©æåç§°",
|
| | | serialNumber: "çµè¯ç ",
|
| | | stockQuantity: "åºåæ°é",
|
| | | status: "ç¶æ",
|
| | | inboundOrderRowNo: "ééå·",
|
| | | detailLoading: "åºåæç»å è½½ä¸...",
|
| | | detailLoadFailed: "åºåæç»å 载失败",
|
| | | detailEmpty: "å½ååºåå¤´ææ æç»æ°æ®",
|
| | | expandPrefix: "æçï¼",
|
| | | expandMiddle: " / ",
|
| | | expandLocation: "è´§ä½ï¼",
|
| | | };
|
| | |
|
| | | export default defineComponent({
|
| | | setup() {
|
| | | const { proxy } = getCurrentInstance();
|
| | | const ElTable = resolveComponent("el-table");
|
| | | const ElTableColumn = resolveComponent("el-table-column");
|
| | |
|
| | | const table = ref({
|
| | | key: "id",
|
| | | footer: "Foots",
|
| | | cnName: TEXT.pageName,
|
| | | name: "stockInfo",
|
| | | url: "/StockInfo/",
|
| | | sortName: "id",
|
| | | });
|
| | |
|
| | | const editFormFields = ref({
|
| | | palletCode: "",
|
| | | locationCode: "",
|
| | | });
|
| | |
|
| | | const editFormOptions = ref([
|
| | | [
|
| | | { field: "palletCode", title: TEXT.palletCode, type: "string" },
|
| | | { field: "locationCode", title: TEXT.locationCode, type: "string" },
|
| | | ],
|
| | | ]);
|
| | |
|
| | | const searchFormFields = ref({
|
| | | palletCode: "",
|
| | | locationCode: "",
|
| | | });
|
| | |
|
| | | const searchFormOptions = ref([
|
| | | [
|
| | | { title: TEXT.palletCode, field: "palletCode", type: "like" },
|
| | | { title: TEXT.locationCode, field: "locationCode", type: "like" },
|
| | | ],
|
| | | ]);
|
| | |
|
| | | const columns = ref([
|
| | | {
|
| | | field: "id",
|
| | | title: "Id",
|
| | | type: "int",
|
| | | width: 90,
|
| | | hidden: true,
|
| | | readonly: true,
|
| | | require: true,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "palletCode",
|
| | | title: TEXT.palletCode,
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "stockStatus",
|
| | | title: TEXT.stockStatus,
|
| | | type: "int",
|
| | | width: 120,
|
| | | align: "left",
|
| | | bind: { key: "stockStatusEmun", data: [] },
|
| | | },
|
| | | // {
|
| | | // field: "locationCode",
|
| | | // title: TEXT.locationCode,
|
| | | // type: "string",
|
| | | // width: 150,
|
| | | // align: "left",
|
| | | // },
|
| | | {
|
| | | field: "warehouseId",
|
| | | title: TEXT.warehouse,
|
| | | type: "select",
|
| | | width: 100,
|
| | | align: "left",
|
| | | bind: { key: "warehouseEnum", data: [] },
|
| | | },
|
| | | {
|
| | | field: "creater",
|
| | | title: TEXT.creator,
|
| | | type: "string",
|
| | | width: 90,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "createDate",
|
| | | title: TEXT.createDate,
|
| | | type: "datetime",
|
| | | width: 160,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "modifier",
|
| | | title: TEXT.modifier,
|
| | | type: "string",
|
| | | width: 100,
|
| | | align: "left",
|
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | field: "modifyDate",
|
| | | title: TEXT.modifyDate,
|
| | | type: "datetime",
|
| | | width: 160,
|
| | | align: "left",
|
| | | hidden: true,
|
| | | },
|
| | | ]);
|
| | |
|
| | | const detail = ref({
|
| | | cnName: "#detailCnName",
|
| | | table: "",
|
| | | columns: [],
|
| | | sortName: "",
|
| | | });
|
| | |
|
| | | const detailState = reactive({
|
| | | rowsMap: {},
|
| | | loadingMap: {},
|
| | | errorMap: {},
|
| | | });
|
| | |
|
| | | const stockStatusOptions = ref([]);
|
| | |
|
| | | const detailColumns = [
|
| | | { field: "materielName", title: TEXT.materielName, minWidth: 160 },
|
| | | { field: "serialNumber", title: TEXT.serialNumber, minWidth: 160 },
|
| | | { field: "stockQuantity", title: TEXT.stockQuantity, minWidth: 120 },
|
| | | { field: "status", title: TEXT.status, minWidth: 120 },
|
| | | { field: "inboundOrderRowNo", title: TEXT.inboundOrderRowNo, minWidth: 120 },
|
| | | ];
|
| | |
|
| | | const normalizeValue = (value) => {
|
| | | return value === null || value === undefined || value === "" ? "--" : value;
|
| | | };
|
| | |
|
| | | const formatStatusText = (value) => {
|
| | | const matched = stockStatusOptions.value.find((item) => `${item.key}` === `${value}`);
|
| | | return matched ? matched.value || matched.label : normalizeValue(value);
|
| | | };
|
| | |
|
| | | const getDetailRows = (stockId) => {
|
| | | return detailState.rowsMap[stockId] || [];
|
| | | };
|
| | |
|
| | | const loadDetailRows = async (row) => {
|
| | | if (!row || !row.id || detailState.loadingMap[row.id]) {
|
| | | return;
|
| | | }
|
| | | if (detailState.rowsMap[row.id]) {
|
| | | return;
|
| | | }
|
| | |
|
| | | detailState.loadingMap[row.id] = true;
|
| | | detailState.errorMap[row.id] = "";
|
| | | try {
|
| | | const result = await proxy.http.post("/api/StockInfoDetail/getPageData", {
|
| | | page: 1,
|
| | | rows: 200,
|
| | | sort: "id",
|
| | | order: "asc",
|
| | | wheres: JSON.stringify([
|
| | | {
|
| | | name: "stockId",
|
| | | value: String(row.id),
|
| | | displayType: "int",
|
| | | },
|
| | | ]),
|
| | | });
|
| | | detailState.rowsMap[row.id] = (result && result.rows) || [];
|
| | | } catch (error) {
|
| | | detailState.rowsMap[row.id] = null;
|
| | | detailState.errorMap[row.id] = error?.message || TEXT.detailLoadFailed;
|
| | | } finally {
|
| | | detailState.loadingMap[row.id] = false;
|
| | | }
|
| | | };
|
| | |
|
| | | const loadStockStatusOptions = async () => {
|
| | | try {
|
| | | const result = await proxy.http.post("/api/Sys_Dictionary/GetVueDictionary", ["stockStatusEmun"]);
|
| | | const matched = (result || []).find((item) => item.dicNo === "stockStatusEmun");
|
| | | stockStatusOptions.value = matched ? matched.data || [] : [];
|
| | | } catch (error) {
|
| | | stockStatusOptions.value = [];
|
| | | }
|
| | | };
|
| | |
|
| | | loadStockStatusOptions();
|
| | |
|
| | | const renderStatus = (row) => {
|
| | | if (detailState.loadingMap[row.id]) {
|
| | | return h("div", { class: "stock-detail-status" }, TEXT.detailLoading);
|
| | | }
|
| | | if (detailState.errorMap[row.id]) {
|
| | | return h(
|
| | | "div",
|
| | | { class: "stock-detail-status stock-detail-status--error" },
|
| | | detailState.errorMap[row.id]
|
| | | );
|
| | | }
|
| | | return null;
|
| | | };
|
| | |
|
| | | const renderDetailTable = (row) => {
|
| | | const statusNode = renderStatus(row);
|
| | | if (statusNode) {
|
| | | return statusNode;
|
| | | }
|
| | |
|
| | | const rows = getDetailRows(row.id);
|
| | | if (!rows.length) {
|
| | | return h("div", { class: "stock-detail-status" }, TEXT.detailEmpty);
|
| | | }
|
| | |
|
| | | return h("div", { class: "stock-detail-table-wrapper" }, [
|
| | | h("div", { class: "stock-detail-toolbar" }, [
|
| | | h("div", { class: "stock-detail-toolbar__left" }, TEXT.detailName),
|
| | | h("div", { class: "stock-detail-toolbar__right" }, [
|
| | | h("span", { class: "stock-detail-count" }, `${rows.length} æ¡`),
|
| | | ]),
|
| | | ]),
|
| | | h(
|
| | | ElTable,
|
| | | {
|
| | | data: rows,
|
| | | border: true,
|
| | | stripe: true,
|
| | | size: "small",
|
| | | class: "stock-detail-el-table",
|
| | | maxHeight: 420,
|
| | | emptyText: TEXT.detailEmpty,
|
| | | },
|
| | | () =>
|
| | | detailColumns.map((column) =>
|
| | | h(ElTableColumn, {
|
| | | key: column.field,
|
| | | prop: column.field,
|
| | | label: column.title,
|
| | | minWidth: column.minWidth,
|
| | | showOverflowTooltip: true,
|
| | | formatter: (detailRow) =>
|
| | | column.field === "status"
|
| | | ? formatStatusText(detailRow[column.field])
|
| | | : normalizeValue(detailRow[column.field]),
|
| | | })
|
| | | )
|
| | | ),
|
| | | ]);
|
| | | };
|
| | |
|
| | | const tableExpand = ref({
|
| | | width: 55,
|
| | | onChange(row, expandedRows) {
|
| | | const isExpanded = expandedRows.some((item) => item.id === row.id);
|
| | | if (isExpanded) {
|
| | | loadDetailRows(row);
|
| | | }
|
| | | },
|
| | | render(render, { row }) {
|
| | | return render("div", { class: "stock-detail-panel" }, [
|
| | | render("div", { class: "stock-detail-header" }, [
|
| | | render("div", { class: "stock-detail-header__main" }, [
|
| | | render("div", { class: "stock-detail-title" }, TEXT.detailName),
|
| | | render(
|
| | | "div",
|
| | | { class: "stock-detail-subtitle" },
|
| | | `${TEXT.expandPrefix}${normalizeValue(row.palletCode)}${TEXT.expandMiddle}${TEXT.expandLocation}${normalizeValue(row.locationCode)}`
|
| | | ),
|
| | | ]),
|
| | | // render("div", { class: "stock-detail-tags" }, [
|
| | | // render("span", { class: "stock-detail-tag" }, normalizeValue(row.palletCode)),
|
| | | // render(
|
| | | // "span",
|
| | | // { class: "stock-detail-tag stock-detail-tag--muted" },
|
| | | // normalizeValue(row.locationCode)
|
| | | // ),
|
| | | // ]),
|
| | | ]),
|
| | | renderDetailTable(row),
|
| | | ]);
|
| | | },
|
| | | });
|
| | |
|
| | | return {
|
| | | table,
|
| | | extend,
|
| | | editFormFields,
|
| | | editFormOptions,
|
| | | searchFormFields,
|
| | | searchFormOptions,
|
| | | columns,
|
| | | detail,
|
| | | tableExpand,
|
| | | };
|
| | | },
|
| | | });
|
| | | </script>
|
| | |
|
| | | <style scoped>
|
| | | .stock-detail-panel {
|
| | | margin: 4px 8px 12px;
|
| | | padding: 14px 16px 16px;
|
| | | background: linear-gradient(180deg, #ffffff 0%, #fafbfc 100%);
|
| | | border: 1px solid #e8edf3;
|
| | | border-radius: 10px;
|
| | | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
|
| | | }
|
| | |
|
| | | .stock-detail-header {
|
| | | display: flex;
|
| | | align-items: flex-start;
|
| | | justify-content: space-between;
|
| | | gap: 12px;
|
| | | margin-bottom: 12px;
|
| | | padding-bottom: 12px;
|
| | | border-bottom: 1px solid #edf1f5;
|
| | | }
|
| | |
|
| | | .stock-detail-header__main {
|
| | | min-width: 0;
|
| | | }
|
| | |
|
| | | .stock-detail-title {
|
| | | margin-bottom: 4px;
|
| | | font-size: 15px;
|
| | | font-weight: 700;
|
| | | color: #303133;
|
| | | }
|
| | |
|
| | | .stock-detail-subtitle {
|
| | | font-size: 13px;
|
| | | color: #606266;
|
| | | line-height: 1.6;
|
| | | }
|
| | |
|
| | | .stock-detail-tags {
|
| | | display: flex;
|
| | | flex-wrap: wrap;
|
| | | justify-content: flex-end;
|
| | | gap: 8px;
|
| | | }
|
| | |
|
| | | .stock-detail-tag {
|
| | | display: inline-flex;
|
| | | align-items: center;
|
| | | height: 28px;
|
| | | padding: 0 10px;
|
| | | color: #1f5eff;
|
| | | background: #edf4ff;
|
| | | border: 1px solid #d8e6ff;
|
| | | border-radius: 999px;
|
| | | font-size: 12px;
|
| | | font-weight: 600;
|
| | | }
|
| | |
|
| | | .stock-detail-tag--muted {
|
| | | color: #4e5969;
|
| | | background: #f4f6f8;
|
| | | border-color: #e5e9ef;
|
| | | }
|
| | |
|
| | | .stock-detail-status {
|
| | | padding: 14px 12px;
|
| | | color: #606266;
|
| | | background: #f8fafc;
|
| | | border: 1px dashed #d9e2ec;
|
| | | border-radius: 8px;
|
| | | }
|
| | |
|
| | | .stock-detail-status--error {
|
| | | color: #f56c6c;
|
| | | background: #fef0f0;
|
| | | border-color: #fde2e2;
|
| | | }
|
| | |
|
| | | .stock-detail-table-wrapper {
|
| | | overflow-x: auto;
|
| | | border: 1px solid #ebeef5;
|
| | | border-radius: 8px;
|
| | | background: #fff;
|
| | | }
|
| | |
|
| | | .stock-detail-toolbar {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: space-between;
|
| | | gap: 12px;
|
| | | padding: 12px 14px;
|
| | | background: #f8fafc;
|
| | | border-bottom: 1px solid #edf1f5;
|
| | | }
|
| | |
|
| | | .stock-detail-toolbar__left {
|
| | | font-size: 13px;
|
| | | font-weight: 600;
|
| | | color: #303133;
|
| | | }
|
| | |
|
| | | .stock-detail-count {
|
| | | display: inline-flex;
|
| | | align-items: center;
|
| | | height: 24px;
|
| | | padding: 0 10px;
|
| | | color: #606266;
|
| | | background: #fff;
|
| | | border: 1px solid #e5e9ef;
|
| | | border-radius: 999px;
|
| | | font-size: 12px;
|
| | | }
|
| | |
|
| | | :deep(.stock-detail-el-table) {
|
| | | border-top: none;
|
| | | }
|
| | |
|
| | | :deep(.stock-detail-el-table .el-table__inner-wrapper::before) {
|
| | | display: none;
|
| | | }
|
| | |
|
| | | :deep(.stock-detail-el-table th.el-table__cell) {
|
| | | background: #f5f7fa;
|
| | | color: #303133;
|
| | | font-weight: 600;
|
| | | }
|
| | |
|
| | | :deep(.stock-detail-el-table td.el-table__cell) {
|
| | | color: #606266;
|
| | | }
|
| | |
|
| | | :deep(.stock-detail-el-table .el-table__body tr:hover > td.el-table__cell) {
|
| | | background: #f0f7ff;
|
| | | }
|
| | | </style>
|
| | |
| | | return `<span style="color: #409EFF; cursor: pointer;">${preview}</span>`; |
| | | } |
| | | }, |
| | | { field: "errorMessage", title: "é误信æ¯", width: 250 }, |
| | | { |
| | | field: "errorMessage", |
| | | title: "é误信æ¯", |
| | | width: 250, |
| | | |
| | | formatter: (row) => { |
| | | if (!row.responseJson) return '-'; |
| | | const preview = row.responseJson.length > 50 |
| | | ? row.responseJson.substring(0, 50) + '...' |
| | | : row.responseJson; |
| | | return `<span style="color: #409EFF; cursor: pointer;">${preview}</span>`; |
| | | } |
| | | }, |
| | | { field: "elapsedMs", title: "èæ¶(ms)", width: 100, sortable: true }, |
| | | { field: "createDate", title: "è°ç¨æ¶é´", width: 160, sortable: true }, |
| | | { field: "creator", title: "æä½äºº", width: 100 } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | |
|
| | | <template>
|
| | | <view-grid
|
| | | ref="grid"
|
| | | :columns="columns"
|
| | | :detail="detail"
|
| | | :editFormFields="editFormFields"
|
| | | :editFormOptions="editFormOptions"
|
| | | :searchFormFields="searchFormFields"
|
| | | :searchFormOptions="searchFormOptions"
|
| | | :table="table"
|
| | | :extend="extend"
|
| | | >
|
| | | </view-grid>
|
| | | </template>
|
| | | <script>
|
| | | import extend from "@/extension/taskinfo/agvTask.jsx";
|
| | | import { ref, defineComponent } from "vue";
|
| | | export default defineComponent({
|
| | | setup() {
|
| | | const table = ref({
|
| | | key: "taskId",
|
| | | footer: "Foots",
|
| | | cnName: "ä»»å¡ä¿¡æ¯",
|
| | | name: "task",
|
| | | url: "/Task/",
|
| | | sortName: "CreateDate",
|
| | | });
|
| | | const editFormFields = ref({});
|
| | | const editFormOptions = ref([]);
|
| | | const searchFormFields = ref({
|
| | | taskNum: "",
|
| | | palletCode: "",
|
| | | roadway: "",
|
| | | taskStatus: "",
|
| | | taskType: "",
|
| | | sourceAddress: "",
|
| | | targetAddress: "",
|
| | | currentAddress: "",
|
| | | nextAddress: "",
|
| | | creater: "",
|
| | | createDate: "",
|
| | | });
|
| | | const searchFormOptions = ref([
|
| | | [
|
| | | { title: "ä»»å¡å·", field: "taskNum", type: "int" },
|
| | | { title: "æçç¼å·", field: "palletCode", type: "like" },
|
| | | { title: "å建人", field: "creater", type: "like" },
|
| | | ],
|
| | | [
|
| | | { title: "ä»»å¡ç±»å",field: "taskType",type: "selectList",dataKey: "taskTypeEnum",data: [],},
|
| | | { title: "ä»»å¡ç¶æ",field: "taskStatus",type: "selectList",dataKey: "taskStatusEnum",data: [],},
|
| | | { title: "å··éå·", field: "roadway", type: "like" },
|
| | | ],
|
| | | [
|
| | | { title: "èµ·å§å°å", field: "sourceAddress", type: "like" },
|
| | | { title: "ç®æ å°å", field: "targetAddress", type: "like" },
|
| | | { title: "å建æ¶é´", field: "createDate", type: "datetime" },
|
| | | ],
|
| | | ]);
|
| | | const columns = ref([
|
| | | {
|
| | | field: "taskId",
|
| | | title: "taskId",
|
| | | type: "int",
|
| | | width: 90,
|
| | | hidden: true,
|
| | | readonly: true,
|
| | | require: true,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "taskNum",
|
| | | title: "ä»»å¡å·",
|
| | | type: "int",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "palletCode",
|
| | | title: "æçç¼å·",
|
| | | type: "string",
|
| | | width: 160,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "roadway",
|
| | | title: "å··éå·",
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "taskType",
|
| | | title: "ä»»å¡ç±»å",
|
| | | type: "int",
|
| | | width: 120,
|
| | | align: "left",
|
| | | bind: { key: "taskTypeEnum", data: [] },
|
| | | },
|
| | | {
|
| | | field: "taskStatus",
|
| | | title: "ä»»å¡ç¶æ",
|
| | | type: "int",
|
| | | width: 150,
|
| | | align: "left",
|
| | | bind: { key: "taskStatusEnum", data: [] },
|
| | | },
|
| | | {
|
| | | field: "sourceAddress",
|
| | | title: "èµ·å§å°å",
|
| | | type: "int",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "targetAddress",
|
| | | title: "ç®æ å°å",
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "currentAddress",
|
| | | title: "å½åä½ç½®",
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "nextAddress",
|
| | | title: "ä¸ä¸ä½ç½®",
|
| | | type: "string",
|
| | | width: 120,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "exceptionMessage",
|
| | | title: "å¼å¸¸ä¿¡æ¯",
|
| | | type: "string",
|
| | | width: 90,
|
| | | align: "left",
|
| | | },
|
| | | // {
|
| | | // field: "grade",
|
| | | // title: "ä¼å
级",
|
| | | // type: "int",
|
| | | // width: 80,
|
| | | // align: "left",
|
| | | // },
|
| | | {
|
| | | field: "depth",
|
| | | title: "深度",
|
| | | type: "int",
|
| | | width: 80,
|
| | | align: "left",
|
| | | bind: { key: "locationDepth", data: [] },
|
| | | },
|
| | | {
|
| | | field: "dispatchertime",
|
| | | title: "ä»»å¡ä¸åæ¶é´",
|
| | | type: "datetime",
|
| | | width: 160,
|
| | | align: "left",
|
| | | // hidden:true,
|
| | | },
|
| | | {
|
| | | field: "wMSId",
|
| | | title: "WMSä»»å¡ä¸»é®",
|
| | | type: "int",
|
| | | width: 120,
|
| | | align: "left",
|
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | field: "creater",
|
| | | title: "å建人",
|
| | | type: "string",
|
| | | width: 90,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "createDate",
|
| | | title: "å建æ¶é´",
|
| | | type: "datetime",
|
| | | width: 160,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "modifier",
|
| | | title: "ä¿®æ¹äºº",
|
| | | type: "string",
|
| | | width: 100,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "modifyDate",
|
| | | title: "ä¿®æ¹æ¶é´",
|
| | | type: "datetime",
|
| | | width: 160,
|
| | | align: "left",
|
| | | },
|
| | | {
|
| | | field: "remark",
|
| | | title: "夿³¨",
|
| | | type: "string",
|
| | | width: 100,
|
| | | align: "left",
|
| | | hidden: true,
|
| | | },
|
| | | ]);
|
| | | const detail = ref({
|
| | | cnName: "#detailCnName",
|
| | | table: "",
|
| | | columns: [],
|
| | | sortName: "",
|
| | | });
|
| | | return {
|
| | | table,
|
| | | extend,
|
| | | editFormFields,
|
| | | editFormOptions,
|
| | | searchFormFields,
|
| | | searchFormOptions,
|
| | | columns,
|
| | | detail,
|
| | | };
|
| | | },
|
| | | });
|
| | | </script>
|
| | | |
| | |
| | | type: "string", |
| | | width: 120, |
| | | align: "left", |
| | | },{ |
| | | field: "operateType", |
| | | title: "æä½ç±»å", |
| | | type: "string", |
| | | width: 120, |
| | | align: "left" |
| | | }, |
| | | { |
| | | field: "taskType", |
| | |
| | | int ExpMinutes = AppSettings.Get("ExpMinutes").ObjToInt(); |
| | | if ((expDate.GetValueOrDefault() - DateTime.Now).TotalMinutes < ExpMinutes / 3 && context.HttpContext.Request.Path != ReplaceTokenPath) |
| | | { |
| | | context.HttpContext.Response.Headers.Add("widesea_exp", "1"); |
| | | context.HttpContext.Response.Headers.Append("widesea_exp", "1"); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | public async Task InvokeAsync(HttpContext context) |
| | | { |
| | | context.Response.Headers.Add("Access-Control-Expose-Headers", "widesea_exp"); |
| | | context.Response.Headers.Append("Access-Control-Expose-Headers", "widesea_exp"); |
| | | await _next(context); |
| | | } |
| | | } |
| | |
| | | public string ApiType { get; set; } |
| | | |
| | | /// <summary> |
| | | /// æçå· |
| | | /// </summary> |
| | | public string PalletCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 请æ±JSON |
| | | /// </summary> |
| | | public string RequestJson { get; set; } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Core; |
| | | |
| | | namespace WIDESEA_IBasicService |
| | | { |
| | | /// <summary> |
| | | /// MES弿¥ä¸ä¼ è¾
å©æå¡ - å°è£
Task.Run + ç¶ææ´æ° + æ¥å¿è®°å½çç»ä¸æ¨¡å¼ |
| | | /// </summary> |
| | | public interface IMesUploadHelper : IDependency |
| | | { |
| | | /// <summary> |
| | | /// 以fire-and-forgetæ¹å¼å¼æ¥æ§è¡MESè°ç¨ï¼èªå¨æ´æ°ä¸ä¼ ç¶æå¹¶è®°å½æ¥å¿ |
| | | /// </summary> |
| | | /// <param name="palletCode">æçå·</param> |
| | | /// <param name="successStatus">æåæ¶çç¶ææä¸¾å¼ï¼å¥æ°=æåï¼å¶æ°=失败ï¼</param> |
| | | /// <param name="apiType">MESæ¥å£ç±»ååç§°</param> |
| | | /// <param name="requestJson">请æ±JSONï¼ç¨äºæ¥å¿è®°å½ï¼</param> |
| | | /// <param name="mesCall">MESè°ç¨å§æï¼è¿å(æ¯å¦æå, ååºJSON, éè¯¯æ¶æ¯)</param> |
| | | /// <param name="creator">æä½äºº</param> |
| | | void FireAndForget( |
| | | string palletCode, |
| | | MesUploadStatusEnum successStatus, |
| | | string apiType, |
| | | string requestJson, |
| | | Func<(bool isSuccess, string responseJson, string errorMessage)> mesCall, |
| | | string creator = "System"); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | using System.Diagnostics; |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_DTO.MES; |
| | | using WIDESEA_IStockService; |
| | | using WIDESEA_IBasicService; |
| | | |
| | | namespace WIDESEA_StockService |
| | | { |
| | | /// <summary> |
| | | /// MES弿¥ä¸ä¼ è¾
婿å¡å®ç° |
| | | /// </summary> |
| | | public class MesUploadHelper : IMesUploadHelper |
| | | { |
| | | private readonly IStockInfoService _stockInfoService; |
| | | private readonly IMesLogService _mesLogService; |
| | | |
| | | /// <summary> |
| | | /// æé 彿° |
| | | /// </summary> |
| | | /// <param name="stockInfoService">åºåä¿¡æ¯æå¡</param> |
| | | /// <param name="mesLogService">MESæ¥å¿æå¡</param> |
| | | public MesUploadHelper(IStockInfoService stockInfoService, IMesLogService mesLogService) |
| | | { |
| | | _stockInfoService = stockInfoService; |
| | | _mesLogService = mesLogService; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 以fire-and-forgetæ¹å¼å¼æ¥æ§è¡MESè°ç¨ï¼èªå¨æ´æ°ä¸ä¼ ç¶æå¹¶è®°å½æ¥å¿ |
| | | /// </summary> |
| | | public void FireAndForget( |
| | | string palletCode, |
| | | MesUploadStatusEnum successStatus, |
| | | string apiType, |
| | | string requestJson, |
| | | Func<(bool isSuccess, string responseJson, string errorMessage)> mesCall, |
| | | string creator = "System") |
| | | { |
| | | _ = Task.Run(async () => |
| | | { |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | try |
| | | { |
| | | var (isSuccess, responseJson, errorMessage) = mesCall(); |
| | | stopwatch.Stop(); |
| | | |
| | | // 奿°=æåï¼å¶æ°=失败 |
| | | int status = isSuccess ? (int)successStatus : (int)successStatus + 1; |
| | | await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status); |
| | | |
| | | await LogAsync(palletCode, apiType, requestJson, responseJson, |
| | | stopwatch.ElapsedMilliseconds, isSuccess, errorMessage, creator); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | int status = (int)successStatus + 1; |
| | | await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, status); |
| | | |
| | | await LogAsync(palletCode, apiType, requestJson, "", |
| | | stopwatch.ElapsedMilliseconds, false, ex.Message, creator); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è®°å½MESæ¥å£è°ç¨æ¥å¿ |
| | | /// </summary> |
| | | private async Task LogAsync(string palletCode, string apiType, string requestJson, |
| | | string responseJson, long elapsedMs, bool isSuccess, string errorMessage, string creator) |
| | | { |
| | | try |
| | | { |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | PalletCode = palletCode, |
| | | ApiType = apiType, |
| | | RequestJson = requestJson, |
| | | ResponseJson = responseJson, |
| | | IsSuccess = isSuccess, |
| | | ErrorMessage = errorMessage, |
| | | ElapsedMs = (int)elapsedMs, |
| | | Creator = creator |
| | | }); |
| | | } |
| | | catch |
| | | { |
| | | // æ¥å¿è®°å½å¤±è´¥ä¸å½±å主æµç¨ |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | try |
| | | { |
| | | var stockInfo = await BaseDal.QueryDataFirstAsync(x => x.PalletCode == palletCode); |
| | | var stockInfo = await BaseDal.QueryFirstAsync(x => x.PalletCode == palletCode); |
| | | if (stockInfo == null) |
| | | return false; |
| | | |
| | |
| | | using Newtonsoft.Json; |
| | | using SqlSugar; |
| | | using System.Diagnostics; |
| | | using WIDESEA_Common.Constants; |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Core; |
| | |
| | | public IMesService _mesService { get; } |
| | | |
| | | private readonly IMesLogService _mesLogService; |
| | | private readonly IMesUploadHelper _mesUploadHelper; |
| | | |
| | | /// <summary> |
| | | /// æé 彿° |
| | |
| | | /// <param name="stockInfoService">åºåä¿¡æ¯æå¡</param> |
| | | /// <param name="stockInfoDetail_HtyService">åºåæç»å岿å¡</param> |
| | | /// <param name="stockInfo_HtyService">åºåå岿å¡</param> |
| | | /// <param name="mesUploadHelper">MES弿¥ä¸ä¼ è¾
婿å¡</param> |
| | | public StockService( |
| | | IStockInfoDetailService stockInfoDetailService, |
| | | IStockInfoService stockInfoService, |
| | |
| | | IMesService mesService, |
| | | IWarehouseService warehouseService, |
| | | ISqlSugarClient sqlSugarClient, |
| | | IMesLogService mesLogService) |
| | | IMesLogService mesLogService, |
| | | IMesUploadHelper mesUploadHelper) |
| | | { |
| | | StockInfoDetailService = stockInfoDetailService; |
| | | StockInfoService = stockInfoService; |
| | |
| | | _warehouseService = warehouseService; |
| | | SqlSugarClient = sqlSugarClient; |
| | | _mesLogService = mesLogService; |
| | | _mesUploadHelper = mesUploadHelper; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | } |
| | | } |
| | | |
| | | // 3. è°ç¨MESè§£ç» |
| | | // 3. Fire-and-forget弿¥è°ç¨MESè§£ç» |
| | | var unbindRequest = new UnBindContainerRequest |
| | | { |
| | | EquipmentCode = equipmentCode, |
| | |
| | | ContainCode = palletCode, |
| | | SfcList = sfcList |
| | | }; |
| | | var unbindResult = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.UnBindContainer(unbindRequest) |
| | | : _mesService.UnBindContainer(unbindRequest, token); |
| | | if (unbindResult == null || unbindResult.Data == null || !unbindResult.Data.IsSuccess) |
| | | { |
| | | return content.Error($"MESè§£ç»å¤±è´¥: {unbindResult?.Data?.Msg ?? unbindResult?.ErrorMessage ?? "æªç¥é误"}"); |
| | | } |
| | | string requestJson = unbindRequest.ToJson(); |
| | | var localToken = token; |
| | | |
| | | _mesUploadHelper.FireAndForget( |
| | | palletCode, |
| | | MesUploadStatusEnum.æçä¸ä¼ æå, |
| | | "UnBindContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(localToken) |
| | | ? _mesService.UnBindContainer(unbindRequest) |
| | | : _mesService.UnBindContainer(unbindRequest, localToken); |
| | | return ( |
| | | result?.Data?.IsSuccess ?? false, |
| | | System.Text.Json.JsonSerializer.Serialize(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }); |
| | | |
| | | // 4. å é¤ä¸´æ¶è¡¨è®°å½ |
| | | await SqlSugarClient.Deleteable<Dt_SplitTemp>().Where(t => t.PalletCode == palletCode).ExecuteCommandAsync(); |
| | |
| | | public async Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName) |
| | | { |
| | | WebResponseContent content = new WebResponseContent(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | try |
| | | { |
| | | if (string.IsNullOrWhiteSpace(palletCode)) |
| | |
| | | }).ToList() |
| | | }; |
| | | string requestJson = bindRequest.ToJson(); |
| | | var bindResult = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.BindContainer(bindRequest) |
| | | : _mesService.BindContainer(bindRequest, token); |
| | | stopwatch.Stop(); |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "BindContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(bindResult), |
| | | IsSuccess = bindResult.IsSuccess, |
| | | ErrorMessage = bindResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = "systeam" |
| | | }); |
| | | if (bindResult == null || bindResult.Data == null || !bindResult.Data.IsSuccess) |
| | | { |
| | | return content.Error($"MESç»å®å¤±è´¥: {bindResult?.Data?.Msg ?? bindResult?.ErrorMessage ?? "æªç¥é误"}"); |
| | | } |
| | | var localToken = token; |
| | | |
| | | // 3. Fire-and-forget弿¥è°ç¨MESç»å® |
| | | _mesUploadHelper.FireAndForget( |
| | | palletCode, |
| | | MesUploadStatusEnum.ç»çä¸ä¼ æå, |
| | | "BindContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(localToken) |
| | | ? _mesService.BindContainer(bindRequest) |
| | | : _mesService.BindContainer(bindRequest, localToken); |
| | | return ( |
| | | result?.Data?.IsSuccess ?? false, |
| | | System.Text.Json.JsonSerializer.Serialize(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }); |
| | | |
| | | return content.OK("æ¹éç»ç确认æå"); |
| | | } |
| | |
| | | using WIDESEA_Core.Helper; |
| | | using WIDESEA_DTO.GradingMachine; |
| | | using WIDESEA_DTO.MES; |
| | | using WIDESEA_DTO.Stock; |
| | | using WIDESEA_DTO.Task; |
| | | using Newtonsoft.Json; |
| | | using System.Diagnostics; |
| | | using WIDESEA_IBasicService; |
| | | using WIDESEA_IRecordService; |
| | | using WIDESEA_IStockService; |
| | |
| | | private readonly IRecordService _recordService; |
| | | private readonly IMESDeviceConfigService _mesDeviceConfigService; |
| | | private readonly IMesLogService _mesLogService; |
| | | private readonly IMesUploadHelper _mesUploadHelper; |
| | | |
| | | public IRepository<Dt_Task> Repository => BaseDal; |
| | | |
| | |
| | | IUnitOfWorkManage unitOfWorkManage, |
| | | IRecordService recordService, |
| | | IMESDeviceConfigService mesDeviceConfigService, |
| | | IMesLogService mesLogService) : base(BaseDal) |
| | | IMesLogService mesLogService, |
| | | IMesUploadHelper mesUploadHelper) : base(BaseDal) |
| | | { |
| | | _mapper = mapper; |
| | | _stockInfoService = stockInfoService; |
| | |
| | | _recordService = recordService; |
| | | _mesDeviceConfigService = mesDeviceConfigService; |
| | | _mesLogService = mesLogService; |
| | | _mesUploadHelper = mesUploadHelper; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | return DetermineTargetAddress(roadway, addressMap); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 弿¥æ§è¡MESä¸ä¼ - ä¸é»å¡ä¸»ä¸å¡é»è¾ |
| | | /// </summary> |
| | | /// <param name="palletCode">æçå·</param> |
| | | /// <param name="successStatus">æåæ¶çç¶ææä¸¾å¼ï¼å¥æ°ï¼</param> |
| | | /// <param name="uploadFunc">å
·ä½çMESè°ç¨å½æ°</param> |
| | | private async Task MesUploadAsync(string palletCode, MesUploadStatusEnum successStatus, Func<Task<HttpResponseResult<MesResponse>>> uploadFunc) |
| | | { |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | string requestJson = ""; |
| | | string responseJson = ""; |
| | | bool isSuccess = false; |
| | | string errorMessage = ""; |
| | | |
| | | try |
| | | { |
| | | // è°ç¨MES |
| | | var result = await uploadFunc(); |
| | | |
| | | stopwatch.Stop(); |
| | | isSuccess = result?.Data?.IsSuccess ?? false; |
| | | errorMessage = result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误"; |
| | | responseJson = JsonConvert.SerializeObject(result); |
| | | |
| | | // æ ¹æ®æå/失败å³å®ç¶æå¼ï¼å¥æ°=æåï¼å¶æ°=失败 |
| | | var uploadStatus = isSuccess ? (int)successStatus : (int)successStatus + 1; |
| | | |
| | | // æ´æ°åºåè¡¨ç¶æï¼ä¸çå¾
ï¼ |
| | | _ = _stockInfoService.UpdateMesUploadStatusAsync(palletCode, uploadStatus); |
| | | |
| | | // è®°å½MESæ¥å¿ |
| | | await LogMesCallAsync(palletCode, successStatus.ToString(), requestJson, responseJson, |
| | | stopwatch.ElapsedMilliseconds, isSuccess ? "æå" : "失败", errorMessage); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | errorMessage = ex.Message; |
| | | |
| | | // æ´æ°ç¶æä¸ºå¤±è´¥ï¼successStatus+1 å³ä¸ºå¤±è´¥ç¶æï¼ |
| | | var uploadStatus = (int)successStatus + 1; |
| | | _ = _stockInfoService.UpdateMesUploadStatusAsync(palletCode, uploadStatus); |
| | | |
| | | // è®°å½å¼å¸¸æ¥å¿ |
| | | await LogMesCallAsync(palletCode, successStatus.ToString(), requestJson, responseJson, |
| | | stopwatch.ElapsedMilliseconds, "失败", errorMessage); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// è®°å½MESæ¥å£è°ç¨æ¥å¿ |
| | | /// </summary> |
| | | private async Task LogMesCallAsync(string palletCode, string apiType, string requestJson, |
| | | string responseJson, long durationMs, string status, string errorMessage) |
| | | { |
| | | try |
| | | { |
| | | var mesLog = new MesApiLogDto |
| | | { |
| | | PalletCode = palletCode, |
| | | ApiType = apiType, |
| | | RequestJson = requestJson, |
| | | ResponseJson = responseJson, |
| | | IsSuccess = status == "æå", |
| | | ErrorMessage = errorMessage, |
| | | ElapsedMs = (int)durationMs, |
| | | Creator = "System" |
| | | }; |
| | | await _mesLogService.LogAsync(mesLog); |
| | | } |
| | | catch |
| | | { |
| | | // æ¥å¿è®°å½å¤±è´¥ä¸å½±å主æµç¨ |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | using Microsoft.AspNetCore.Http.HttpResults; |
| | | using Newtonsoft.Json; |
| | | using System.Diagnostics; |
| | | using WIDESEA_Common.Constants; |
| | | using WIDESEA_Common.LocationEnum; |
| | | using WIDESEA_Common.StockEnum; |
| | |
| | | /// </summary> |
| | | public async Task<WebResponseContent> InboundFinishTaskAsync(CreateTaskDto taskDto) |
| | | { |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | try |
| | | { |
| | | var task = await BaseDal.QueryFirstAsync(s => s.PalletCode == taskDto.PalletCode); |
| | |
| | | } |
| | | else |
| | | { |
| | | |
| | | |
| | | // 夿æ¯ä¸æ¯æå·åºä»»å¡ |
| | | if (taskDto.WarehouseId == (int)WarehouseEnum.FJ1 || taskDto.WarehouseId == (int)WarehouseEnum.ZJ1) |
| | | { |
| | |
| | | return WebResponseContent.Instance.Error("ä»»å¡å®æå¤±è´¥"); |
| | | |
| | | // æ ¹æ®åºåRemarkéæ©é置设å¤ï¼æ¥MES卿åè¯ |
| | | //string deviceName = stockInfo.Remark == "GW_1" ? "髿¸©éç½®1" |
| | | // : stockInfo.Remark == "GW_2" ? "髿¸©éç½®2" |
| | | // : "常温éç½®1"; |
| | | //var mesConfig = _mesDeviceConfigService.GetByDeviceName(deviceName); |
| | | //string equipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE; |
| | | //string resourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE; |
| | | //string token = mesConfig?.Token; |
| | | string deviceName = stockInfo.Remark == "GW_1" ? "髿¸©éç½®1" |
| | | : stockInfo.Remark == "GW_2" ? "髿¸©éç½®2" |
| | | : "常温éç½®1"; |
| | | var mesConfig = _mesDeviceConfigService.GetByDeviceName(deviceName); |
| | | string equipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE; |
| | | string resourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE; |
| | | string token = mesConfig?.Token; |
| | | |
| | | // è°ç¨MESæçè¿ç« |
| | | //var inboundRequest = new InboundInContainerRequest |
| | | //{ |
| | | // EquipmentCode = equipmentCode, |
| | | // ResourceCode = resourceCode, |
| | | // LocalTime = DateTime.Now, |
| | | // ContainerCode = taskDto.PalletCode |
| | | //}; |
| | | //string requestJson = inboundRequest.ToJson(); |
| | | //var inboundResult = string.IsNullOrWhiteSpace(token) |
| | | // ? _mesService.InboundInContainer(inboundRequest) |
| | | // : _mesService.InboundInContainer(inboundRequest, token); |
| | | //stopwatch.Stop(); |
| | | //await _mesLogService.LogAsync(new MesApiLogDto |
| | | //{ |
| | | // ApiType = "InboundInContainer", |
| | | // RequestJson = requestJson, |
| | | // ResponseJson = JsonConvert.SerializeObject(inboundResult), |
| | | // IsSuccess = inboundResult.IsSuccess, |
| | | // ErrorMessage = inboundResult.ErrorMessage, |
| | | // ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | // Creator = "systeam" |
| | | //}); |
| | | //if (inboundResult == null || inboundResult.Data == null || !inboundResult.Data.IsSuccess) |
| | | //{ |
| | | // return content.Error($"ä»»å¡å®æå¤±è´¥ï¼MESè¿ç«å¤±è´¥: {inboundResult?.Data?.Msg ?? inboundResult?.ErrorMessage ?? "æªç¥é误"}"); |
| | | //} |
| | | // 弿¥è°ç¨MESæçè¿ç«ï¼ä¸é»å¡ä¸»é»è¾ |
| | | var inboundRequest = new InboundInContainerRequest |
| | | { |
| | | EquipmentCode = equipmentCode, |
| | | ResourceCode = resourceCode, |
| | | LocalTime = DateTime.Now, |
| | | ContainerCode = taskDto.PalletCode |
| | | }; |
| | | string requestJson = inboundRequest.ToJson(); |
| | | var palletCode = taskDto.PalletCode; |
| | | |
| | | _mesUploadHelper.FireAndForget( |
| | | palletCode, |
| | | MesUploadStatusEnum.è¿ç«ä¸ä¼ æå, |
| | | "InboundInContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.InboundInContainer(inboundRequest) |
| | | : _mesService.InboundInContainer(inboundRequest, token); |
| | | return ( |
| | | result?.Data?.IsSuccess ?? false, |
| | | JsonConvert.SerializeObject(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }); |
| | | |
| | | return await CompleteTaskAsync(task, "å
¥åºå®æ"); |
| | | }); |
| | | } |
| | |
| | | using System.Diagnostics; |
| | | using WIDESEA_Common.Constants; |
| | | using WIDESEA_Common.LocationEnum; |
| | | using WIDESEA_Common.StockEnum; |
| | |
| | | /// </summary> |
| | | public async Task<WebResponseContent> OutboundFinishTaskAsync(CreateTaskDto taskDto) |
| | | { |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | try |
| | | { |
| | | var task = await BaseDal.QueryFirstAsync(s => s.PalletCode == taskDto.PalletCode); |
| | |
| | | LocalTime = DateTime.Now, |
| | | ContainerCode = taskDto.PalletCode |
| | | }; |
| | | string palletCode = taskDto.PalletCode; |
| | | string requestJson = outboundRequest.ToJson(); |
| | | var outboundResult = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.OutboundInContainer(outboundRequest) |
| | | : _mesService.OutboundInContainer(outboundRequest, token); |
| | | stopwatch.Stop(); |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "UnbindContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(outboundResult), |
| | | IsSuccess = outboundResult.IsSuccess, |
| | | ErrorMessage = outboundResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = "systeam" |
| | | }); |
| | | if (outboundResult == null || outboundResult.Data == null || !outboundResult.Data.IsSuccess) |
| | | { |
| | | return content.Error($"åºåºå®æå¤±è´¥ï¼MESåºç«å¤±è´¥: {outboundResult?.Data?.Msg ?? outboundResult?.ErrorMessage ?? "æªç¥é误"}"); |
| | | } |
| | | |
| | | // Fire-and-forget: 弿¥æ§è¡MESåºç«ï¼ä¸é»å¡ä¸»ä¸å¡é»è¾ |
| | | _mesUploadHelper.FireAndForget( |
| | | palletCode, |
| | | MesUploadStatusEnum.åºç«ä¸ä¼ æå, |
| | | "OutboundInContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.OutboundInContainer(outboundRequest) |
| | | : _mesService.OutboundInContainer(outboundRequest, token); |
| | | return ( |
| | | result?.Data?.IsSuccess ?? false, |
| | | Newtonsoft.Json.JsonConvert.SerializeObject(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }); |
| | | |
| | | var completeResult = await CompleteTaskAsync(task, "åºåºå®æ"); |
| | | if (!completeResult.Status) |
| | |
| | | using WIDESEA_IBasicService; |
| | | using WIDESEA_ISystemService; |
| | | using WIDESEA_Model.Models; |
| | | using WIDESEA_Common.Constants; |
| | | using WIDESEA_Common.StockEnum; |
| | | using System.Diagnostics; |
| | | |
| | | namespace WIDESEA_WMSServer.Controllers.Stock |
| | | { |
| | |
| | | [ApiController] |
| | | public class StockInfoController : ApiBaseController<IStockInfoService, Dt_StockInfo> |
| | | { |
| | | private readonly IMesLogService _mesLogService; |
| | | private readonly IMesService _mesService; |
| | | private readonly IMESDeviceConfigService _mesDeviceConfigService; |
| | | private readonly ISys_DictionaryService _sysDictionaryService; |
| | | private readonly IMesUploadHelper _mesUploadHelper; |
| | | |
| | | public StockInfoController( |
| | | IStockInfoService service, |
| | | IMesLogService mesLogService, |
| | | IMesService mesService, |
| | | ISys_DictionaryService sysDictionaryService) : base(service) |
| | | IMESDeviceConfigService mesDeviceConfigService, |
| | | ISys_DictionaryService sysDictionaryService, |
| | | IMesUploadHelper mesUploadHelper) : base(service) |
| | | { |
| | | _mesLogService = mesLogService; |
| | | _mesService = mesService; |
| | | _mesDeviceConfigService = mesDeviceConfigService; |
| | | _sysDictionaryService = sysDictionaryService; |
| | | _mesUploadHelper = mesUploadHelper; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | public async Task<WebResponseContent> InboundInContainer([FromBody] InboundInContainerRequestDto dto) |
| | | { |
| | | var response = new WebResponseContent(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | |
| | | try |
| | | { |
| | |
| | | return response.Error($"å½ååºåç¶æä¸å
许è¿ç«æä½ï¼å½åç¶æï¼{stockInfo.StockStatus}"); |
| | | } |
| | | |
| | | // 4. æé MESè¯·æ± |
| | | // 4. 卿è·åMESåè¯ |
| | | string deviceName = stockInfo.Remark == "GW_1" ? "髿¸©éç½®1" |
| | | : stockInfo.Remark == "GW_2" ? "髿¸©éç½®2" |
| | | : "常温éç½®1"; |
| | | var mesConfig = _mesDeviceConfigService.GetByDeviceName(deviceName); |
| | | |
| | | var mesRequest = new InboundInContainerRequest |
| | | { |
| | | EquipmentCode = "STK-GROUP-001", |
| | | ResourceCode = "STK-GROUP-001", |
| | | EquipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE, |
| | | ResourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE, |
| | | LocalTime = DateTime.Now, |
| | | ContainerCode = dto.PalletCode |
| | | }; |
| | | |
| | | string token = mesConfig?.Token; |
| | | string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest); |
| | | string palletCode = stockInfo.PalletCode; |
| | | |
| | | // 5. è°ç¨MESæ¥å£ï¼åæ¥æ¹æ³ï¼ |
| | | var mesResult = _mesService.InboundInContainer(mesRequest); |
| | | stopwatch.Stop(); |
| | | // 5. 弿¥æ§è¡MESè°ç¨ï¼fire-and-forgetï¼ |
| | | _mesUploadHelper.FireAndForget( |
| | | palletCode, |
| | | MesUploadStatusEnum.è¿ç«ä¸ä¼ æå, |
| | | "InboundInContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.InboundInContainer(mesRequest) |
| | | : _mesService.InboundInContainer(mesRequest, token); |
| | | return ( |
| | | result.Data?.IsSuccess ?? false, |
| | | System.Text.Json.JsonSerializer.Serialize(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }, |
| | | App.User.UserName); |
| | | |
| | | // 6. è®°å½æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "InboundInContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(mesResult), |
| | | IsSuccess = mesResult.IsSuccess, |
| | | ErrorMessage = mesResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | // 7. è¿åç»æ |
| | | if (mesResult.IsSuccess) |
| | | { |
| | | return response.OK("æçè¿ç«æå"); |
| | | } |
| | | else |
| | | { |
| | | return response.Error($"MESæ¥å£è°ç¨å¤±è´¥: {mesResult.ErrorMessage}"); |
| | | } |
| | | // 6. ç«å³è¿åæå |
| | | return response.OK("æçè¿ç«æå"); |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | |
| | | // è®°å½é误æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "InboundInContainer", |
| | | IsSuccess = false, |
| | | ErrorMessage = ex.Message, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | return response.Error($"æçè¿ç«å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | |
| | | public async Task<WebResponseContent> OutboundInContainer([FromBody] OutboundInContainerRequestDto dto) |
| | | { |
| | | var response = new WebResponseContent(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | |
| | | try |
| | | { |
| | |
| | | return response.Error($"å½ååºåç¶æä¸å
许åºç«æä½ï¼å½åç¶æï¼{stockInfo.StockStatus}"); |
| | | } |
| | | |
| | | // 4. æé MESè¯·æ± |
| | | // 4. 卿è·åMESåè¯ |
| | | string deviceName = stockInfo.Remark == "GW_1" ? "髿¸©éç½®1" |
| | | : stockInfo.Remark == "GW_2" ? "髿¸©éç½®2" |
| | | : "常温éç½®1"; |
| | | var mesConfig = _mesDeviceConfigService.GetByDeviceName(deviceName); |
| | | |
| | | var mesRequest = new OutboundInContainerRequest |
| | | { |
| | | EquipmentCode = "STK-GROUP-001", |
| | | ResourceCode = "STK-GROUP-001", |
| | | EquipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE, |
| | | ResourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE, |
| | | LocalTime = DateTime.Now, |
| | | ContainerCode = dto.PalletCode, |
| | | ParamList = dto.ParamList?.Select(p => new ParamItem |
| | |
| | | }).ToList() |
| | | }; |
| | | |
| | | string token = mesConfig?.Token; |
| | | string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest); |
| | | string palletCode = stockInfo.PalletCode; |
| | | |
| | | // 5. è°ç¨MESæ¥å£ï¼åæ¥æ¹æ³ï¼ |
| | | var mesResult = _mesService.OutboundInContainer(mesRequest); |
| | | stopwatch.Stop(); |
| | | // 5. 弿¥æ§è¡MESè°ç¨ï¼fire-and-forgetï¼ |
| | | _mesUploadHelper.FireAndForget( |
| | | palletCode, |
| | | MesUploadStatusEnum.åºç«ä¸ä¼ æå, |
| | | "OutboundInContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.OutboundInContainer(mesRequest) |
| | | : _mesService.OutboundInContainer(mesRequest, token); |
| | | return ( |
| | | result?.Data?.IsSuccess ?? false, |
| | | System.Text.Json.JsonSerializer.Serialize(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }, |
| | | App.User.UserName); |
| | | |
| | | // 6. è®°å½æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "OutboundInContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(mesResult), |
| | | IsSuccess = mesResult.IsSuccess, |
| | | ErrorMessage = mesResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | // 7. è¿åç»æ |
| | | if (mesResult.IsSuccess) |
| | | { |
| | | return response.OK("æçåºç«æå"); |
| | | } |
| | | else |
| | | { |
| | | return response.Error($"MESæ¥å£è°ç¨å¤±è´¥: {mesResult.ErrorMessage}"); |
| | | } |
| | | // 6. ç«å³è¿åæå |
| | | return response.OK("æçåºç«æå"); |
| | | } |
| | | catch (System.Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | |
| | | // è®°å½é误æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "OutboundInContainer", |
| | | IsSuccess = false, |
| | | ErrorMessage = ex.Message, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | return response.Error($"æçåºç«å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | |
| | | using Microsoft.AspNetCore.Http; |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using Microsoft.AspNetCore.Mvc; |
| | | using WIDESEA_Common.Constants; |
| | | using WIDESEA_Common.StockEnum; |
| | | using WIDESEA_Core; |
| | | using WIDESEA_Core.BaseController; |
| | | using WIDESEA_DTO.MES; |
| | | using WIDESEA_IStockService; |
| | | using WIDESEA_IBasicService; |
| | | using WIDESEA_IStockService; |
| | | using WIDESEA_ISystemService; |
| | | using WIDESEA_Model.Models; |
| | | using System.Diagnostics; |
| | | |
| | | namespace WIDESEA_WMSServer.Controllers.Stock |
| | | { |
| | |
| | | [ApiController] |
| | | public class StockInfoDetailController : ApiBaseController<IStockInfoDetailService, Dt_StockInfoDetail> |
| | | { |
| | | private readonly IMesLogService _mesLogService; |
| | | private readonly IMesService _mesService; |
| | | private readonly ISys_DictionaryService _sysDictionaryService; |
| | | private readonly IStockInfoService _stockInfoService; |
| | | private readonly IMESDeviceConfigService _mesDeviceConfigService; |
| | | private readonly IMesUploadHelper _mesUploadHelper; |
| | | |
| | | public StockInfoDetailController( |
| | | IStockInfoDetailService service, |
| | | IMesLogService mesLogService, |
| | | IMesService mesService, |
| | | ISys_DictionaryService sysDictionaryService, |
| | | IStockInfoService stockInfoService) : base(service) |
| | | IStockInfoService stockInfoService, |
| | | IMESDeviceConfigService mesDeviceConfigService, |
| | | IMesUploadHelper mesUploadHelper) : base(service) |
| | | { |
| | | _mesLogService = mesLogService; |
| | | _mesService = mesService; |
| | | _sysDictionaryService = sysDictionaryService; |
| | | _stockInfoService = stockInfoService; |
| | | _mesDeviceConfigService = mesDeviceConfigService; |
| | | _mesUploadHelper = mesUploadHelper; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | public async Task<WebResponseContent> BindContainer([FromBody] BindContainerRequestDto dto) |
| | | { |
| | | var response = new WebResponseContent(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | |
| | | try |
| | | { |
| | | // 1. åæ°éªè¯ |
| | | if (dto.SfcList == null || !dto.SfcList.Any()) |
| | | { |
| | | return response.Error("çµè¯ç å表ä¸è½ä¸ºç©º"); |
| | | } |
| | | //// 1. åæ°éªè¯ |
| | | //if (dto.SfcList == null || !dto.SfcList.Any()) |
| | | //{ |
| | | // return response.Error("çµè¯ç å表ä¸è½ä¸ºç©º"); |
| | | //} |
| | | |
| | | // 2. éªè¯çµè¯ç¶æï¼é'å·²éå®'ç¶æå
许ç»å®ï¼ |
| | | var stockDetail = await Service.Repository.QueryFirstAsync(x => dto.SfcList.Contains(x.SerialNumber)); |
| | | if (stockDetail != null && stockDetail.Status == 99) |
| | | { |
| | | return response.Error("å½ååºåæç»å
å«å·²éå®ç¶æï¼ä¸å
许æ§è¡ç»å®æä½"); |
| | | } |
| | | var stockInfo = await _stockInfoService.Repository.QueryFirstAsync(x => stockDetail.StockId == x.Id); |
| | | //var stockDetail = await Service.Repository.QueryFirstAsync(x => dto.SfcList.Contains(x.SerialNumber)); |
| | | //if (stockDetail != null && stockDetail.Status == 99) |
| | | //{ |
| | | // return response.Error("å½ååºåæç»å
å«å·²éå®ç¶æï¼ä¸å
许æ§è¡ç»å®æä½"); |
| | | //} |
| | | var stockInfo = await _stockInfoService.Repository.QueryDataNavFirstAsync(x => x.PalletCode == dto.PalletCode); |
| | | |
| | | // 3. æé MESè¯·æ± - å°çµè¯å表转æ¢ä¸ºContainerSfcItemæ ¼å¼ |
| | | // 3. 卿è·åMESåè¯ |
| | | var mesConfig = _mesDeviceConfigService.GetByDeviceName("ç»çæºæ¢°æ"); |
| | | string equipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE; |
| | | string resourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE; |
| | | string token = mesConfig?.Token; |
| | | |
| | | // 4. æé MESè¯·æ± - å°çµè¯å表转æ¢ä¸ºContainerSfcItemæ ¼å¼ |
| | | var mesRequest = new BindContainerRequest |
| | | { |
| | | EquipmentCode = "STK-GROUP-001", |
| | | ResourceCode = "STK-GROUP-001", |
| | | EquipmentCode = equipmentCode, |
| | | ResourceCode = resourceCode, |
| | | LocalTime = DateTime.Now, |
| | | ContainerCode = stockInfo.PalletCode, |
| | | ContainerSfcList = dto.SfcList.Select(sfc => new ContainerSfcItem |
| | | ContainerSfcList = stockInfo.Details.Select(sfc => new ContainerSfcItem |
| | | { |
| | | Sfc = sfc, |
| | | Location = dto.Location ?? "" |
| | | Sfc = sfc.SerialNumber, |
| | | Location = sfc.InboundOrderRowNo.ToString() ?? "" |
| | | }).ToList(), |
| | | OperationType = dto.OperationType |
| | | }; |
| | | |
| | | string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest); |
| | | |
| | | // 4. è°ç¨MESæ¥å£ï¼åæ¥æ¹æ³ï¼ |
| | | var mesResult = _mesService.BindContainer(mesRequest); |
| | | stopwatch.Stop(); |
| | | // 5. 弿¥è°ç¨MESæ¥å£ï¼fire-and-forgetï¼ |
| | | _mesUploadHelper.FireAndForget( |
| | | stockInfo.PalletCode, |
| | | MesUploadStatusEnum.ç»çä¸ä¼ æå, |
| | | "BindContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.BindContainer(mesRequest) |
| | | : _mesService.BindContainer(mesRequest, token); |
| | | return ( |
| | | result?.Data?.IsSuccess ?? false, |
| | | System.Text.Json.JsonSerializer.Serialize(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }, |
| | | App.User.UserName); |
| | | |
| | | // 5. è®°å½æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "BindContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(mesResult), |
| | | IsSuccess = mesResult.IsSuccess, |
| | | ErrorMessage = mesResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | // 6. è¿åç»æ |
| | | if (mesResult.IsSuccess) |
| | | { |
| | | return response.OK("æççµè¯ç»å®æå"); |
| | | } |
| | | else |
| | | { |
| | | return response.Error($"MESæ¥å£è°ç¨å¤±è´¥: {mesResult.ErrorMessage}"); |
| | | } |
| | | // 6. ç«å³è¿åæåååº |
| | | return response.OK("æççµè¯ç»å®æå"); |
| | | } |
| | | catch (System.Exception ex) |
| | | catch (Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | |
| | | // è®°å½é误æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "BindContainer", |
| | | IsSuccess = false, |
| | | ErrorMessage = ex.Message, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | return response.Error($"æççµè¯ç»å®å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | |
| | | public async Task<WebResponseContent> UnbindContainer([FromBody] UnbindContainerRequestDto dto) |
| | | { |
| | | var response = new WebResponseContent(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | |
| | | try |
| | | { |
| | | // 1. åæ°éªè¯ |
| | | if (dto.SfcList == null || !dto.SfcList.Any()) |
| | | { |
| | | return response.Error("çµè¯ç å表ä¸è½ä¸ºç©º"); |
| | | } |
| | | //if (dto.SfcList == null || !dto.SfcList.Any()) |
| | | //{ |
| | | // return response.Error("çµè¯ç å表ä¸è½ä¸ºç©º"); |
| | | //} |
| | | |
| | | // 2. éªè¯çµè¯ç¶æï¼é'å·²éå®'ç¶æå
许解ç»ï¼ |
| | | var stockDetail = await Service.Repository.QueryFirstAsync(x => dto.SfcList.Contains(x.SerialNumber)); |
| | | if (stockDetail != null && stockDetail.Status == 99) |
| | | { |
| | | return response.Error("å½ååºåæç»å
å«å·²éå®ç¶æï¼ä¸å
许æ§è¡è§£ç»æä½"); |
| | | } |
| | | var stockInfo = await _stockInfoService.Repository.QueryFirstAsync(x => stockDetail.StockId == x.Id); |
| | | //// 2. éªè¯çµè¯ç¶æï¼é'å·²éå®'ç¶æå
许解ç»ï¼ |
| | | //var stockDetail = await Service.Repository.QueryFirstAsync(x => dto.SfcList.Contains(x.SerialNumber)); |
| | | //if (stockDetail != null && stockDetail.Status == 99) |
| | | //{ |
| | | // return response.Error("å½ååºåæç»å
å«å·²éå®ç¶æï¼ä¸å
许æ§è¡è§£ç»æä½"); |
| | | //} |
| | | var stockInfo = await _stockInfoService.Repository.QueryDataNavFirstAsync(x => dto.PalletCode == x.PalletCode); |
| | | |
| | | // 3. æé MESè¯·æ± |
| | | // 3. 卿è·åMESåè¯ |
| | | var mesConfig = _mesDeviceConfigService.GetByDeviceName("ç»çæºæ¢°æ"); |
| | | string equipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE; |
| | | string resourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE; |
| | | string token = mesConfig?.Token; |
| | | |
| | | // 4. æé MESè¯·æ± |
| | | var mesRequest = new UnBindContainerRequest |
| | | { |
| | | EquipmentCode = "STK-GROUP-001", |
| | | ResourceCode = "STK-GROUP-001", |
| | | EquipmentCode = equipmentCode, |
| | | ResourceCode = resourceCode, |
| | | LocalTime = DateTime.Now, |
| | | ContainCode = stockInfo.PalletCode, |
| | | SfcList = dto.SfcList |
| | | SfcList = stockInfo.Details.Select(x => x.SerialNumber).ToList(), |
| | | }; |
| | | |
| | | string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest); |
| | | |
| | | // 4. è°ç¨MESæ¥å£ï¼åæ¥æ¹æ³ï¼ |
| | | var mesResult = _mesService.UnBindContainer(mesRequest); |
| | | stopwatch.Stop(); |
| | | // 5. 弿¥è°ç¨MESæ¥å£ï¼fire-and-forgetï¼ |
| | | _mesUploadHelper.FireAndForget( |
| | | stockInfo.PalletCode, |
| | | MesUploadStatusEnum.æçä¸ä¼ æå, |
| | | "UnbindContainer", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = string.IsNullOrWhiteSpace(token) |
| | | ? _mesService.UnBindContainer(mesRequest) |
| | | : _mesService.UnBindContainer(mesRequest, token); |
| | | return ( |
| | | result?.Data?.IsSuccess ?? false, |
| | | System.Text.Json.JsonSerializer.Serialize(result), |
| | | result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }, |
| | | App.User.UserName); |
| | | |
| | | // 5. è®°å½æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "UnbindContainer", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(mesResult), |
| | | IsSuccess = mesResult.IsSuccess, |
| | | ErrorMessage = mesResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | // 6. è¿åç»æ |
| | | if (mesResult.IsSuccess) |
| | | { |
| | | return response.OK("æççµè¯è§£ç»æå"); |
| | | } |
| | | else |
| | | { |
| | | return response.Error($"MESæ¥å£è°ç¨å¤±è´¥: {mesResult.ErrorMessage}"); |
| | | } |
| | | // 6. ç«å³è¿åæåååº |
| | | return response.OK("æççµè¯è§£ç»æå"); |
| | | } |
| | | catch (System.Exception ex) |
| | | catch (Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | |
| | | // è®°å½é误æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "UnbindContainer", |
| | | IsSuccess = false, |
| | | ErrorMessage = ex.Message, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | return response.Error($"æççµè¯è§£ç»å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | |
| | | public async Task<WebResponseContent> ContainerNgReport([FromBody] ContainerNgReportRequestDto dto) |
| | | { |
| | | var response = new WebResponseContent(); |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | |
| | | try |
| | | { |
| | |
| | | } |
| | | var stockInfo = await _stockInfoService.Repository.QueryFirstAsync(x => stockDetail.StockId == x.Id); |
| | | |
| | | // 3. æé MESè¯·æ± - å°DTOæ ¼å¼è½¬æ¢ä¸ºMESè¯·æ±æ ¼å¼ |
| | | // 3. 卿è·åMESåè¯ |
| | | var mesConfig = _mesDeviceConfigService.GetByDeviceName("ç»çæºæ¢°æ"); |
| | | string equipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE; |
| | | string resourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE; |
| | | |
| | | // 4. æé MESè¯·æ± - å°DTOæ ¼å¼è½¬æ¢ä¸ºMESè¯·æ±æ ¼å¼ |
| | | var mesRequest = new ContainerNgReportRequest |
| | | { |
| | | EquipmentCode = "STK-GROUP-001", |
| | | ResourceCode = "RESOURCE-001", |
| | | EquipmentCode = equipmentCode, |
| | | ResourceCode = resourceCode, |
| | | LocalTime = DateTime.Now, |
| | | ContainerCode = stockInfo.PalletCode, |
| | | NgSfcList = dto.NgSfcList.Select(ng => new NgSfcItem |
| | |
| | | |
| | | string requestJson = System.Text.Json.JsonSerializer.Serialize(mesRequest); |
| | | |
| | | // 4. è°ç¨MESæ¥å£ï¼åæ¥æ¹æ³ï¼ |
| | | var mesResult = _mesService.ContainerNgReport(mesRequest); |
| | | stopwatch.Stop(); |
| | | // 5. 弿¥è°ç¨MESæ¥å£ï¼fire-and-forgetï¼ |
| | | _mesUploadHelper.FireAndForget( |
| | | stockInfo.PalletCode, |
| | | MesUploadStatusEnum.NG䏿¥æå, |
| | | "ContainerNgReport", |
| | | requestJson, |
| | | () => |
| | | { |
| | | var result = _mesService.ContainerNgReport(mesRequest); |
| | | return ( |
| | | result?.IsSuccess ?? false, |
| | | System.Text.Json.JsonSerializer.Serialize(result), |
| | | result?.ErrorMessage ?? "æªç¥é误" |
| | | ); |
| | | }, |
| | | App.User.UserName); |
| | | |
| | | // 5. è®°å½æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "ContainerNgReport", |
| | | RequestJson = requestJson, |
| | | ResponseJson = System.Text.Json.JsonSerializer.Serialize(mesResult), |
| | | IsSuccess = mesResult.IsSuccess, |
| | | ErrorMessage = mesResult.ErrorMessage, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | // 6. è¿åç»æ |
| | | if (mesResult.IsSuccess) |
| | | { |
| | | return response.OK("NGçµè¯ä¸æ¥æå"); |
| | | } |
| | | else |
| | | { |
| | | return response.Error($"MESæ¥å£è°ç¨å¤±è´¥: {mesResult.ErrorMessage}"); |
| | | } |
| | | // 6. ç«å³è¿åæåååº |
| | | return response.OK("NGçµè¯ä¸æ¥æå"); |
| | | } |
| | | catch (System.Exception ex) |
| | | catch (Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | |
| | | // è®°å½é误æ¥å¿ |
| | | await _mesLogService.LogAsync(new MesApiLogDto |
| | | { |
| | | ApiType = "ContainerNgReport", |
| | | IsSuccess = false, |
| | | ErrorMessage = ex.Message, |
| | | ElapsedMs = (int)stopwatch.ElapsedMilliseconds, |
| | | Creator = App.User.UserName |
| | | }); |
| | | |
| | | return response.Error($"NGçµè¯ä¸æ¥å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | |
| | | return defaultValue; |
| | | } |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # MES ä¸ä¼ ç¶æè·è¸ªä¸å¼æ¥ä¸ä¼ å®ç°è®¡å |
| | | |
| | | > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [x]`) syntax for tracking. |
| | | |
| | | **Goal:** å¨åºå表添å MES ä¸ä¼ ç¶æåæ®µï¼éè¿ `Task.Run` 弿¥æ¹å¼ä¸ä¼ MES æ°æ®ä¸å¹²æ°ä¸»é»è¾ï¼ææ MES è°ç¨è®°å½è¯¦ç»æ¥å¿ï¼å端æ¾ç¤ºç¶æå¹¶æä¾ç»ç/æçæé®ï¼ææ MES åè¯æ¹ä¸ºå¨æè·åã |
| | | |
| | | **Architecture:** |
| | | - `Dt_StockInfo.MesUploadStatus` ååæ®µè®°å½æè¿ä¸æ¬¡ MES æä½ç»æç¶æ |
| | | - ææ MES è°ç¨ç»ä¸éè¿ `Task.Run` 弿¥æ§è¡ï¼ä¸é»å¡ä¸»é»è¾ |
| | | - ä¸ä¼ å®æåæ´æ° `MesUploadStatus`ï¼å¹¶éè¿ `IMesLogService.LogAsync` è®°å½è¯¦ç»æ¥å¿ |
| | | - ææ MES åè¯ï¼EquipmentCodeãResourceCodeãTokenï¼æ¹ä¸ºä» `Dt_MESDeviceConfig` è¡¨å¨æè·å |
| | | - å端 `stockInfo.vue` æ°å¢ç¶æåï¼`stock.jsx` æ°å¢ç»ç/æçæé® |
| | | |
| | | **Tech Stack:** .NET 6/8, C#, SqlSugar ORM, ASP.NET Core WebAPI, Vue 3, Element Plus |
| | | |
| | | --- |
| | | |
| | | ## æä»¶åæ´æ¦è§ |
| | | |
| | | | æä½ | æä»¶ | |
| | | |------|------| |
| | | | æ°å¢ | `WIDESEA_Common/StockEnum/MesUploadStatusEnum.cs` | |
| | | | ä¿®æ¹ | `WIDESEA_Model/Models/Stock/Dt_StockInfo.cs` - æ°å¢ `MesUploadStatus` åæ®µ | |
| | | | ä¿®æ¹ | `WIDESEA_IStockService/IStockInfoService.cs` - æ°å¢ `UpdateMesUploadStatusAsync` | |
| | | | ä¿®æ¹ | `WIDESEA_StockService/StockInfoService.cs` - å®ç° `UpdateMesUploadStatusAsync` | |
| | | | ä¿®æ¹ | `WIDESEA_DTO/MES/MesApiLogDto.cs` - æ°å¢ `PalletCode` åæ®µ | |
| | | | ä¿®æ¹ | `WIDESEA_TaskInfoService/TaskService.cs` - æ°å¢ `MesUploadAsync` + `LogMesCallAsync` | |
| | | | ä¿®æ¹ | `WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs` - åºç« MES æ¹ä¸ºå¼æ¥ | |
| | | | ä¿®æ¹ | `WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs` - è¿ç« MES æ¹ä¸ºå¼æ¥ | |
| | | | ä¿®æ¹ | `WIDESEA_StockService/StockSerivce.cs` - ç»ç/æç MES æ¹ä¸ºå¼æ¥ | |
| | | | ä¿®æ¹ | `WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs` - è¿ç«/åºç« MES æ¹ä¸ºå¼æ¥ + 卿åè¯ | |
| | | | ä¿®æ¹ | `WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs` - ç»å®/è§£ç»/NG MES æ¹ä¸ºå¼æ¥ + 卿åè¯ | |
| | | | ä¿®æ¹ | `WIDESEA_WMSClient/src/views/stock/stockInfo.vue` - æ°å¢ `mesUploadStatus` å | |
| | | | ä¿®æ¹ | `WIDESEA_WMSClient/src/extension/stock/stock.jsx` - æ°å¢ç»ç/æçæé® | |
| | | | æ°å¢ | æ°æ®åºåæ´èæ¬ | |
| | | |
| | | --- |
| | | |
| | | ## Phase 1: åºç¡è®¾æ½ |
| | | |
| | | ### Task 1: æ°å¢ MesUploadStatusEnum æä¸¾ â
|
| | | |
| | | **Files:** Create `WIDESEA_Common/StockEnum/MesUploadStatusEnum.cs` |
| | | |
| | | - [x] å建æä¸¾ç±»ï¼11个å¼ï¼0=æªä¸ä¼ , 1/2=ç»ç, 3/4=æç, 5/6=è¿ç«, 7/8=åºç«, 9/10=NG䏿¥ï¼ |
| | | - [x] Commit: `b21d0f2` |
| | | |
| | | ### Task 2: ä¿®æ¹ Dt_StockInfo å®ä½ â
|
| | | |
| | | **Files:** Modify `WIDESEA_Model/Models/Stock/Dt_StockInfo.cs` |
| | | |
| | | - [x] å¨ `Remark` å `OutboundDate` ä¹é´æ°å¢ `MesUploadStatus` åæ®µï¼int, é»è®¤0ï¼ |
| | | - [x] Commit: `58759d4` |
| | | |
| | | ### Task 3: ä¿®æ¹ IStockInfoService æ¥å£ â
|
| | | |
| | | **Files:** Modify `WIDESEA_IStockService/IStockInfoService.cs` |
| | | |
| | | - [x] æ°å¢ `UpdateMesUploadStatusAsync(string palletCode, int status)` æ¹æ³å£°æ |
| | | - [x] Commit: `18e0765` |
| | | |
| | | ### Task 4: ä¿®æ¹ StockInfoService å®ç° â
|
| | | |
| | | **Files:** Modify `WIDESEA_StockService/StockInfoService.cs` |
| | | |
| | | - [x] å®ç° `UpdateMesUploadStatusAsync`ï¼ææçå·æ¥è¯¢ â æ´æ° MesUploadStatus |
| | | - [x] Commit: `25a246f`ï¼åä¿®å¤ç¼ºå¤±éåæ¬å· â `c329a05`ï¼ |
| | | |
| | | ### Task 5: ä¿®æ¹ TaskService æ°å¢å¼æ¥æ¹æ³ â
|
| | | |
| | | **Files:** Modify `WIDESEA_TaskInfoService/TaskService.cs` |
| | | |
| | | - [x] æ·»å using: `WIDESEA_Common.StockEnum`, `System.Diagnostics`, `Newtonsoft.Json` |
| | | - [x] æ°å¢ `MesUploadAsync` ç§æå¼æ¥æ¹æ³ï¼Task.Run è°ç¨ MES + æ´æ°ç¶æ + æ¥å¿ï¼ |
| | | - [x] æ°å¢ `LogMesCallAsync` ç§ææ¥å¿æ¹æ³ |
| | | - [x] Commit: `1330eff` |
| | | |
| | | ### Task 9: æ°æ®åºåæ´èæ¬ â
|
| | | |
| | | **Files:** Create `Database/Scripts/20260420_Dt_StockInfo_MesUploadStatus.sql` |
| | | |
| | | - [x] ALTER TABLE æ°å¢ MesUploadStatus TINYINT NOT NULL DEFAULT 0 |
| | | - [x] Commit: `eec94e8` |
| | | |
| | | ### éå ä¿®å¤: MesApiLogDto æ°å¢ PalletCode â
|
| | | |
| | | **Files:** Modify `WIDESEA_DTO/MES/MesApiLogDto.cs` |
| | | |
| | | - [x] æ°å¢ `PalletCode` 屿§æ¯æææçå·æ¥è¯¢æ¥å¿ |
| | | - [x] Commit: `32ece02` |
| | | |
| | | --- |
| | | |
| | | ## Phase 2: å端 MES è°ç¨æ¹é |
| | | |
| | | ### Task 6: TaskService_Outbound åºç« MES 弿¥ â
|
| | | |
| | | **Files:** Modify `WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs` |
| | | |
| | | - [x] `OutboundInContainer` æ¹ä¸º `Task.Run` 弿¥æ§è¡ |
| | | - [x] ä½¿ç¨ `MesUploadStatusEnum.åºç«ä¸ä¼ æå`ï¼7ï¼/ `åºç«ä¸ä¼ 失败`ï¼8ï¼ |
| | | - [x] Commit: `91e3264` |
| | | |
| | | ### Task 11: StockService ç»ç/æç MES 弿¥ â
|
| | | |
| | | **Files:** Modify `WIDESEA_StockService/StockSerivce.cs` |
| | | |
| | | - [x] `GroupPalletConfirmAsync` â `BindContainer` æ¹ä¸º `Task.Run` 弿¥ |
| | | - æå: `MesUploadStatusEnum.ç»çä¸ä¼ æå`ï¼1ï¼ |
| | | - 失败: `MesUploadStatusEnum.ç»çä¸ä¼ 失败`ï¼2ï¼ |
| | | - [x] `SplitPalletConfirmAsync` â `UnBindContainer` æ¹ä¸º `Task.Run` 弿¥ |
| | | - æå: `MesUploadStatusEnum.æçä¸ä¼ æå`ï¼3ï¼ |
| | | - 失败: `MesUploadStatusEnum.æçä¸ä¼ 失败`ï¼4ï¼ |
| | | - [x] ä¿ç卿 Token è·åé»è¾ï¼`ResolveMesConfig`ï¼ |
| | | - [x] Commit: `4506a1e` |
| | | |
| | | ### Task 12: StockInfoDetailController MES 弿¥ + 卿åè¯ â
|
| | | |
| | | **Files:** Modify `WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs` |
| | | |
| | | - [x] `BindContainer` æ¹ä¸º `Task.Run` 弿¥ â `MesUploadStatusEnum.ç»çä¸ä¼ æå/失败` |
| | | - [x] `UnbindContainer` æ¹ä¸º `Task.Run` 弿¥ â `MesUploadStatusEnum.æçä¸ä¼ æå/失败` |
| | | - [x] `ContainerNgReport` æ¹ä¸º `Task.Run` 弿¥ â `MesUploadStatusEnum.NG䏿¥æå/失败` |
| | | - [x] 硬ç¼ç `"STK-GROUP-001"` æ¹ä¸º `_mesDeviceConfigService.GetByDeviceName()` 卿è·å |
| | | - [x] 注å
¥ `IMESDeviceConfigService` |
| | | - [x] Commit: `57feefd` â `c36c5c6` |
| | | |
| | | ### Task 13: StockInfoController MES 弿¥ + 卿åè¯ â
|
| | | |
| | | **Files:** Modify `WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs` |
| | | |
| | | - [x] `InboundInContainer` æ¹ä¸º `Task.Run` 弿¥ â `MesUploadStatusEnum.è¿ç«ä¸ä¼ æå/失败` |
| | | - [x] `OutboundInContainer` æ¹ä¸º `Task.Run` 弿¥ â `MesUploadStatusEnum.åºç«ä¸ä¼ æå/失败` |
| | | - [x] 硬ç¼ç `"STK-GROUP-001"` æ¹ä¸ºåºäº `stockInfo.Remark` å¨æéæ©è®¾å¤åæ¥è¯¢ MES åè¯ |
| | | - [x] 注å
¥ `IMESDeviceConfigService` å `IStockInfoService` |
| | | - [x] Commit: `343d512` â `fba665e` |
| | | |
| | | ### Task 14: TaskService_Inbound è¿ç« MES 弿¥ â
|
| | | |
| | | **Files:** Modify `WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs` |
| | | |
| | | - [x] `InboundInContainer` æ¹ä¸º `Task.Run` 弿¥æ§è¡ |
| | | - [x] ä½¿ç¨ `MesUploadStatusEnum.è¿ç«ä¸ä¼ æå`ï¼5ï¼/ `è¿ç«ä¸ä¼ 失败`ï¼6ï¼ |
| | | - [x] ä¿ç卿 MES åè¯è·åé»è¾ï¼`_mesDeviceConfigService.GetByDeviceName`ï¼ |
| | | - [x] `CompleteTaskAsync` ç«å³è¿åï¼ä¸çå¾
MES ç»æ |
| | | - [x] Commit: `63ca4ac` |
| | | |
| | | --- |
| | | |
| | | ## Phase 3: å端 |
| | | |
| | | ### Task 7: stockInfo.vue æ°å¢ MES ç¶æå â
|
| | | |
| | | **Files:** Modify `WIDESEA_WMSClient/src/views/stock/stockInfo.vue` |
| | | |
| | | - [x] columns ä¸ `stockStatus` ä¹åæ°å¢ `mesUploadStatus` åï¼bind: mesUploadStatusEnumï¼ |
| | | - [x] `loadStockStatusOptions` æ¹ä¸ºåæ¶å è½½ `stockStatusEmun` + `mesUploadStatusEnum` |
| | | - [x] Commit: `9a1c82a` |
| | | |
| | | ### Task 8: stock.jsx æ°å¢ç»ç/æçæé® â
|
| | | |
| | | **Files:** Modify `WIDESEA_WMSClient/src/extension/stock/stock.jsx` |
| | | |
| | | - [x] `onInited` 䏿³¨å
¥ `editTableButtons`ï¼ç»ç + æç |
| | | - [x] `onGroupPallet` â POST `/Stock/GroupPalletConfirm` |
| | | - [x] `onSplitPallet` â POST `/Stock/SplitPalletConfirm` |
| | | - [x] Commit: `0be9278` |
| | | |
| | | --- |
| | | |
| | | ## Phase 4: æå»ºéªè¯ |
| | | |
| | | ### Task 10: æå»ºéªè¯ â
|
| | | |
| | | - [x] å端 `dotnet build WIDESEA_WMSServer.sln` â 0 é误 |
| | | - [x] å端 `npm run build` â 0 é误 |
| | | |
| | | --- |
| | | |
| | | ## MES è°ç¨ç¹å
¨è¦ç |
| | | |
| | | | ä½ç½® | æ¹æ³ | MESæ¥å£ | ç¶ææä¸¾ | 卿åè¯ | 弿¥ | |
| | | |------|------|---------|---------|---------|------| |
| | | | `StockSerivce.cs` | `GroupPalletConfirmAsync` | `BindContainer` | 1æå/2失败 | â
ResolveMesConfig | â
| |
| | | | `StockSerivce.cs` | `SplitPalletConfirmAsync` | `UnBindContainer` | 3æå/4失败 | â
ResolveMesConfig | â
| |
| | | | `TaskService_Inbound.cs` | `InboundFinishTaskAsync` | `InboundInContainer` | 5æå/6失败 | â
MESDeviceConfigService | â
| |
| | | | `TaskService_Outbound.cs` | `OutboundFinishTaskAsync` | `OutboundInContainer` | 7æå/8失败 | â
MESDeviceConfigService | â
| |
| | | | `StockInfoController.cs` | `InboundInContainer` | `InboundInContainer` | 5æå/6失败 | â
MESDeviceConfigService | â
| |
| | | | `StockInfoController.cs` | `OutboundInContainer` | `OutboundInContainer` | 7æå/8失败 | â
MESDeviceConfigService | â
| |
| | | | `StockInfoDetailController.cs` | `BindContainer` | `BindContainer` | 1æå/2失败 | â
MESDeviceConfigService | â
| |
| | | | `StockInfoDetailController.cs` | `UnbindContainer` | `UnBindContainer` | 3æå/4失败 | â
MESDeviceConfigService | â
| |
| | | | `StockInfoDetailController.cs` | `ContainerNgReport` | `ContainerNgReport` | 9æå/10失败 | â
MESDeviceConfigService | â
| |
| | | |
| | | --- |
| | | |
| | | ## èªæ£æ¸
å |
| | | |
| | | - [x] `MesUploadStatusEnum` æä¸¾å¼å¥æ°ä¸ºæåï¼å¶æ°ä¸ºå¤±è´¥ |
| | | - [x] ææ MES è°ç¨éè¿ `Task.Run` 弿¥æ§è¡ï¼ä¸é»å¡ä¸»é»è¾ |
| | | - [x] ææ MES è°ç¨è®°å½è¯¦ç»æ¥å¿ï¼æçå·ãæ¥å£ç±»åã请æ±JSONãååºJSONãèæ¶ãç¶æãé误åå ï¼ |
| | | - [x] ææ MES åè¯å¨æè·åï¼ä¸å硬ç¼ç `"STK-GROUP-001"` |
| | | - [x] å端ç»ç/æçæé®æ£ç¡®è°ç¨ `GroupPalletConfirmAsync` / `SplitPalletConfirmAsync` |
| | | - [x] `stockInfo.vue` æ£ç¡®æ¾ç¤º `mesUploadStatus` åæ®µ |
| | | - [x] ææ public æ¹æ³åæ XML ææ¡£æ³¨é |
| | | - [x] æ°æ®åºèæ¬å« IF NOT EXISTS 鲿¢é夿·»å |
| | | - [x] å端åå端å坿£å¸¸ç¼è¯æå»ºï¼0 éè¯¯ï¼ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # MES ä¸ä¼ ç¶æè·è¸ªä¸å¼æ¥ä¸ä¼ 设计 |
| | | |
| | | > **Date:** 2026-04-20 |
| | | > **Author:** Claude |
| | | |
| | | ## 1. ç®æ |
| | | |
| | | å¨åºå表添å MES ä¸ä¼ ç¶æåæ®µï¼éè¿å¼æ¥æ¹å¼ä¸ä¼ MES æ°æ®ï¼ä¸å¹²æ°ä¸»ä¸å¡é»è¾ï¼ææ MES è°ç¨åè®°å½è¯¦ç»æ¥å¿ã |
| | | |
| | | ## 2. æ°æ®åºåæ´ |
| | | |
| | | ### 2.1 Dt_StockInfo 表æ°å¢å段 |
| | | |
| | | ```sql |
| | | ALTER TABLE [dbo].[Dt_StockInfo] ADD [MesUploadStatus] TINYINT NOT NULL DEFAULT 0; |
| | | GO |
| | | ``` |
| | | |
| | | ### 2.2 æä¸¾å®ä¹ |
| | | |
| | | | å¼ | å«ä¹ | |
| | | |----|------| |
| | | | 0 | æªä¸ä¼ ï¼ä»æªè°ç¨è¿MESï¼ | |
| | | | 1 | ç»çä¸ä¼ æå | |
| | | | 2 | ç»çä¸ä¼ 失败 | |
| | | | 3 | æçä¸ä¼ æå | |
| | | | 4 | æçä¸ä¼ 失败 | |
| | | | 5 | è¿ç«ä¸ä¼ æå | |
| | | | 6 | è¿ç«ä¸ä¼ 失败 | |
| | | | 7 | åºç«ä¸ä¼ æå | |
| | | | 8 | åºç«ä¸ä¼ 失败 | |
| | | | 9 | NG䏿¥æå | |
| | | | 10 | NG䏿¥å¤±è´¥ | |
| | | |
| | | å¨ `WIDESEA_Common` é¡¹ç®æ°å¢æä¸¾ç±» `MesUploadStatusEnum`ã |
| | | |
| | | ## 3. å端设计 |
| | | |
| | | ### 3.1 æ ¸å¿å¼æ¥æ¹æ³ |
| | | |
| | | å¨ `WIDESEA_TaskInfoService/TaskService.cs` 䏿°å¢ `MesUploadAsync` ç§æå¼æ¥æ¹æ³ï¼ |
| | | |
| | | ```csharp |
| | | /// <summary> |
| | | /// 弿¥æ§è¡MESä¸ä¼ - ä¸é»å¡ä¸»ä¸å¡é»è¾ |
| | | /// </summary> |
| | | /// <param name="palletCode">æçå·</param> |
| | | /// <param name="mesType">MESæä½ç±»åæä¸¾</param> |
| | | /// <param name="uploadFunc">å
·ä½çMESè°ç¨å½æ°</param> |
| | | private async Task MesUploadAsync(string palletCode, MesUploadStatusEnum mesType, Func<Task<HttpResponseResult<MesResponse>>> uploadFunc) |
| | | { |
| | | var stopwatch = Stopwatch.StartNew(); |
| | | string requestJson = ""; |
| | | string responseJson = ""; |
| | | bool isSuccess = false; |
| | | string errorMessage = ""; |
| | | |
| | | try |
| | | { |
| | | // è®°å½è¯·æ±æ¥å¿ |
| | | var mesLog = new MesApiLogDto |
| | | { |
| | | PalletCode = palletCode, |
| | | ApiType = mesType.ToString(), |
| | | RequestTime = DateTime.Now |
| | | }; |
| | | |
| | | // è°ç¨MES |
| | | var result = await uploadFunc(); |
| | | |
| | | stopwatch.Stop(); |
| | | isSuccess = result?.Data?.IsSuccess ?? false; |
| | | errorMessage = result?.Data?.Msg ?? result?.ErrorMessage ?? "æªç¥é误"; |
| | | responseJson = JsonConvert.SerializeObject(result); |
| | | |
| | | // æ´æ°åºåè¡¨ç¶æ |
| | | var uploadStatus = isSuccess ? (int)mesType : (int)mesType + 1; // 奿°=æåï¼å¶æ°=失败 |
| | | await _stockInfoService.UpdateMesUploadStatusAsync(palletCode, uploadStatus); |
| | | |
| | | // è®°å½æ¥å¿ |
| | | mesLog.ResponseTime = DateTime.Now; |
| | | mesLog.Duration = stopwatch.ElapsedMilliseconds; |
| | | mesLog.RequestParams = requestJson; |
| | | mesLog.ResponseResult = responseJson; |
| | | mesLog.Status = isSuccess ? "æå" : "失败"; |
| | | mesLog.ErrorMessage = errorMessage; |
| | | mesLog.CreateTime = DateTime.Now; |
| | | |
| | | _ = _mesLogService.LogAsync(mesLog); // ä¸çå¾
|
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | stopwatch.Stop(); |
| | | errorMessage = ex.Message; |
| | | |
| | | // æ´æ°ç¶æä¸ºå¤±è´¥ |
| | | var uploadStatus = (int)mesType + 1; |
| | | _stockInfoService.UpdateMesUploadStatusAsync(palletCode, uploadStatus).ConfigureAwait(false); |
| | | |
| | | // è®°å½å¼å¸¸æ¥å¿ |
| | | var mesLog = new MesApiLogDto |
| | | { |
| | | PalletCode = palletCode, |
| | | ApiType = mesType.ToString(), |
| | | RequestTime = DateTime.Now, |
| | | ResponseTime = DateTime.Now, |
| | | Duration = stopwatch.ElapsedMilliseconds, |
| | | RequestParams = requestJson, |
| | | ResponseResult = responseJson, |
| | | Status = "失败", |
| | | ErrorMessage = errorMessage, |
| | | CreateTime = DateTime.Now |
| | | }; |
| | | _ = _mesLogService.LogAsync(mesLog); // ä¸çå¾
|
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### 3.2 è°ç¨æ¹å¼ |
| | | |
| | | å¨å个 MES æä½å¤ç»ä¸ä½¿ç¨ `Task.Run` + `MesUploadAsync`ï¼ |
| | | |
| | | ```csharp |
| | | // ç»ç确认 |
| | | public async Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName) |
| | | { |
| | | // ... ä¸å¡é»è¾ ... |
| | | |
| | | // 弿¥MESä¸ä¼ ï¼ä¸é»å¡ä¸»é»è¾ |
| | | _ = Task.Run(() => MesUploadAsync(palletCode, MesUploadStatusEnum.GroupPalletSuccess, async () => |
| | | { |
| | | return await _mesService.BindContainerAsync(bindRequest, token); |
| | | })); |
| | | |
| | | return content.OK("ç»çæå"); |
| | | } |
| | | |
| | | // æç确认 |
| | | public async Task<WebResponseContent> SplitPalletConfirmAsync(string palletCode, string deviceName) |
| | | { |
| | | // ... ä¸å¡é»è¾ ... |
| | | |
| | | _ = Task.Run(() => MesUploadAsync(palletCode, MesUploadStatusEnum.SplitPalletSuccess, async () => |
| | | { |
| | | return await _mesService.UnBindContainerAsync(unbindRequest, token); |
| | | })); |
| | | |
| | | return content.OK("æçæå"); |
| | | } |
| | | ``` |
| | | |
| | | ### 3.3 IStockInfoService æ°å¢æ¹æ³ |
| | | |
| | | å¨ `IStockInfoService` æ¥å£æ°å¢ï¼ |
| | | |
| | | ```csharp |
| | | /// <summary> |
| | | /// æ´æ°MESä¸ä¼ ç¶æ |
| | | /// </summary> |
| | | /// <param name="palletCode">æçå·</param> |
| | | /// <param name="status">ç¶æå¼</param> |
| | | Task<bool> UpdateMesUploadStatusAsync(string palletCode, int status); |
| | | ``` |
| | | |
| | | å¨ `StockInfoService` ä¸å®ç°è¯¥æ¹æ³ã |
| | | |
| | | ### 3.4 æ¥å¿è®°å½è§è |
| | | |
| | | ææ MES è°ç¨ç»ä¸è®°å½ä»¥ä¸åæ®µï¼ |
| | | |
| | | | åæ®µ | 说æ | |
| | | |------|------| |
| | | | PalletCode | æçå· | |
| | | | ApiType | æ¥å£ç±»åï¼ç»ç/æç/è¿ç«/åºç«/NG䏿¥ï¼ | |
| | | | RequestTime | è¯·æ±æ¶é´ | |
| | | | ResponseTime | ååºæ¶é´ | |
| | | | Duration | èæ¶(ms) | |
| | | | RequestParams | 请æ±JSON | |
| | | | ResponseResult | ååºJSON | |
| | | | Status | æå/失败 | |
| | | | ErrorMessage | 失败åå | |
| | | |
| | | ## 4. åç«¯åæ´ |
| | | |
| | | ### 4.1 åºå页颿ä½åæ°å¢æé® |
| | | |
| | | å¨ `WMS/WIDESEA_WMSClient/src/extension/stock/stock.jsx` 䏿©å±æä½åï¼ |
| | | |
| | | ```jsx |
| | | let extension = { |
| | | components: { |
| | | gridHeader: "", |
| | | gridBody: "", |
| | | gridFooter: "", |
| | | modelHeader: "", |
| | | modelBody: "", |
| | | modelFooter: "", |
| | | }, |
| | | tableAction: "stock", |
| | | buttons: { |
| | | view: ["Export"], |
| | | box: [] |
| | | }, |
| | | methods: { |
| | | onInit() { |
| | | return true; |
| | | }, |
| | | onInited() { |
| | | // 注å
¥ç»ç/æçæé® |
| | | this.editTableButtons = [ |
| | | { name: "ç»ç", onClick: this.onGroupPallet }, |
| | | { name: "æç", onClick: this.onSplitPallet } |
| | | ]; |
| | | return true; |
| | | }, |
| | | async onGroupPallet({ row }) { |
| | | // è°ç¨ç»çæ¥å£ |
| | | let result = await this.$api.post("/Stock/GroupPalletConfirm", { palletCode: row.palletCode }); |
| | | if (result.status) { |
| | | this.$Message.success("ç»çæå"); |
| | | this.$refs.grid.search(); |
| | | } else { |
| | | this.$Message.error(result.message || "ç»ç失败"); |
| | | } |
| | | }, |
| | | async onSplitPallet({ row }) { |
| | | // è°ç¨æçæ¥å£ |
| | | let result = await this.$api.post("/Stock/SplitPalletConfirm", { palletCode: row.palletCode }); |
| | | if (result.status) { |
| | | this.$Message.success("æçæå"); |
| | | this.$refs.grid.search(); |
| | | } else { |
| | | this.$Message.error(result.message || "æç失败"); |
| | | } |
| | | } |
| | | }, |
| | | }; |
| | | |
| | | export default extension; |
| | | ``` |
| | | |
| | | ### 4.2 åºåå表æ°å¢ç¶æå |
| | | |
| | | å¨ `WMS/WIDESEA_WMSClient/src/views/stock/stock.vue` ç `columns` 䏿°å¢ï¼ |
| | | |
| | | ```vue |
| | | { field: "mesUploadStatus", title: "MESç¶æ", type: "int", width: 120, bind: { key: "mesUploadStatusEnum", data: [] } } |
| | | ``` |
| | | |
| | | ### 4.3 åå
¸é
ç½® |
| | | |
| | | å¨ `mesUploadStatusEnum` åå
¸ä¸æ·»å ï¼ |
| | | |
| | | | value | label | |
| | | |-------|-------| |
| | | | 0 | æªä¸ä¼ | |
| | | | 1 | ç»çæå | |
| | | | 2 | ç»ç失败 | |
| | | | 3 | æçæå | |
| | | | 4 | æç失败 | |
| | | | 5 | è¿ç«æå | |
| | | | 6 | è¿ç«å¤±è´¥ | |
| | | | 7 | åºç«æå | |
| | | | 8 | åºç«å¤±è´¥ | |
| | | | 9 | NG䏿¥æå | |
| | | | 10 | NG䏿¥å¤±è´¥ | |
| | | |
| | | ## 5. æä»¶åæ´æ¸
å |
| | | |
| | | | æä½ | æä»¶ | |
| | | |------|------| |
| | | | æ°å¢ | `WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/MesUploadStatusEnum.cs` | |
| | | | ä¿®æ¹ | `WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfo.cs` - æ°å¢ MesUploadStatus åæ®µ | |
| | | | ä¿®æ¹ | `WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs` - æ°å¢ UpdateMesUploadStatusAsync | |
| | | | ä¿®æ¹ | `WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs` - å®ç° UpdateMesUploadStatusAsync | |
| | | | ä¿®æ¹ | `WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs` - æ°å¢ MesUploadAsync + åå¤è°ç¨ | |
| | | | ä¿®æ¹ | `WMS/WIDESEA_WMSClient/src/extension/stock/stock.jsx` - æ°å¢ç»ç/æçæé® | |
| | | | ä¿®æ¹ | `WMS/WIDESEA_WMSClient/src/views/stock/stock.vue` - æ°å¢MESç¶æå | |
| | | | æ°å¢ | æ°æ®åºåæ´èæ¬ | |
| | | |
| | | ## 6. èªæ£æ¸
å |
| | | |
| | | - [ ] `MesUploadStatusEnum` æä¸¾å¼å¥æ°ä¸ºæåï¼å¶æ°ä¸ºå¤±è´¥ï¼+1è¿ç®æ£ç¡® |
| | | - [ ] `MesUploadAsync` æ¹æ³å
ææ MES è°ç¨è®°å½è¯¦ç»æ¥å¿ï¼è¯·æ±JSONãååºJSONãèæ¶ãé误åå ï¼ |
| | | - [ ] ç»ç/æç/è¿ç«/åºç«/NG䏿¥åéè¿ `Task.Run` 弿¥æ§è¡ï¼ä¸é»å¡ä¸»é»è¾ |
| | | - [ ] å端ç»ç/æçæé®è°ç¨ `GroupPalletConfirmAsync` / `SplitPalletConfirmAsync` |
| | | - [ ] åºåå表æ£ç¡®æ¾ç¤º `mesUploadStatus` åæ®µ |
| | | - [ ] ææ public æ¹æ³åæ XML ææ¡£æ³¨é |