Merge remote-tracking branch 'origin/dev_business' into dev_business
# Conflicts:
# yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java
| | |
| | | { |
| | | "mcpServers": { |
| | | "idea": { |
| | | "url": "http://127.0.0.1:64342/stream", |
| | | "url": "http://127.0.0.1:64417/stream", |
| | | "type": "http" |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "mcpServers": { |
| | | "idea": { |
| | | "url": "http://127.0.0.1:64417/stream", |
| | | "type": "http" |
| | | } |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: 工忰ååMOMç³»ç» |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: 工忰ååMOMç³»ç» |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=e7]: |
| | | - complementary [ref=e8]: |
| | | - generic [ref=e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=e18] |
| | | - generic [ref=e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=e22]: |
| | | - listitem [ref=e23]: |
| | | - generic [ref=e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=e34]: |
| | | - generic [ref=e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=e43]: |
| | | - generic [ref=e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=e50]: |
| | | - generic [ref=e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=e57]: |
| | | - generic [ref=e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=e65]: |
| | | - generic [ref=e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=e74]: |
| | | - generic [ref=e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=e82]: |
| | | - generic [ref=e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=e89]: |
| | | - generic [ref=e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=e96]: |
| | | - generic [ref=e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=e103]: |
| | | - generic [ref=e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=e110]: |
| | | - generic [ref=e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=e117]: |
| | | - generic [ref=e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=e131]: |
| | | - generic [ref=e132]: |
| | | - banner [ref=e133]: |
| | | - button [ref=e134] [cursor=pointer] |
| | | - button [ref=e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=e142]: |
| | | - list [ref=e143]: |
| | | - listitem [ref=e144]: |
| | | - link [ref=e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=e152] |
| | | - listitem [ref=e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=e156] |
| | | - generic [ref=e159]: |
| | | - generic [ref=e161] [cursor=pointer]: |
| | | - generic [ref=e165]: æç´¢ |
| | | - generic [ref=e166]: Ctrl K |
| | | - button [ref=e168] [cursor=pointer] |
| | | - button "dark" [ref=e173] [cursor=pointer] |
| | | - button [ref=e182] [cursor=pointer] |
| | | - button [ref=e188] [cursor=pointer] |
| | | - button [ref=e191] [cursor=pointer] |
| | | - button [ref=e197] [cursor=pointer]: |
| | | - button [ref=e199] |
| | | - button "å·¥ä½å°" [ref=e203] [cursor=pointer] |
| | | - button "æºç " [ref=e207] [cursor=pointer] |
| | | - generic [ref=e214]: |
| | | - generic [ref=e219]: |
| | | - generic [ref=e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=e254] [cursor=pointer] |
| | | - main [ref=e272]: |
| | | - generic [ref=e275]: |
| | | - generic [ref=e276]: |
| | | - button [ref=e277] [cursor=pointer] |
| | | - generic [ref=e280]: æµè¯é¡¹ç® |
| | | - generic [ref=e281]: æµè¯ç¼å· |
| | | - generic [ref=e282]: è¯æ ä¸ |
| | | - generic [ref=e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=e284] [cursor=pointer] |
| | | - generic [ref=e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=e291]: |
| | | - generic [ref=e292]: |
| | | - generic [ref=e293]: é¢ç®éé¢ |
| | | - generic [ref=e294]: 15,000 å
|
| | | - generic [ref=e295]: |
| | | - generic [ref=e296]: è´è´£äºº |
| | | - generic [ref=e297]: "-" |
| | | - generic [ref=e298]: |
| | | - generic [ref=e299]: éè´ç»ç» |
| | | - generic [ref=e300]: "-" |
| | | - generic [ref=e301]: |
| | | - generic [ref=e302]: 弿 æ¶é´ |
| | | - generic [ref=e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=e304]: |
| | | - generic [ref=e305]: å¼å§æ¶é´ |
| | | - generic [ref=e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=e307]: |
| | | - generic [ref=e308]: æªæ¢æ¶é´ |
| | | - generic [ref=e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=e313]: |
| | | - tablist [ref=e314]: |
| | | - generic [ref=e316]: |
| | | - tab [ref=e318] [cursor=pointer] |
| | | - tab [ref=e323] [cursor=pointer] |
| | | - tab [ref=e328] [cursor=pointer] |
| | | - tab [ref=e333] [cursor=pointer] |
| | | - tab [ref=e338] [cursor=pointer] |
| | | - tab [active] [selected] [ref=e343] [cursor=pointer] |
| | | - tabpanel "宿 " [ref=e404]: |
| | | - generic [ref=e405]: |
| | | - generic "å°æªå®æ " |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=e7]: |
| | | - complementary [ref=e8]: |
| | | - generic [ref=e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=e18] |
| | | - generic [ref=e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=e22]: |
| | | - listitem [ref=e23]: |
| | | - generic [ref=e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=e34]: |
| | | - generic [ref=e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=e43]: |
| | | - generic [ref=e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=e50]: |
| | | - generic [ref=e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=e57]: |
| | | - generic [ref=e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=e65]: |
| | | - generic [ref=e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=e74]: |
| | | - generic [ref=e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=e82]: |
| | | - generic [ref=e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=e89]: |
| | | - generic [ref=e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=e96]: |
| | | - generic [ref=e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=e103]: |
| | | - generic [ref=e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=e110]: |
| | | - generic [ref=e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=e117]: |
| | | - generic [ref=e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=e131]: |
| | | - generic [ref=e132]: |
| | | - banner [ref=e133]: |
| | | - button [ref=e134] [cursor=pointer] |
| | | - button [ref=e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=e142]: |
| | | - list [ref=e143]: |
| | | - listitem [ref=e144]: |
| | | - link [ref=e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=e152] |
| | | - listitem [ref=e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=e156] |
| | | - generic [ref=e159]: |
| | | - generic [ref=e161] [cursor=pointer]: |
| | | - generic [ref=e165]: æç´¢ |
| | | - generic [ref=e166]: Ctrl K |
| | | - button [ref=e168] [cursor=pointer] |
| | | - button "dark" [ref=e173] [cursor=pointer] |
| | | - button [ref=e182] [cursor=pointer] |
| | | - button [ref=e188] [cursor=pointer] |
| | | - button [ref=e191] [cursor=pointer] |
| | | - button [ref=e197] [cursor=pointer]: |
| | | - button [ref=e199] |
| | | - button "å·¥ä½å°" [ref=e203] [cursor=pointer] |
| | | - button "æºç " [ref=e207] [cursor=pointer] |
| | | - generic [ref=e214]: |
| | | - generic [ref=e219]: |
| | | - generic [ref=e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=e254] [cursor=pointer] |
| | | - main [ref=e272]: |
| | | - generic [ref=e275]: |
| | | - generic [ref=e276]: |
| | | - button [ref=e277] [cursor=pointer] |
| | | - generic [ref=e280]: æµè¯é¡¹ç® |
| | | - generic [ref=e281]: æµè¯ç¼å· |
| | | - generic [ref=e282]: è¯æ ä¸ |
| | | - generic [ref=e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=e284] [cursor=pointer] |
| | | - generic [ref=e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=e291]: |
| | | - generic [ref=e292]: |
| | | - generic [ref=e293]: é¢ç®éé¢ |
| | | - generic [ref=e294]: 15,000 å
|
| | | - generic [ref=e295]: |
| | | - generic [ref=e296]: è´è´£äºº |
| | | - generic [ref=e297]: "-" |
| | | - generic [ref=e298]: |
| | | - generic [ref=e299]: éè´ç»ç» |
| | | - generic [ref=e300]: "-" |
| | | - generic [ref=e301]: |
| | | - generic [ref=e302]: 弿 æ¶é´ |
| | | - generic [ref=e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=e304]: |
| | | - generic [ref=e305]: å¼å§æ¶é´ |
| | | - generic [ref=e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=e307]: |
| | | - generic [ref=e308]: æªæ¢æ¶é´ |
| | | - generic [ref=e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=e313]: |
| | | - tablist [ref=e314]: |
| | | - generic [ref=e316]: |
| | | - tab [ref=e318] [cursor=pointer] |
| | | - tab [ref=e323] [cursor=pointer] |
| | | - tab [ref=e328] [cursor=pointer] |
| | | - tab [active] [selected] [ref=e333] [cursor=pointer] |
| | | - tab [ref=e338] [cursor=pointer] |
| | | - tab [ref=e343] [cursor=pointer] |
| | | - tabpanel "弿 " [ref=e406]: |
| | | - generic [ref=e407]: |
| | | - generic "å°æªå¼æ " |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: 工忰ååMOMç³»ç» |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f1e7]: |
| | | - complementary [ref=f1e8]: |
| | | - generic [ref=f1e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=f1e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=f1e18] |
| | | - generic [ref=f1e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=f1e22]: |
| | | - listitem [ref=f1e23]: |
| | | - generic [ref=f1e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=f1e34]: |
| | | - generic [ref=f1e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f1e43]: |
| | | - generic [ref=f1e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f1e50]: |
| | | - generic [ref=f1e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f1e57]: |
| | | - generic [ref=f1e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f1e65]: |
| | | - generic [ref=f1e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f1e74]: |
| | | - generic [ref=f1e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f1e82]: |
| | | - generic [ref=f1e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f1e89]: |
| | | - generic [ref=f1e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f1e96]: |
| | | - generic [ref=f1e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f1e103]: |
| | | - generic [ref=f1e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f1e110]: |
| | | - generic [ref=f1e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f1e117]: |
| | | - generic [ref=f1e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f1e131]: |
| | | - generic [ref=f1e132]: |
| | | - banner [ref=f1e133]: |
| | | - button [ref=f1e134] [cursor=pointer] |
| | | - button [ref=f1e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f1e142]: |
| | | - list [ref=f1e143]: |
| | | - listitem [ref=f1e144]: |
| | | - link [ref=f1e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=f1e152] |
| | | - listitem [ref=f1e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=f1e156] |
| | | - generic [ref=f1e159]: |
| | | - generic [ref=f1e161] [cursor=pointer]: |
| | | - generic [ref=f1e165]: æç´¢ |
| | | - generic [ref=f1e166]: Ctrl K |
| | | - button [ref=f1e168] [cursor=pointer] |
| | | - button "dark" [ref=f1e173] [cursor=pointer] |
| | | - button [ref=f1e182] [cursor=pointer] |
| | | - button [ref=f1e188] [cursor=pointer] |
| | | - button [ref=f1e191] [cursor=pointer] |
| | | - button [ref=f1e197] [cursor=pointer]: |
| | | - button [ref=f1e199] |
| | | - button "å·¥ä½å°" [ref=f1e203] [cursor=pointer] |
| | | - button "æºç " [ref=f1e207] [cursor=pointer] |
| | | - generic [ref=f1e214]: |
| | | - generic [ref=f1e219]: |
| | | - generic [ref=f1e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=f1e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=f1e254] [cursor=pointer] |
| | | - main [ref=f1e272]: |
| | | - generic [ref=f1e275]: |
| | | - generic [ref=f1e276]: |
| | | - button [ref=f1e277] [cursor=pointer] |
| | | - generic [ref=f1e280]: æµè¯é¡¹ç® |
| | | - generic [ref=f1e281]: æµè¯ç¼å· |
| | | - generic [ref=f1e282]: è¯æ ä¸ |
| | | - generic [ref=f1e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=f1e284] [cursor=pointer] |
| | | - generic [ref=f1e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=f1e291]: |
| | | - generic [ref=f1e292]: |
| | | - generic [ref=f1e293]: é¢ç®éé¢ |
| | | - generic [ref=f1e294]: 15,000 å
|
| | | - generic [ref=f1e295]: |
| | | - generic [ref=f1e296]: è´è´£äºº |
| | | - generic [ref=f1e297]: "-" |
| | | - generic [ref=f1e298]: |
| | | - generic [ref=f1e299]: éè´ç»ç» |
| | | - generic [ref=f1e300]: "-" |
| | | - generic [ref=f1e301]: |
| | | - generic [ref=f1e302]: 弿 æ¶é´ |
| | | - generic [ref=f1e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=f1e304]: |
| | | - generic [ref=f1e305]: å¼å§æ¶é´ |
| | | - generic [ref=f1e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=f1e307]: |
| | | - generic [ref=f1e308]: æªæ¢æ¶é´ |
| | | - generic [ref=f1e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=f1e313]: |
| | | - tablist [ref=f1e314]: |
| | | - generic [ref=f1e316]: |
| | | - tab [ref=f1e318] [cursor=pointer] |
| | | - tab [ref=f1e323] [cursor=pointer] |
| | | - tab [ref=f1e328] [cursor=pointer] |
| | | - tab [ref=f1e333] [cursor=pointer] |
| | | - tab [ref=f1e338] [cursor=pointer] |
| | | - tab [active] [selected] [ref=f1e343] [cursor=pointer] |
| | | - tabpanel "宿 " [ref=f1e404]: |
| | | - generic [ref=f1e405]: |
| | | - generic "å°æªå®æ " |
| | | - button "åå»ºå®æ " [ref=f1e406] [cursor=pointer] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f1e4]: |
| | | - generic [ref=f1e7]: |
| | | - complementary [ref=f1e8]: |
| | | - generic [ref=f1e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=f1e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=f1e18] |
| | | - generic [ref=f1e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=f1e22]: |
| | | - listitem [ref=f1e23]: |
| | | - generic [ref=f1e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=f1e34]: |
| | | - generic [ref=f1e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f1e43]: |
| | | - generic [ref=f1e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f1e50]: |
| | | - generic [ref=f1e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f1e57]: |
| | | - generic [ref=f1e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f1e65]: |
| | | - generic [ref=f1e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f1e74]: |
| | | - generic [ref=f1e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f1e82]: |
| | | - generic [ref=f1e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f1e89]: |
| | | - generic [ref=f1e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f1e96]: |
| | | - generic [ref=f1e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f1e103]: |
| | | - generic [ref=f1e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f1e110]: |
| | | - generic [ref=f1e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f1e117]: |
| | | - generic [ref=f1e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f1e131]: |
| | | - generic [ref=f1e132]: |
| | | - banner [ref=f1e133]: |
| | | - button [ref=f1e134] [cursor=pointer] |
| | | - button [ref=f1e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f1e142]: |
| | | - list [ref=f1e143]: |
| | | - listitem [ref=f1e144]: |
| | | - link [ref=f1e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=f1e152] |
| | | - listitem [ref=f1e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=f1e156] |
| | | - generic [ref=f1e159]: |
| | | - generic [ref=f1e161] [cursor=pointer]: |
| | | - generic [ref=f1e165]: æç´¢ |
| | | - generic [ref=f1e166]: Ctrl K |
| | | - button [ref=f1e168] [cursor=pointer] |
| | | - button "dark" [ref=f1e173] [cursor=pointer] |
| | | - button [ref=f1e182] [cursor=pointer] |
| | | - button [ref=f1e188] [cursor=pointer] |
| | | - button [ref=f1e191] [cursor=pointer] |
| | | - button [ref=f1e197] [cursor=pointer]: |
| | | - button [ref=f1e199] |
| | | - button "å·¥ä½å°" [ref=f1e203] [cursor=pointer] |
| | | - button "æºç " [ref=f1e207] [cursor=pointer] |
| | | - generic [ref=f1e214]: |
| | | - generic [ref=f1e219]: |
| | | - generic [ref=f1e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=f1e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=f1e254] [cursor=pointer] |
| | | - main [ref=f1e272]: |
| | | - generic [ref=f1e275]: |
| | | - generic [ref=f1e276]: |
| | | - button [ref=f1e277] [cursor=pointer] |
| | | - generic [ref=f1e280]: æµè¯é¡¹ç® |
| | | - generic [ref=f1e281]: æµè¯ç¼å· |
| | | - generic [ref=f1e282]: è¯æ ä¸ |
| | | - generic [ref=f1e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=f1e284] [cursor=pointer] |
| | | - generic [ref=f1e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=f1e291]: |
| | | - generic [ref=f1e292]: |
| | | - generic [ref=f1e293]: é¢ç®éé¢ |
| | | - generic [ref=f1e294]: 15,000 å
|
| | | - generic [ref=f1e295]: |
| | | - generic [ref=f1e296]: è´è´£äºº |
| | | - generic [ref=f1e297]: "-" |
| | | - generic [ref=f1e298]: |
| | | - generic [ref=f1e299]: éè´ç»ç» |
| | | - generic [ref=f1e300]: "-" |
| | | - generic [ref=f1e301]: |
| | | - generic [ref=f1e302]: 弿 æ¶é´ |
| | | - generic [ref=f1e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=f1e304]: |
| | | - generic [ref=f1e305]: å¼å§æ¶é´ |
| | | - generic [ref=f1e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=f1e307]: |
| | | - generic [ref=f1e308]: æªæ¢æ¶é´ |
| | | - generic [ref=f1e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=f1e313]: |
| | | - tablist [ref=f1e314]: |
| | | - generic [ref=f1e316]: |
| | | - tab [ref=f1e318] [cursor=pointer] |
| | | - tab [ref=f1e323] [cursor=pointer] |
| | | - tab [ref=f1e328] [cursor=pointer] |
| | | - tab [ref=f1e333] [cursor=pointer] |
| | | - tab [ref=f1e338] [cursor=pointer] |
| | | - tab [selected] [ref=f1e343] [cursor=pointer] |
| | | - tabpanel "宿 " [ref=f1e404]: |
| | | - generic [ref=f1e405]: |
| | | - generic "å°æªå®æ " |
| | | - button "åå»ºå®æ " [active] [ref=f1e406] [cursor=pointer] |
| | | - dialog "åå»ºå®æ " [ref=f1e412]: |
| | | - document: |
| | | - generic [ref=f1e413]: |
| | | - button "Close" [ref=f1e414] [cursor=pointer]: |
| | | - img "close" [ref=f1e416] |
| | | - generic [ref=f1e419]: åå»ºå®æ |
| | | - generic [ref=f1e422]: |
| | | - generic [ref=f1e424]: |
| | | - generic "宿 ç¼å·" [ref=f1e426]: "* 宿 ç¼å·" |
| | | - textbox "å¦ AWARD2024010001" [ref=f1e430] |
| | | - generic [ref=f1e431]: |
| | | - generic [ref=f1e434]: |
| | | - generic "ä¾åºå" [ref=f1e436]: "* ä¾åºå" |
| | | - generic [ref=f1e441]: |
| | | - combobox [ref=f1e443] |
| | | - generic "0" [ref=f1e444] |
| | | - generic [ref=f1e447]: |
| | | - generic "ææ " [ref=f1e449]: "* ææ " |
| | | - generic [ref=f1e454]: |
| | | - combobox [ref=f1e456] |
| | | - generic "0" [ref=f1e457] |
| | | - generic [ref=f1e459]: |
| | | - generic "宿 éé¢" [ref=f1e461]: "* 宿 éé¢" |
| | | - generic [ref=f1e466]: |
| | | - generic [ref=f1e467]: |
| | | - generic [ref=f1e468]: |
| | | - button "Increase Value" [ref=f1e469] [cursor=pointer]: |
| | | - img "up" [ref=f1e470] |
| | | - button "Decrease Value" [ref=f1e473] [cursor=pointer]: |
| | | - img "down" [ref=f1e474] |
| | | - spinbutton "宿 éé¢" [ref=f1e478] |
| | | - generic [ref=f1e479]: å
|
| | | - generic [ref=f1e481]: |
| | | - generic "夿³¨" [ref=f1e483] |
| | | - textbox "å¦ï¼ç»¼åè¯æ 第ä¸å" [ref=f1e487] |
| | | - generic [ref=f1e488]: |
| | | - button "å æ¶" [ref=f1e489] [cursor=pointer] |
| | | - button "ç¡® å®" [ref=f1e491] [cursor=pointer] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f1e4]: |
| | | - generic [ref=f1e7]: |
| | | - complementary [ref=f1e8]: |
| | | - generic [ref=f1e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=f1e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=f1e18] |
| | | - generic [ref=f1e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=f1e22]: |
| | | - listitem [ref=f1e23]: |
| | | - generic [ref=f1e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=f1e34]: |
| | | - generic [ref=f1e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f1e43]: |
| | | - generic [ref=f1e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f1e50]: |
| | | - generic [ref=f1e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f1e57]: |
| | | - generic [ref=f1e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f1e65]: |
| | | - generic [ref=f1e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f1e74]: |
| | | - generic [ref=f1e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f1e82]: |
| | | - generic [ref=f1e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f1e89]: |
| | | - generic [ref=f1e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f1e96]: |
| | | - generic [ref=f1e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f1e103]: |
| | | - generic [ref=f1e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f1e110]: |
| | | - generic [ref=f1e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f1e117]: |
| | | - generic [ref=f1e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f1e131]: |
| | | - generic [ref=f1e132]: |
| | | - banner [ref=f1e133]: |
| | | - button [ref=f1e134] [cursor=pointer] |
| | | - button [ref=f1e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f1e142]: |
| | | - list [ref=f1e143]: |
| | | - listitem [ref=f1e144]: |
| | | - link [ref=f1e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=f1e152] |
| | | - listitem [ref=f1e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=f1e156] |
| | | - generic [ref=f1e159]: |
| | | - generic [ref=f1e161] [cursor=pointer]: |
| | | - generic [ref=f1e165]: æç´¢ |
| | | - generic [ref=f1e166]: Ctrl K |
| | | - button [ref=f1e168] [cursor=pointer] |
| | | - button "dark" [ref=f1e173] [cursor=pointer] |
| | | - button [ref=f1e182] [cursor=pointer] |
| | | - button [ref=f1e188] [cursor=pointer] |
| | | - button [ref=f1e191] [cursor=pointer] |
| | | - button [ref=f1e197] [cursor=pointer]: |
| | | - button [ref=f1e199] |
| | | - button "å·¥ä½å°" [ref=f1e203] [cursor=pointer] |
| | | - button "æºç " [ref=f1e207] [cursor=pointer] |
| | | - generic [ref=f1e214]: |
| | | - generic [ref=f1e219]: |
| | | - generic [ref=f1e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=f1e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=f1e254] [cursor=pointer] |
| | | - main [ref=f1e272]: |
| | | - generic [ref=f1e275]: |
| | | - generic [ref=f1e276]: |
| | | - button [ref=f1e277] [cursor=pointer] |
| | | - generic [ref=f1e280]: æµè¯é¡¹ç® |
| | | - generic [ref=f1e281]: æµè¯ç¼å· |
| | | - generic [ref=f1e282]: è¯æ ä¸ |
| | | - generic [ref=f1e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=f1e284] [cursor=pointer] |
| | | - generic [ref=f1e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=f1e291]: |
| | | - generic [ref=f1e292]: |
| | | - generic [ref=f1e293]: é¢ç®éé¢ |
| | | - generic [ref=f1e294]: 15,000 å
|
| | | - generic [ref=f1e295]: |
| | | - generic [ref=f1e296]: è´è´£äºº |
| | | - generic [ref=f1e297]: "-" |
| | | - generic [ref=f1e298]: |
| | | - generic [ref=f1e299]: éè´ç»ç» |
| | | - generic [ref=f1e300]: "-" |
| | | - generic [ref=f1e301]: |
| | | - generic [ref=f1e302]: 弿 æ¶é´ |
| | | - generic [ref=f1e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=f1e304]: |
| | | - generic [ref=f1e305]: å¼å§æ¶é´ |
| | | - generic [ref=f1e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=f1e307]: |
| | | - generic [ref=f1e308]: æªæ¢æ¶é´ |
| | | - generic [ref=f1e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=f1e313]: |
| | | - tablist [ref=f1e314]: |
| | | - generic [ref=f1e316]: |
| | | - tab [ref=f1e318] [cursor=pointer] |
| | | - tab [ref=f1e323] [cursor=pointer] |
| | | - tab [ref=f1e328] [cursor=pointer] |
| | | - tab [ref=f1e333] [cursor=pointer] |
| | | - tab [ref=f1e338] [cursor=pointer] |
| | | - tab [selected] [ref=f1e343] [cursor=pointer] |
| | | - tabpanel "宿 " [ref=f1e404]: |
| | | - generic [ref=f1e405]: |
| | | - generic "å°æªå®æ " |
| | | - button "åå»ºå®æ " [ref=f1e406] [cursor=pointer] |
| | | - dialog "åå»ºå®æ " [ref=f1e412]: |
| | | - document: |
| | | - generic [ref=f1e413]: |
| | | - button "Close" [ref=f1e414] [cursor=pointer]: |
| | | - img "close" [ref=f1e416] |
| | | - generic [ref=f1e419]: åå»ºå®æ |
| | | - generic [ref=f1e422]: |
| | | - generic [ref=f1e424]: |
| | | - generic "宿 ç¼å·" [ref=f1e426]: "* 宿 ç¼å·" |
| | | - textbox "å¦ AWARD2024010001" [ref=f1e430] |
| | | - generic [ref=f1e431]: |
| | | - generic [ref=f1e434]: |
| | | - generic "ä¾åºå" [ref=f1e436]: "* ä¾åºå" |
| | | - generic [ref=f1e441]: |
| | | - combobox [ref=f1e443] |
| | | - generic "0" [ref=f1e444] |
| | | - generic [ref=f1e447]: |
| | | - generic "ææ " [ref=f1e449]: "* ææ " |
| | | - generic [ref=f1e454]: |
| | | - combobox [ref=f1e456] |
| | | - generic "0" [ref=f1e457] |
| | | - generic [ref=f1e459]: |
| | | - generic "宿 éé¢" [ref=f1e461]: "* 宿 éé¢" |
| | | - generic [ref=f1e466]: |
| | | - generic [ref=f1e467]: |
| | | - generic [ref=f1e468]: |
| | | - button "Increase Value" [ref=f1e469] [cursor=pointer]: |
| | | - img "up" [ref=f1e470] |
| | | - button "Decrease Value" [ref=f1e473] [cursor=pointer]: |
| | | - img "down" [ref=f1e474] |
| | | - spinbutton "宿 éé¢" [ref=f1e478] |
| | | - generic [ref=f1e479]: å
|
| | | - generic [ref=f1e481]: |
| | | - generic "夿³¨" [ref=f1e483] |
| | | - textbox "å¦ï¼ç»¼åè¯æ 第ä¸å" [ref=f1e487] |
| | | - generic [ref=f1e488]: |
| | | - button "å æ¶" [ref=f1e489] [cursor=pointer] |
| | | - button "ç¡® å®" [ref=f1e491] [cursor=pointer] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: 工忰ååMOMç³»ç» |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f2e7]: |
| | | - complementary [ref=f2e8]: |
| | | - generic [ref=f2e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=f2e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=f2e18] |
| | | - generic [ref=f2e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=f2e22]: |
| | | - listitem [ref=f2e23]: |
| | | - generic [ref=f2e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=f2e34]: |
| | | - generic [ref=f2e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f2e43]: |
| | | - generic [ref=f2e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f2e50]: |
| | | - generic [ref=f2e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f2e57]: |
| | | - generic [ref=f2e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f2e65]: |
| | | - generic [ref=f2e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f2e74]: |
| | | - generic [ref=f2e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f2e82]: |
| | | - generic [ref=f2e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f2e89]: |
| | | - generic [ref=f2e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f2e96]: |
| | | - generic [ref=f2e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f2e103]: |
| | | - generic [ref=f2e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f2e110]: |
| | | - generic [ref=f2e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f2e117]: |
| | | - generic [ref=f2e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f2e131]: |
| | | - generic [ref=f2e132]: |
| | | - banner [ref=f2e133]: |
| | | - button [ref=f2e134] [cursor=pointer] |
| | | - button [ref=f2e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f2e142]: |
| | | - list [ref=f2e143]: |
| | | - listitem [ref=f2e144]: |
| | | - link [ref=f2e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=f2e152] |
| | | - listitem [ref=f2e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=f2e156] |
| | | - generic [ref=f2e159]: |
| | | - generic [ref=f2e161] [cursor=pointer]: |
| | | - generic [ref=f2e165]: æç´¢ |
| | | - generic [ref=f2e166]: Ctrl K |
| | | - button [ref=f2e168] [cursor=pointer] |
| | | - button "dark" [ref=f2e173] [cursor=pointer] |
| | | - button [ref=f2e182] [cursor=pointer] |
| | | - button [ref=f2e188] [cursor=pointer] |
| | | - button [ref=f2e191] [cursor=pointer] |
| | | - button [ref=f2e197] [cursor=pointer]: |
| | | - button [ref=f2e199] |
| | | - button "å·¥ä½å°" [ref=f2e203] [cursor=pointer] |
| | | - button "æºç " [ref=f2e207] [cursor=pointer] |
| | | - generic [ref=f2e214]: |
| | | - generic [ref=f2e219]: |
| | | - generic [ref=f2e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=f2e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=f2e254] [cursor=pointer] |
| | | - main [ref=f2e272]: |
| | | - generic [ref=f2e275]: |
| | | - generic [ref=f2e276]: |
| | | - button [ref=f2e277] [cursor=pointer] |
| | | - generic [ref=f2e280]: æµè¯é¡¹ç® |
| | | - generic [ref=f2e281]: æµè¯ç¼å· |
| | | - generic [ref=f2e282]: 已宿 |
| | | - generic [ref=f2e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=f2e284] [cursor=pointer] |
| | | - generic [ref=f2e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=f2e291]: |
| | | - generic [ref=f2e292]: |
| | | - generic [ref=f2e293]: é¢ç®éé¢ |
| | | - generic [ref=f2e294]: 15,000 å
|
| | | - generic [ref=f2e295]: |
| | | - generic [ref=f2e296]: è´è´£äºº |
| | | - generic [ref=f2e297]: "-" |
| | | - generic [ref=f2e298]: |
| | | - generic [ref=f2e299]: éè´ç»ç» |
| | | - generic [ref=f2e300]: "-" |
| | | - generic [ref=f2e301]: |
| | | - generic [ref=f2e302]: 弿 æ¶é´ |
| | | - generic [ref=f2e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=f2e304]: |
| | | - generic [ref=f2e305]: å¼å§æ¶é´ |
| | | - generic [ref=f2e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=f2e307]: |
| | | - generic [ref=f2e308]: æªæ¢æ¶é´ |
| | | - generic [ref=f2e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=f2e313]: |
| | | - tablist [ref=f2e314]: |
| | | - generic [ref=f2e316]: |
| | | - tab [ref=f2e318] [cursor=pointer] |
| | | - tab [ref=f2e323] [cursor=pointer] |
| | | - tab [ref=f2e328] [cursor=pointer] |
| | | - tab [ref=f2e333] [cursor=pointer] |
| | | - tab [ref=f2e338] [cursor=pointer] |
| | | - tab [active] [selected] [ref=f2e343] [cursor=pointer] |
| | | - tabpanel "宿 " [ref=f2e350]: |
| | | - generic [ref=f2e351]: |
| | | - generic [ref=f2e353]: |
| | | - generic [ref=f2e354]: å·²å®è¡¨ |
| | | - generic [ref=f2e355]: "12" |
| | | - generic [ref=f2e357]: 10,000 å
|
| | | - text: 2026-07-29 14:52:43 |
| | | - generic [ref=f2e358]: 已宿 |
| | | - text: å¾
çæç»¼åè¯å® |
| | | - generic [ref=f2e361]: |
| | | - generic "宿 宿" |
| | | - button "çæéè´è®¢å" [ref=f2e362] [cursor=pointer] |
| | | - button "å é¤å®æ " [ref=f2e366] [cursor=pointer] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: 工忰ååMOMç³»ç» |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f3e7]: |
| | | - complementary [ref=f3e8]: |
| | | - generic [ref=f3e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=f3e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=f3e18] |
| | | - generic [ref=f3e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=f3e22]: |
| | | - listitem [ref=f3e23]: |
| | | - generic [ref=f3e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=f3e34]: |
| | | - generic [ref=f3e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f3e43]: |
| | | - generic [ref=f3e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f3e50]: |
| | | - generic [ref=f3e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f3e57]: |
| | | - generic [ref=f3e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f3e65]: |
| | | - generic [ref=f3e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f3e74]: |
| | | - generic [ref=f3e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f3e82]: |
| | | - generic [ref=f3e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f3e89]: |
| | | - generic [ref=f3e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f3e96]: |
| | | - generic [ref=f3e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f3e103]: |
| | | - generic [ref=f3e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f3e110]: |
| | | - generic [ref=f3e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f3e117]: |
| | | - generic [ref=f3e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f3e131]: |
| | | - generic [ref=f3e132]: |
| | | - banner [ref=f3e133]: |
| | | - button [ref=f3e134] [cursor=pointer] |
| | | - button [ref=f3e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f3e142]: |
| | | - list [ref=f3e143]: |
| | | - listitem [ref=f3e144]: |
| | | - link [ref=f3e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=f3e152] |
| | | - listitem [ref=f3e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=f3e156] |
| | | - generic [ref=f3e159]: |
| | | - generic [ref=f3e161] [cursor=pointer]: |
| | | - generic [ref=f3e165]: æç´¢ |
| | | - generic [ref=f3e166]: Ctrl K |
| | | - button [ref=f3e168] [cursor=pointer] |
| | | - button "dark" [ref=f3e173] [cursor=pointer] |
| | | - button [ref=f3e182] [cursor=pointer] |
| | | - button [ref=f3e188] [cursor=pointer] |
| | | - button [ref=f3e191] [cursor=pointer] |
| | | - button [ref=f3e197] [cursor=pointer]: |
| | | - button [ref=f3e199] |
| | | - button "å·¥ä½å°" [ref=f3e203] [cursor=pointer] |
| | | - button "æºç " [ref=f3e207] [cursor=pointer] |
| | | - generic [ref=f3e214]: |
| | | - generic [ref=f3e219]: |
| | | - generic [ref=f3e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=f3e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=f3e254] [cursor=pointer] |
| | | - main [ref=f3e272]: |
| | | - generic [ref=f3e275]: |
| | | - generic [ref=f3e276]: |
| | | - button [ref=f3e277] [cursor=pointer] |
| | | - generic [ref=f3e280]: æµè¯é¡¹ç® |
| | | - generic [ref=f3e281]: æµè¯ç¼å· |
| | | - generic [ref=f3e282]: 已宿 |
| | | - generic [ref=f3e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=f3e284] [cursor=pointer] |
| | | - generic [ref=f3e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=f3e291]: |
| | | - generic [ref=f3e292]: |
| | | - generic [ref=f3e293]: é¢ç®éé¢ |
| | | - generic [ref=f3e294]: 15,000 å
|
| | | - generic [ref=f3e295]: |
| | | - generic [ref=f3e296]: è´è´£äºº |
| | | - generic [ref=f3e297]: "-" |
| | | - generic [ref=f3e298]: |
| | | - generic [ref=f3e299]: éè´ç»ç» |
| | | - generic [ref=f3e300]: "-" |
| | | - generic [ref=f3e301]: |
| | | - generic [ref=f3e302]: 弿 æ¶é´ |
| | | - generic [ref=f3e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=f3e304]: |
| | | - generic [ref=f3e305]: å¼å§æ¶é´ |
| | | - generic [ref=f3e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=f3e307]: |
| | | - generic [ref=f3e308]: æªæ¢æ¶é´ |
| | | - generic [ref=f3e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=f3e313]: |
| | | - tablist [ref=f3e314]: |
| | | - generic [ref=f3e316]: |
| | | - tab [ref=f3e318] [cursor=pointer] |
| | | - tab [ref=f3e323] [cursor=pointer] |
| | | - tab [ref=f3e328] [cursor=pointer] |
| | | - tab [ref=f3e333] [cursor=pointer] |
| | | - tab [ref=f3e338] [cursor=pointer] |
| | | - tab [active] [selected] [ref=f3e343] [cursor=pointer] |
| | | - tabpanel "宿 " [ref=f3e404]: |
| | | - generic [ref=f3e405]: |
| | | - generic [ref=f3e407]: |
| | | - generic [ref=f3e408]: å·²å®è¡¨ |
| | | - generic [ref=f3e409]: "12" |
| | | - generic [ref=f3e411]: 10,000 å
|
| | | - text: 2026-07-29 14:52:43 |
| | | - generic [ref=f3e412]: å·²çæè®¢å |
| | | - text: 18综åè¯å® |
| | | - generic [ref=f3e415]: |
| | | - generic "订åå·²çæ" |
| | | - button "å é¤å®æ " [ref=f3e416] [cursor=pointer] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: 工忰ååMOMç³»ç» |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [ref=f4e7]: |
| | | - complementary [ref=f4e8]: |
| | | - generic [ref=f4e9]: |
| | | - link "工忰ååMOMç³»ç» å·¥åæ°ååMOMç³»ç»" [ref=f4e15] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - img "工忰ååMOMç³»ç»" [ref=f4e18] |
| | | - generic [ref=f4e19]: 工忰ååMOMç³»ç» |
| | | - menu [ref=f4e22]: |
| | | - listitem [ref=f4e23]: |
| | | - generic [ref=f4e24] [cursor=pointer]: æ¦è§ |
| | | - listitem [ref=f4e34]: |
| | | - generic [ref=f4e35] [cursor=pointer]: åºç¡æ°æ® |
| | | - listitem [ref=f4e43]: |
| | | - generic [ref=f4e44] [cursor=pointer]: éè´ç®¡ç |
| | | - listitem [ref=f4e50]: |
| | | - generic [ref=f4e51] [cursor=pointer]: è¥é管ç |
| | | - listitem [ref=f4e57]: |
| | | - generic [ref=f4e58] [cursor=pointer]: 设å¤ç®¡ç |
| | | - listitem [ref=f4e65]: |
| | | - generic [ref=f4e66] [cursor=pointer]: ä»å¨ç©æµ |
| | | - listitem [ref=f4e74]: |
| | | - generic [ref=f4e75] [cursor=pointer]: çäº§ç®¡æ§ |
| | | - listitem [ref=f4e82]: |
| | | - generic [ref=f4e83] [cursor=pointer]: è´¨é管ç |
| | | - listitem [ref=f4e89]: |
| | | - generic [ref=f4e90] [cursor=pointer]: åååå
¬ |
| | | - listitem [ref=f4e96]: |
| | | - generic [ref=f4e97] [cursor=pointer]: 人åèµæº |
| | | - listitem [ref=f4e103]: |
| | | - generic [ref=f4e104] [cursor=pointer]: åºç¡è®¾æ½ |
| | | - listitem [ref=f4e110]: |
| | | - generic [ref=f4e111] [cursor=pointer]: ç³»ç»ç®¡ç |
| | | - listitem [ref=f4e117]: |
| | | - generic [ref=f4e118] [cursor=pointer]: IM 峿¶é讯 |
| | | - generic [ref=f4e131]: |
| | | - generic [ref=f4e132]: |
| | | - banner [ref=f4e133]: |
| | | - button [ref=f4e134] [cursor=pointer] |
| | | - button [ref=f4e137] [cursor=pointer] |
| | | - navigation "breadcrumb" [ref=f4e142]: |
| | | - list [ref=f4e143]: |
| | | - listitem [ref=f4e144]: |
| | | - link [ref=f4e145] [cursor=pointer]: |
| | | - /url: javascript:void 0 |
| | | - listitem [ref=f4e152] |
| | | - listitem [ref=f4e155]: |
| | | - link "ææ è¯¦æ
" [disabled] [ref=f4e156] |
| | | - generic [ref=f4e159]: |
| | | - generic [ref=f4e161] [cursor=pointer]: |
| | | - generic [ref=f4e165]: æç´¢ |
| | | - generic [ref=f4e166]: Ctrl K |
| | | - button [ref=f4e168] [cursor=pointer] |
| | | - button "dark" [ref=f4e173] [cursor=pointer] |
| | | - button [ref=f4e182] [cursor=pointer] |
| | | - button [ref=f4e188] [cursor=pointer] |
| | | - button [ref=f4e191] [cursor=pointer] |
| | | - button [ref=f4e197] [cursor=pointer]: |
| | | - button [ref=f4e199] |
| | | - button "å·¥ä½å°" [ref=f4e203] [cursor=pointer] |
| | | - button "æºç " [ref=f4e207] [cursor=pointer] |
| | | - generic [ref=f4e214]: |
| | | - generic [ref=f4e219]: |
| | | - generic [ref=f4e220] [cursor=pointer]: åæé¡µ |
| | | - generic [ref=f4e238] [cursor=pointer]: ææ è¯¦æ
|
| | | - button [ref=f4e254] [cursor=pointer] |
| | | - main [ref=f4e272]: |
| | | - generic [ref=f4e275]: |
| | | - generic [ref=f4e276]: |
| | | - button [ref=f4e277] [cursor=pointer] |
| | | - generic [ref=f4e280]: æµè¯é¡¹ç® |
| | | - generic [ref=f4e281]: æµè¯ç¼å· |
| | | - generic [ref=f4e282]: 已宿 |
| | | - generic [ref=f4e283]: å
¬å¼ææ |
| | | - button "å·æ°" [ref=f4e284] [cursor=pointer] |
| | | - generic [ref=f4e290]: |
| | | - generic: |
| | | - generic "è稿" |
| | | - generic "åå¸" |
| | | - generic "ææ ä¸" |
| | | - generic "è¯æ ä¸" |
| | | - generic "已宿 " |
| | | - generic [ref=f4e291]: |
| | | - generic [ref=f4e292]: |
| | | - generic [ref=f4e293]: é¢ç®éé¢ |
| | | - generic [ref=f4e294]: 15,000 å
|
| | | - generic [ref=f4e295]: |
| | | - generic [ref=f4e296]: è´è´£äºº |
| | | - generic [ref=f4e297]: "-" |
| | | - generic [ref=f4e298]: |
| | | - generic [ref=f4e299]: éè´ç»ç» |
| | | - generic [ref=f4e300]: "-" |
| | | - generic [ref=f4e301]: |
| | | - generic [ref=f4e302]: 弿 æ¶é´ |
| | | - generic [ref=f4e303]: 2026-07-29 11:20:11 |
| | | - generic [ref=f4e304]: |
| | | - generic [ref=f4e305]: å¼å§æ¶é´ |
| | | - generic [ref=f4e306]: 2026-07-29 11:13:02 |
| | | - generic [ref=f4e307]: |
| | | - generic [ref=f4e308]: æªæ¢æ¶é´ |
| | | - generic [ref=f4e309]: 2026-07-29 19:13:06 |
| | | - generic [ref=f4e313]: |
| | | - tablist [ref=f4e314]: |
| | | - generic [ref=f4e316]: |
| | | - tab [ref=f4e318] [cursor=pointer] |
| | | - tab [ref=f4e323] [cursor=pointer] |
| | | - tab [ref=f4e328] [cursor=pointer] |
| | | - tab [ref=f4e333] [cursor=pointer] |
| | | - tab [ref=f4e338] [cursor=pointer] |
| | | - tab [selected] [ref=f4e343] [cursor=pointer] |
| | | - tabpanel "宿 " [active] [ref=f4e404]: |
| | | - generic [ref=f4e405]: |
| | | - generic [ref=f4e407]: |
| | | - generic [ref=f4e408]: AWARD2024070001 |
| | | - generic [ref=f4e409]: "12" |
| | | - generic [ref=f4e411]: 10,000 å
|
| | | - text: 2026-07-29 14:52:43 |
| | | - generic [ref=f4e412]: å·²çæè®¢å |
| | | - text: 18综åè¯å® |
| | | - generic [ref=f4e415]: |
| | | - generic "订åå·²çæ" |
| | | - button "å é¤å®æ " [ref=f4e416] [cursor=pointer] |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | - generic [active]: 工忰ååMOMç³»ç» |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å®å工忍¡å - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶å页é¢ï¼å
¨é¨æ°å»ºï¼ |
| | | |
| | | | é¡µé¢ | è·¯ç±å»ºè®® | 说æ | |
| | | |------|---------|------| |
| | | | å®åå·¥åå表 | `/aftersales/ticket` | å·¥åå表ãæç´¢ãç¶æçé | |
| | | | å®åå·¥å详æ
/ç¼è¾ | `/aftersales/ticket/detail?id=:id` | æ°å»º/ç¼è¾å·¥åãæ¥ç详æ
| |
| | | | éè´§ç³è¯·å表 | `/aftersales/return` | éè´§ç³è¯·å表ãæç´¢ | |
| | | | éè´§ç³è¯·è¯¦æ
| `/aftersales/return/detail?id=:id` | é货详æ
ãå®¡æ ¸æä½ | |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | ### æµç¨ä¸ï¼ä¸è¬é®é¢å·¥å |
| | | |
| | | ``` |
| | | å建工å â åé
å¤ç人 â é®é¢å¤å®ï¼ä¸è¬é®é¢ï¼â å¤ç â å®ç» â å
³é |
| | | ``` |
| | | |
| | | ### æµç¨äºï¼éè´§é®é¢å·¥å |
| | | |
| | | ``` |
| | | å建工å â åé
å¤ç人 â é®é¢å¤å®ï¼éè´§é®é¢ï¼ |
| | | â å建éè´§ç³è¯· â éå®å®¡æ ¸ â [MESéè´§æµç¨èªå¨æ§è¡] â 鿬¾/æ¢è´§å®æ â å®ç» â å
³é |
| | | ``` |
| | | |
| | | ### æµç¨ä¸ï¼ç»´ä¿®é®é¢å·¥å |
| | | |
| | | ``` |
| | | å建工å â åé
å¤ç人 â é®é¢å¤å®ï¼ç»´ä¿®é®é¢ï¼ |
| | | â åå»ºç»´ä¿®è®°å½ â ç»´ä¿®å®æ â å®ç» â å
³é |
| | | ``` |
| | | |
| | | ### æ°æ®å¸¦å
¥å
³ç³» |
| | | |
| | | | æ¥éª¤ | æ¥æº | 带å
¥å段 | |
| | | |------|------|----------| |
| | | | å建éè´§ç³è¯· | å·¥å详æ
| `ticketId`ã`customerId`ã`saleOrderId`ãå·¥åæç»è¡ï¼`ticketItemId`ã`itemId`ã`itemCode`ã`itemName`ï¼ | |
| | | | éè´§ç³è¯·å®¡æ¹ | éè´§ç³è¯· | `id`ï¼éè¿ URL åæ°ææé®ä¼ å
¥ï¼ | |
| | | |
| | | **éç¹è¯´æï¼** |
| | | - å建éè´§ç³è¯·æ¶ï¼ä»å·¥å详æ
页çæç»è¡ä¸çé `needReturn = true` çè¡ä½ä¸ºéè´§æç» |
| | | - éè´§æç»ä¸ç `ticketItemId` å¿
须对åºå·¥åæç»è¡ç `id` |
| | | - ç©æä¿¡æ¯ï¼`itemId`ã`itemCode`ã`itemName`ï¼ä»å·¥åæç»è¡å¸¦å
¥ï¼ä¸å
è®¸ä¿®æ¹ |
| | | - éå®åä»·ï¼`unitPrice`ï¼éè¦ä»éå®è®¢åè¡æ¥è¯¢è·åï¼å端å¯éè¿å·²æç ERP éå®è®¢åæ¥å£æ¥è¯¢ |
| | | |
| | | --- |
| | | |
| | | ## API 说æ |
| | | |
| | | ### ä¸ãå®åå·¥å |
| | | |
| | | | æ¹æ³ | è·¯å¾ | æé | 说æ | |
| | | |------|------|------|------| |
| | | | POST | `/aftersales/ticket/create` | `aftersales:ticket:create` | å建工å | |
| | | | PUT | `/aftersales/ticket/update` | `aftersales:ticket:update` | æ´æ°å·¥åï¼ä»
èç¨¿ç¶æå¯æ´æ°ï¼ | |
| | | | DELETE | `/aftersales/ticket/delete` | `aftersales:ticket:delete` | å é¤å·¥åï¼ä»
è稿/å·²åæ¶ç¶æå¯å é¤ï¼ | |
| | | | GET | `/aftersales/ticket/get` | `aftersales:ticket:query` | è·åå·¥å详æ
| |
| | | | GET | `/aftersales/ticket/page` | `aftersales:ticket:query` | å页æ¥è¯¢å·¥å | |
| | | | POST | `/aftersales/ticket/assign` | `aftersales:ticket:update` | åé
å¤ç人 | |
| | | | POST | `/aftersales/ticket/classify` | `aftersales:ticket:update` | é®é¢å¤å® | |
| | | | PUT | `/aftersales/ticket/resolve` | `aftersales:ticket:update` | å®ç»å·¥å | |
| | | | PUT | `/aftersales/ticket/close` | `aftersales:ticket:update` | å
³éå·¥å | |
| | | | PUT | `/aftersales/ticket/cancel` | `aftersales:ticket:update` | åæ¶å·¥å | |
| | | |
| | | #### 1.1 å建工å `POST /aftersales/ticket/create` |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | name | String | æ¯ | å·¥åä¸»é¢ | |
| | | | customerId | Long | æ¯ | 客æ·ç¼å· | |
| | | | contactId | Long | å¦ | è系人ç¼å· | |
| | | | saleOrderId | Long | å¦ | éå®è®¢åç¼å· | |
| | | | saleOrderNo | String | å¦ | éå®è®¢åå·ï¼åä½ï¼ä¸ saleOrderId é
å¥ä¼ å
¥ï¼ | |
| | | | contractId | Long | å¦ | ååç¼å· | |
| | | | issueDescription | String | å¦ | é®é¢æè¿° | |
| | | | remark | String | å¦ | 夿³¨ | |
| | | | items | List\<Item\> | å¦ | æç»è¡å表 | |
| | | |
| | | **Item ç»æï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | saleOrderItemId | Long | å¦ | éå®è®¢åè¡ç¼å· | |
| | | | itemId | Long | æ¯ | MDM ç©æç¼å· | |
| | | | itemCode | String | å¦ | ç©æç¼ç | |
| | | | itemName | String | å¦ | ç©æåç§° | |
| | | | batchId | Long | å¦ | çäº§æ¹æ¬¡ç¼å· | |
| | | | batchCode | String | å¦ | çäº§æ¹æ¬¡å· | |
| | | | saleQuantity | BigDecimal | å¦ | é宿°é | |
| | | | returnQuantity | BigDecimal | å¦ | éè´§æ°é | |
| | | | needRepair | Boolean | å¦ | æ¯å¦éè¦ç»´ä¿® | |
| | | | needReturn | Boolean | å¦ | æ¯å¦éè¦éè´§ | |
| | | | remark | String | å¦ | 夿³¨ | |
| | | |
| | | **请æ±ç¤ºä¾ï¼** |
| | | ```json |
| | | { |
| | | "name": "产åå¤è§ç¼ºé·æè¯", |
| | | "customerId": 1, |
| | | "contactId": 2, |
| | | "saleOrderId": 100, |
| | | "saleOrderNo": "SO202401010001", |
| | | "contractId": 50, |
| | | "issueDescription": "æ¶å°è´§ååç°äº§åè¡¨é¢æææ¾åç", |
| | | "remark": "客æ·è¦æ±å°½å¿«å¤ç", |
| | | "items": [ |
| | | { |
| | | "saleOrderItemId": 10, |
| | | "itemId": 200, |
| | | "itemCode": "MAT-001", |
| | | "itemName": "çµåå
å¨ä»¶", |
| | | "batchId": 5, |
| | | "batchCode": "BATCH-2024-001", |
| | | "saleQuantity": 100.000, |
| | | "returnQuantity": 10.000, |
| | | "needRepair": false, |
| | | "needReturn": true, |
| | | "remark": "å¤è§ç¼ºé·" |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | **ååºï¼** `{ "code": 0, "data": 1 }` â data 为æ°å»ºå·¥å ID |
| | | |
| | | #### 1.2 æ´æ°å·¥å `PUT /aftersales/ticket/update` |
| | | |
| | | 请æ±åæ°ä¸å建ç¸åï¼é¢å¤éè¦ `id` åæ®µãä»
èç¨¿ç¶æå¯æ´æ°ã |
| | | |
| | | #### 1.3 å é¤å·¥å `DELETE /aftersales/ticket/delete` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | å·¥åç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ååºï¼** `{ "code": 0, "data": true }` |
| | | |
| | | #### 1.4 è·åå·¥å详æ
`GET /aftersales/ticket/get` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | å·¥åç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ååºå段ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | id | Long | å·¥åç¼å· | |
| | | | no | String | å·¥ååå·ï¼æ ¼å¼ï¼AS + yyyyMMdd + 6ä½åºå·ï¼ | |
| | | | name | String | å·¥åä¸»é¢ | |
| | | | customerId | Long | 客æ·ç¼å· | |
| | | | customerName | String | 客æ·åç§° | |
| | | | contactId | Long | è系人ç¼å· | |
| | | | contactName | String | è系人åç§° | |
| | | | saleOrderId | Long | éå®è®¢åç¼å· | |
| | | | saleOrderNo | String | éå®è®¢åå· | |
| | | | contractId | Long | ååç¼å· | |
| | | | issueType | Integer | é®é¢ç±»åï¼1-ä¸è¬é®é¢ 2-ç»´ä¿®é®é¢ 3-éè´§é®é¢ | |
| | | | issueCategory | String | é®é¢åç±» | |
| | | | issueDescription | String | é®é¢æè¿° | |
| | | | severityLevel | Integer | 严éç¨åº¦ï¼0-轻微 1-ä¸è¬ 2-严é 3-è´å½ | |
| | | | status | Integer | ç¶æï¼è§ç¶ææä¸¾ï¼ | |
| | | | ownerUserId | Long | è´è´£äººç¨æ·ç¼å· | |
| | | | ownerUserName | String | è´è´£äººåç§° | |
| | | | handlerUserId | Long | å¤çäººç¨æ·ç¼å· | |
| | | | handlerUserName | String | å¤ç人åç§° | |
| | | | processInstanceId | String | BPM 工使µå®ä¾ç¼å· | |
| | | | returnId | Long | å
³èéè´§ç³è¯·ç¼å· | |
| | | | repairId | Long | å
³è维修记å½ç¼å· | |
| | | | resolvedTime | DateTime | è§£å³æ¶é´ | |
| | | | closedTime | DateTime | å
³éæ¶é´ | |
| | | | remark | String | 夿³¨ | |
| | | | creator | String | å建è
| |
| | | | createTime | DateTime | å建æ¶é´ | |
| | | | updater | String | æ´æ°è
| |
| | | | updateTime | DateTime | æ´æ°æ¶é´ | |
| | | | items | List\<Item\> | æç»è¡å表 | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "id": 1, |
| | | "no": "AS20260730000001", |
| | | "name": "产åå¤è§ç¼ºé·æè¯", |
| | | "customerId": 1, |
| | | "customerName": "XXç§ææéå
¬å¸", |
| | | "contactId": 2, |
| | | "contactName": "å¼ ä¸", |
| | | "saleOrderId": 100, |
| | | "saleOrderNo": "SO202401010001", |
| | | "contractId": 50, |
| | | "issueType": 3, |
| | | "issueCategory": "å¤è§ç¼ºé·", |
| | | "issueDescription": "æ¶å°è´§ååç°äº§åè¡¨é¢æææ¾åç", |
| | | "severityLevel": 1, |
| | | "status": 30, |
| | | "ownerUserId": 1, |
| | | "ownerUserName": "管çå", |
| | | "handlerUserId": 2, |
| | | "handlerUserName": "å®åä¸å", |
| | | "returnId": 1, |
| | | "items": [ |
| | | { |
| | | "id": 1, |
| | | "ticketId": 1, |
| | | "saleOrderItemId": 10, |
| | | "itemId": 200, |
| | | "itemCode": "MAT-001", |
| | | "itemName": "çµåå
å¨ä»¶", |
| | | "batchId": 5, |
| | | "batchCode": "BATCH-2024-001", |
| | | "saleQuantity": 100.000, |
| | | "returnQuantity": 10.000, |
| | | "needRepair": false, |
| | | "needReturn": true |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | #### 1.5 å页æ¥è¯¢å·¥å `GET /aftersales/ticket/page` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | pageNo | Integer | å¦ | 页ç ï¼é»è®¤ 1 | |
| | | | pageSize | Integer | å¦ | æ¯é¡µå¤§å°ï¼é»è®¤ 10 | |
| | | | no | String | å¦ | å·¥ååå· | |
| | | | name | String | å¦ | å·¥åä¸»é¢ | |
| | | | customerId | Long | å¦ | 客æ·ç¼å· | |
| | | | saleOrderId | Long | å¦ | éå®è®¢åç¼å· | |
| | | | status | Integer | å¦ | å·¥åç¶æ | |
| | | | issueType | Integer | å¦ | é®é¢ç±»å | |
| | | | sceneType | Integer | å¦ | åºæ¯ç±»åï¼1-æè´è´£ç 2-æåä¸ç 3-ä¸å±è´è´£ç 4-å
¨é¨ | |
| | | |
| | | **ååºï¼** |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "list": [ /* AfterSaleTicketRespVO æ°ç» */ ], |
| | | "total": 100 |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | **注æï¼** å页å表ååºä¸çæ¯æ¡è®°å½ç»æä¸è¯¦æ
æ¥å£ä¸è´ï¼å« `items` åå
³èåç§°åæ®µï¼ï¼ä½åè¡¨åºæ¯ä¸ `items` å¯ä¸ºç©ºã |
| | | |
| | | #### 1.6 åé
å¤ç人 `POST /aftersales/ticket/assign` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | å·¥åç¼å·ï¼Query åæ°ï¼ | |
| | | | handlerUserId | Long | æ¯ | å¤çäººç¨æ·ç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ä¸å¡è§åï¼** ä»
è稿ãå¤çä¸ç¶æå¯åé
ãåé
åç¶æèªå¨å为"å¤çä¸"ã |
| | | |
| | | #### 1.7 é®é¢å¤å® `POST /aftersales/ticket/classify` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | å·¥åç¼å·ï¼Query åæ°ï¼ | |
| | | | issueType | Integer | æ¯ | é®é¢ç±»åï¼1-ä¸è¬é®é¢ 2-ç»´ä¿®é®é¢ 3-éè´§é®é¢ | |
| | | | issueCategory | String | å¦ | é®é¢åç±»ï¼å¦"å¤è§ç¼ºé·"ã"åè½æ
é"çï¼ | |
| | | | severityLevel | Integer | å¦ | 严éç¨åº¦ï¼0-轻微 1-ä¸è¬ 2-严é 3-è´å½ | |
| | | |
| | | **ä¸å¡è§åï¼** ä»
å¤çä¸ç¶æå¯å¤å®ãå¤å®ä¸ºéè´§é®é¢åï¼åºå¼å¯¼ç¨æ·å建éè´§ç³è¯·ã |
| | | |
| | | #### 1.8 å®ç»å·¥å `PUT /aftersales/ticket/resolve` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | å·¥åç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ä¸å¡è§åï¼** ä»
å¤çä¸/å¾
éè´§/å¾
鿬¾ç¶æå¯å®ç»ã |
| | | |
| | | #### 1.9 å
³éå·¥å `PUT /aftersales/ticket/close` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | å·¥åç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ä¸å¡è§åï¼** ä»
å·²å®ç»ç¶æå¯å
³éã |
| | | |
| | | #### 1.10 åæ¶å·¥å `PUT /aftersales/ticket/cancel` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | å·¥åç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ä¸å¡è§åï¼** ä»
è稿ãå¤çä¸ç¶æå¯åæ¶ã |
| | | |
| | | --- |
| | | |
| | | ### äºãå®åéè´§ç³è¯· |
| | | |
| | | | æ¹æ³ | è·¯å¾ | æé | 说æ | |
| | | |------|------|------|------| |
| | | | POST | `/aftersales/return/create` | `aftersales:return:create` | å建éè´§ç³è¯· | |
| | | | PUT | `/aftersales/return/approve` | `aftersales:return:approve` | å®¡æ ¸éè¿ï¼è§¦å MES éè´§åï¼ | |
| | | | GET | `/aftersales/return/get` | `aftersales:return:query` | è·åé货详æ
| |
| | | | GET | `/aftersales/return/page` | `aftersales:return:query` | å页æ¥è¯¢éè´§ç³è¯· | |
| | | |
| | | #### 2.1 å建éè´§ç³è¯· `POST /aftersales/return/create` |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | ticketId | Long | æ¯ | å
³èå·¥åç¼å· | |
| | | | customerId | Long | æ¯ | 客æ·ç¼å·ï¼ä»å·¥å带å
¥ï¼ | |
| | | | saleOrderId | Long | å¦ | å
³èéå®è®¢åç¼å·ï¼ä»å·¥å带å
¥ï¼ | |
| | | | returnType | Integer | æ¯ | éè´§ç±»åï¼1-鿬¾éè´§ 2-æ¢è´§ 3-ä»
鿬¾ | |
| | | | returnReason | String | æ¯ | éè´§åå | |
| | | | defectCategory | String | å¦ | 缺é·åç±» | |
| | | | remark | String | å¦ | 夿³¨ | |
| | | | items | List\<Item\> | æ¯ | éè´§æç»è¡å表 | |
| | | |
| | | **Item ç»æï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | ticketItemId | Long | æ¯ | å·¥åæç»è¡ç¼å·ï¼å
³è after_sale_ticket_item.idï¼ | |
| | | | itemId | Long | æ¯ | MDM ç©æç¼å·ï¼ä»å·¥åæç»è¡å¸¦å
¥ï¼ | |
| | | | itemCode | String | å¦ | ç©æç¼ç | |
| | | | itemName | String | å¦ | ç©æåç§° | |
| | | | batchId | Long | å¦ | æ¹æ¬¡ç¼å· | |
| | | | batchCode | String | å¦ | æ¹æ¬¡å· | |
| | | | returnQuantity | BigDecimal | æ¯ | éè´§æ°é | |
| | | | unitPrice | BigDecimal | æ¯ | éå®åä»·ï¼éä»éå®è®¢åè¡æ¥è¯¢è·åï¼ | |
| | | | returnPrice | BigDecimal | å¦ | éè´§éé¢ï¼= returnQuantity à unitPriceï¼ | |
| | | | remark | String | å¦ | 夿³¨ | |
| | | |
| | | **请æ±ç¤ºä¾ï¼** |
| | | ```json |
| | | { |
| | | "ticketId": 1, |
| | | "customerId": 1, |
| | | "saleOrderId": 100, |
| | | "returnType": 1, |
| | | "returnReason": "产åå¤è§ç¼ºé·", |
| | | "defectCategory": "å¤è§ç¼ºé·", |
| | | "remark": "客æ·è¦æ±éè´§éæ¬¾", |
| | | "items": [ |
| | | { |
| | | "ticketItemId": 1, |
| | | "itemId": 200, |
| | | "itemCode": "MAT-001", |
| | | "itemName": "çµåå
å¨ä»¶", |
| | | "batchId": 5, |
| | | "batchCode": "BATCH-2024-001", |
| | | "returnQuantity": 10.000, |
| | | "unitPrice": 100.00, |
| | | "returnPrice": 1000.00 |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | **ååºï¼** `{ "code": 0, "data": 1 }` â data 为æ°å»ºéè´§ç³è¯· ID |
| | | |
| | | **ä¸å¡è§åï¼** |
| | | - å建éè´§ç³è¯·åï¼å
³èå·¥åç¶æèªå¨å为"å¾
éè´§(30)" |
| | | - `returnPrice` å端ä¼èªå¨è®¡ç®ï¼`returnQuantity à unitPrice` æ±åï¼ï¼å端å¯ä¸ä¼ |
| | | |
| | | #### 2.2 å®¡æ ¸éè¿ `PUT /aftersales/return/approve` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | éè´§ç³è¯·ç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ä¸å¡è§åï¼** |
| | | - ä»
èç¨¿ç¶æ(0)å¯å®¡æ ¸ |
| | | - å®¡æ ¸éè¿åï¼å端èªå¨è°ç¨ MES å建éå®éè´§åï¼ç¶æå为"å®¡æ ¸éè¿-已忥MES(20)" |
| | | - åç» MES éè´§æµç¨ï¼è´¨æ£âå
¥åºâ鿬¾ï¼ç±å端åè°èªå¨å®æï¼å端æ éæä½ |
| | | |
| | | #### 2.3 è·åé货详æ
`GET /aftersales/return/get` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | id | Long | æ¯ | éè´§ç³è¯·ç¼å·ï¼Query åæ°ï¼ | |
| | | |
| | | **ååºåæ®µï¼æ°å¢/éè¦å段ï¼ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | id | Long | éè´§ç³è¯·ç¼å· | |
| | | | no | String | éè´§åå·ï¼æ ¼å¼ï¼RT + yyyyMMdd + 6ä½åºå·ï¼ | |
| | | | ticketId | Long | å
³èå·¥åç¼å· | |
| | | | customerId | Long | 客æ·ç¼å· | |
| | | | customerName | String | 客æ·åç§° | |
| | | | saleOrderId | Long | éå®è®¢åç¼å· | |
| | | | returnType | Integer | éè´§ç±»å | |
| | | | returnReason | String | éè´§åå | |
| | | | defectCategory | String | 缺é·åç±» | |
| | | | totalReturnPrice | BigDecimal | åºéæ»éé¢ | |
| | | | actualRefundPrice | BigDecimal | å®ééé¢ | |
| | | | status | Integer | ç¶æï¼è§éè´§ç¶ææä¸¾ï¼ | |
| | | | auditUserId | Long | å®¡æ ¸äºº | |
| | | | auditTime | DateTime | å®¡æ ¸æ¶é´ | |
| | | | mesReturnId | Long | MESéè´§åç¼å· | |
| | | | mesReturnCode | String | MESéè´§åå· | |
| | | | qualityResult | String | è´¨æ£ç»è®º | |
| | | | qualityReportUrl | String | è´¨æ£æ¥åéä»¶URL | |
| | | | returnInboundTime | DateTime | éè´§å
¥åºå®ææ¶é´ | |
| | | | refundTime | DateTime | 鿬¾å®ææ¶é´ | |
| | | | items | List\<Item\> | éè´§æç»è¡ | |
| | | |
| | | #### 2.4 å页æ¥è¯¢éè´§ç³è¯· `GET /aftersales/return/page` |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | pageNo | Integer | å¦ | 页ç | |
| | | | pageSize | Integer | å¦ | æ¯é¡µå¤§å° | |
| | | | no | String | å¦ | éè´§åå· | |
| | | | ticketId | Long | å¦ | å
³èå·¥åç¼å· | |
| | | | customerId | Long | å¦ | 客æ·ç¼å· | |
| | | | status | Integer | å¦ | éè´§ç¶æ | |
| | | | sceneType | Integer | å¦ | åºæ¯ç±»å | |
| | | |
| | | --- |
| | | |
| | | ## æä¸¾å¼éæ¥ |
| | | |
| | | ### å·¥åç¶æ (AfterSaleTicketStatusEnum) |
| | | |
| | | | å¼ | åç§° | 说æ | |
| | | |----|------|------| |
| | | | 0 | è稿 | å¯ç¼è¾ãå¯å é¤ãå¯åæ¶ | |
| | | | 10 | å¤çä¸ | å¯åé
ãå¯å¤å®ãå¯åæ¶ | |
| | | | 30 | å¾
éè´§ | éè´§æµç¨è¿è¡ä¸ | |
| | | | 40 | å¾
鿬¾/æ¢è´§ | çå¾
鿬¾ææ¢è´§å®æ | |
| | | | 50 | å·²å®ç» | å¯å
³é | |
| | | | 60 | å·²å
³é | ç»æ | |
| | | | 99 | 已忶 | ç»æ | |
| | | |
| | | ### é®é¢ç±»å (AfterSaleIssueTypeEnum) |
| | | |
| | | | å¼ | åç§° | åç»æä½ | |
| | | |----|------|----------| |
| | | | 0 | æªå¤å® | åå»ºå·¥åæ¶çåå§å¼ | |
| | | | 1 | ä¸è¬é®é¢ | ç´æ¥å¤çâå®ç» | |
| | | | 2 | ç»´ä¿®é®é¢ | å建维修记å½âç»´ä¿®å®æâå®ç» | |
| | | | 3 | éè´§é®é¢ | å建éè´§ç³è¯·âå®¡æ ¸âMESéè´§âå®ç» | |
| | | |
| | | ### éè´§ç¶æ (AfterSaleReturnStatusEnum) |
| | | |
| | | | å¼ | åç§° | 说æ | |
| | | |----|------|------| |
| | | | 0 | è稿 | å¯å®¡æ ¸ | |
| | | | 10 | éå®å®¡æ ¸ä¸ | â | |
| | | | 20 | å®¡æ ¸éè¿-已忥MES | çå¾
MESå¤ç | |
| | | | 30 | æ£éªä¸ | MESè´¨æ£è¿è¡ä¸ | |
| | | | 40 | æ£éªå®æ | çå¾
å
¥åº | |
| | | | 50 | å·²å
¥åº | çå¾
鿬¾ | |
| | | | 60 | 鿬¾/æ¢è´§å®æ | â | |
| | | | 70 | å·²å
³é | ç»æ | |
| | | | 99 | 已忶 | ç»æ | |
| | | |
| | | ### éè´§ç±»å |
| | | |
| | | | å¼ | åç§° | |
| | | |----|------| |
| | | | 1 | 鿬¾éè´§ | |
| | | | 2 | æ¢è´§ | |
| | | | 3 | ä»
鿬¾ | |
| | | |
| | | ### 严éç¨åº¦ |
| | | |
| | | | å¼ | åç§° | 建议é¢è² | |
| | | |----|------|----------| |
| | | | 0 | 轻微 | ç»¿è² | |
| | | | 1 | ä¸è¬ | èè² | |
| | | | 2 | 严é | æ©è² | |
| | | | 3 | è´å½ | çº¢è² | |
| | | |
| | | ### åºæ¯ç±»å (sceneType) |
| | | |
| | | | å¼ | åç§° | 说æ | |
| | | |----|------|------| |
| | | | 1 | æè´è´£ç | å½åç¨æ·ä¸ºè´è´£äºº | |
| | | | 2 | æåä¸ç | å½åç¨æ·ä¸ºå¤ç人æè¢«ææ | |
| | | | 3 | ä¸å±è´è´£ç | ä¸å±ä¸ºè´è´£äºº | |
| | | | 4 | å
¨é¨ | 管çåæ¥çææ | |
| | | |
| | | --- |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | ### å·¥åå表页 |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | no | å表 | åå·ï¼å¯ç¹å»è¿å
¥è¯¦æ
| |
| | | | name | å表 | å·¥åä¸»é¢ | |
| | | | customerName | å表 | 客æ·åç§° | |
| | | | saleOrderNo | å表 | éå®è®¢åå· | |
| | | | issueType | å表 | é®é¢ç±»åï¼ç¨æ ç¾åºåé¢è² | |
| | | | severityLevel | å表 | 严éç¨åº¦ï¼ç¨æ ç¾åºåé¢è² | |
| | | | status | å表 | ç¶æï¼ç¨æ ç¾åºåé¢è² | |
| | | | ownerUserName | å表 | è´è´£äºº | |
| | | | handlerUserName | å表 | å¤ç人 | |
| | | | createTime | å表 | å建æ¶é´ | |
| | | | â | æç´¢åº | åå·ã主é¢ã客æ·ã订åãç¶æãé®é¢ç±»å | |
| | | | â | æç´¢åº | åºæ¯ç±»å Tabï¼æè´è´£ç/æåä¸ç/ä¸å±è´è´£ç/å
¨é¨ | |
| | | |
| | | ### å·¥å详æ
页 |
| | | |
| | | | åæ®µ | å±ç¤ºåºå | 说æ | |
| | | |------|----------|------| |
| | | | no | å¤´é¨ | åå· | |
| | | | name | å¤´é¨ | å·¥åä¸»é¢ | |
| | | | status | å¤´é¨ | ç¶ææ ç¾ + ç¶ææµè½¬æé® | |
| | | | customerId / customerName | åºæ¬ä¿¡æ¯ | 客æ·éæ©å¨ï¼å建æ¶å¯éï¼å建ååªè¯»ï¼ | |
| | | | contactId / contactName | åºæ¬ä¿¡æ¯ | èç³»äººéæ©å¨ | |
| | | | saleOrderId / saleOrderNo | åºæ¬ä¿¡æ¯ | éå®è®¢åéæ©å¨ | |
| | | | contractId | åºæ¬ä¿¡æ¯ | ååéæ©å¨ | |
| | | | issueType | åºæ¬ä¿¡æ¯ | é®é¢ç±»åï¼å¤å®åæ¾ç¤ºï¼ | |
| | | | issueCategory | åºæ¬ä¿¡æ¯ | é®é¢åç±»ï¼å¤å®åæ¾ç¤ºï¼ | |
| | | | issueDescription | åºæ¬ä¿¡æ¯ | é®é¢æè¿° | |
| | | | severityLevel | åºæ¬ä¿¡æ¯ | 严éç¨åº¦ï¼å¤å®åæ¾ç¤ºï¼ | |
| | | | ownerUserId / ownerUserName | åºæ¬ä¿¡æ¯ | è´è´£äººï¼å建æ¶èªå¨è®¾ä¸ºå½åç¨æ·ï¼ | |
| | | | handlerUserId / handlerUserName | åºæ¬ä¿¡æ¯ | å¤ç人ï¼åé
åæ¾ç¤ºï¼ | |
| | | | returnId | åºæ¬ä¿¡æ¯ | å
³èéè´§ç³è¯·ï¼å¯ç¹å»è·³è½¬ï¼ | |
| | | | repairId | åºæ¬ä¿¡æ¯ | å
³è维修记å½ï¼å¯ç¹å»è·³è½¬ï¼ | |
| | | | resolvedTime | åºæ¬ä¿¡æ¯ | è§£å³æ¶é´ï¼å®ç»åæ¾ç¤ºï¼ | |
| | | | closedTime | åºæ¬ä¿¡æ¯ | å
³éæ¶é´ï¼å
³éåæ¾ç¤ºï¼ | |
| | | | remark | åºæ¬ä¿¡æ¯ | 夿³¨ | |
| | | | items | æç»è¡¨æ ¼ | ç©æãæ¹æ¬¡ãé宿°éãéè´§æ°éãæ¯å¦ç»´ä¿®ãæ¯å¦éè´§ | |
| | | | createTime / creator | åºé¨ä¿¡æ¯ | åå»ºä¿¡æ¯ | |
| | | | updateTime / updater | åºé¨ä¿¡æ¯ | æ´æ°ä¿¡æ¯ | |
| | | |
| | | ### éè´§ç³è¯·å表页 |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | no | å表 | éè´§åå· | |
| | | | ticketId | å表 | å
³èå·¥åç¼å·ï¼å¯ç¹å»è·³è½¬ï¼ | |
| | | | customerName | å表 | 客æ·åç§° | |
| | | | returnType | å表 | éè´§ç±»åæ ç¾ | |
| | | | totalReturnPrice | å表 | åºéæ»éé¢ | |
| | | | actualRefundPrice | å表 | å®ééé¢ | |
| | | | status | å表 | ç¶ææ ç¾ | |
| | | | mesReturnCode | å表 | MESéè´§åå· | |
| | | | qualityResult | å表 | è´¨æ£ç»è®º | |
| | | | createTime | å表 | å建æ¶é´ | |
| | | |
| | | ### éè´§ç³è¯·è¯¦æ
页 |
| | | |
| | | | åæ®µ | å±ç¤ºåºå | 说æ | |
| | | |------|----------|------| |
| | | | no | å¤´é¨ | éè´§åå· | |
| | | | status | å¤´é¨ | ç¶ææ ç¾ + å®¡æ ¸æé®ï¼èç¨¿ç¶ææ¾ç¤ºï¼ | |
| | | | ticketId | åºæ¬ä¿¡æ¯ | å
³èå·¥åï¼å¯ç¹å»è·³è½¬ï¼ | |
| | | | customerName | åºæ¬ä¿¡æ¯ | 客æ·åç§° | |
| | | | saleOrderId | åºæ¬ä¿¡æ¯ | éå®è®¢å | |
| | | | returnType | åºæ¬ä¿¡æ¯ | éè´§ç±»å | |
| | | | returnReason | åºæ¬ä¿¡æ¯ | éè´§åå | |
| | | | defectCategory | åºæ¬ä¿¡æ¯ | 缺é·åç±» | |
| | | | totalReturnPrice | åºæ¬ä¿¡æ¯ | åºéæ»éé¢ | |
| | | | actualRefundPrice | åºæ¬ä¿¡æ¯ | å®ééé¢ | |
| | | | mesReturnId / mesReturnCode | MESä¿¡æ¯ | MESéè´§å | |
| | | | qualityResult | MESä¿¡æ¯ | è´¨æ£ç»è®º | |
| | | | qualityReportUrl | MESä¿¡æ¯ | è´¨æ£æ¥å龿¥ | |
| | | | returnInboundTime | MESä¿¡æ¯ | å
¥åºæ¶é´ | |
| | | | refundTime | 鿬¾ä¿¡æ¯ | 鿬¾æ¶é´ | |
| | | | items | æç»è¡¨æ ¼ | ç©æãæ¹æ¬¡ãéè´§æ°éãåä»·ãéè´§éé¢ | |
| | | | createTime / creator | åºé¨ä¿¡æ¯ | åå»ºä¿¡æ¯ | |
| | | |
| | | --- |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | ### å·¥åæä½æé®æ¾éè§å |
| | | |
| | | | æä½ | è稿(0) | å¤çä¸(10) | å¾
éè´§(30) | å¾
鿬¾(40) | å·²å®ç»(50) | å·²å
³é(60) | 已忶(99) | |
| | | |------|---------|------------|------------|------------|------------|------------|------------| |
| | | | ç¼è¾ | â
| â | â | â | â | â | â | |
| | | | å é¤ | â
| â | â | â | â | â | â
| |
| | | | åé
å¤ç人 | â
| â
| â | â | â | â | â | |
| | | | é®é¢å¤å® | â | â
| â | â | â | â | â | |
| | | | å建éè´§ç³è¯· | â | â
(å¤å®ä¸ºéè´§å) | â | â | â | â | â | |
| | | | å®ç» | â | â
| â
| â
| â | â | â | |
| | | | å
³é | â | â | â | â | â
| â | â | |
| | | | åæ¶ | â
| â
| â | â | â | â | â | |
| | | |
| | | ### éè´§ç³è¯·æä½æé®æ¾éè§å |
| | | |
| | | | æä½ | è稿(0) | å®¡æ ¸ä¸(10) | 已忥MES(20) | æ£éªä¸(30) | æ£éªå®æ(40) | å·²å
¥åº(50) | 鿬¾å®æ(60) | |
| | | |------|---------|------------|---------------|------------|--------------|------------|--------------| |
| | | | å®¡æ ¸éè¿ | â
| â | â | â | â | â | â | |
| | | | æ¥ç详æ
| â
| â
| â
| â
| â
| â
| â
| |
| | | |
| | | ### å页æ¥è¯¢æ°æ®æé说æ |
| | | |
| | | - **sceneType=1ï¼æè´è´£çï¼**ï¼æ¾ç¤ºå½åç¨æ·ä¸º `ownerUserId` çå·¥å + æ°æ®äº¤æ¥çå·¥å |
| | | - **sceneType=2ï¼æåä¸çï¼**ï¼æ¾ç¤ºå½åç¨æ·æè¯»/åæéçå·¥å |
| | | - **sceneType=3ï¼ä¸å±è´è´£çï¼**ï¼æ¾ç¤ºå½åç¨æ·çä¸å±è´è´£çå·¥å |
| | | - **sceneType=4ï¼å
¨é¨ï¼**ï¼éè¦ç®¡çåæéï¼`aftersales:admin`ï¼ |
| | | |
| | | --- |
| | | |
| | | ## æä»¶ä¸ä¼ |
| | | |
| | | å®å模å使ç¨ç»ä¸çæä»¶ä¸ä¼ æºå¶ï¼ä¸èªè¡å®ç°ä¸ä¼ æ¥å£ã |
| | | |
| | | **ä¸ä¼ æµç¨ï¼** |
| | | 1. è°ç¨ `POST /system/storage-blob/upload` ä¸ä¼ æä»¶ â è·å¾ `blobId` |
| | | 2. è°ç¨ `POST /system/storage-attachment/bind` ç»å®å°ä¸å¡è®°å½ |
| | | |
| | | **recordType åå¼ï¼** |
| | | |
| | | | ä¸å¡å¯¹è±¡ | recordType | |
| | | |----------|------------| |
| | | | å®åå·¥å | `aftersales_ticket` | |
| | | | å®åéè´§ç³è¯· | `aftersales_return` | |
| | | |
| | | **æ¥è¯¢éä»¶ï¼** `GET /system/storage-attachment/list?recordType=aftersales_ticket&recordId=1` |
| | | |
| | | --- |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | 1. **æç»è¡æ´æ°çç¥**ï¼æ´æ°å·¥åæ¶ï¼æç»è¡éç¨"å
å åå¢"çç¥ï¼å端å¿
é¡»ä¼ å
¥å®æ´çæç»è¡å表ï¼å
æ¬æªä¿®æ¹çè¡ï¼ï¼å¦åä¼å¯¼è´æç»è¡ä¸¢å¤±ã |
| | | 2. **åå·çæ**ï¼å·¥ååå·ï¼ASåç¼ï¼åéè´§åå·ï¼RTåç¼ï¼ç±å端èªå¨çæï¼å端ä¸éè¦ä¼ å
¥ã |
| | | 3. **ç¶ææµè½¬**ï¼ææç¶æåæ´æä½ï¼åé
ãå¤å®ãå®ç»ãå
³éãåæ¶ãå®¡æ ¸ï¼å端é½ä¼æ ¡éªå½åç¶ææ¯å¦å
许ï¼åç«¯åºæ ¹æ®æé®æ¾éè§åæ§å¶æä½å
¥å£ã |
| | | 4. **éè´§å®¡æ ¸åèªå¨åæ¥ MES**ï¼å®¡æ ¸éè¿éè´§ç³è¯·åï¼å端èªå¨è°ç¨ MES å建éå®éè´§åï¼åç» MES æµç¨ï¼è´¨æ£âå
¥åºâ鿬¾ï¼ç±åè°èªå¨æ¨è¿ç¶æï¼å端åªéè½®è¯¢å·æ°æ¥çææ°ç¶æã |
| | | 5. **æ°æ®å¸¦å
¥**ï¼å建éè´§ç³è¯·æ¶ï¼å¿
é¡»ä»å·¥å详æ
页跳转并带å
¥ `ticketId`ã`customerId`ã`saleOrderId` 以åå·¥åæç»è¡ä¸æ 记为"éè¦éè´§"çè¡ã |
| | | 6. **æéæ§å¶**ï¼æææ¥å£é½æ `@PreAuthorize` æéæ ¡éªï¼å端èååæé®éè¦å¯¹åºé
ç½®æéæ è¯ã |
| | | 7. **è·¯ç±æé**ï¼éå¨ `src/router/routes/modules/` 䏿°å»º `aftersales.ts` è·¯ç±æ¨¡åæä»¶ï¼å¹¶å¨èå䏿³¨å"å®åæå¡"ä¸çº§èåã |
| | | 8. **API 模å**ï¼éå¨ `src/api/` 䏿°å»º `aftersales/` ç®å½ï¼å建 `ticket.ts` å `return.ts` 两个 API æä»¶ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ¥çå
¨é¨å®¢æ·æé - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | | é¡µé¢ | è·¯ç±è·¯å¾ | 说æ | |
| | | |------|----------|------| |
| | | | 客æ·ç®¡çå表 | `/crm/customer` | 客æ·åè¡¨é¡µï¼æ°å¢"å
¨é¨"Tab | |
| | | |
| | | --- |
| | | |
| | | ## API |
| | | |
| | | ### å·²ææ¥å£ï¼å®¢æ·å页æ¥è¯¢ï¼æ 鿰墿¥å£ï¼ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/crm/customer/page` | 客æ·å页æ¥è¯¢ | |
| | | |
| | | **å·²æè¯·æ±åæ°ï¼`CrmCustomerPageReqVO`ï¼ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | sceneType | Integer | å¦ | åºæ¯ç±»åï¼1-æè´è´£ç / 2-æåä¸ç / 3-ä¸å±è´è´£ç / **4-å
¨é¨ï¼æ°å¢ï¼** | |
| | | | name | String | å¦ | 客æ·åç§°ï¼æ¨¡ç³ï¼ | |
| | | | mobile | String | å¦ | ææº | |
| | | | industryId | Integer | å¦ | æå±è¡ä¸ | |
| | | | level | Integer | å¦ | 客æ·ç级 | |
| | | | source | Integer | å¦ | å®¢æ·æ¥æº | |
| | | | pool | Boolean | å¦ | æ¯å¦ä¸ºå
¬æµ·æ°æ® | |
| | | | followUpStatus | Boolean | å¦ | è·è¿ç¶æ | |
| | | |
| | | **ååºæ åå**ï¼`CrmCustomerRespVO` å·²å
å«ï¼ |
| | | - `ownerUserName` â éå®äººååç§° |
| | | - `ownerUserDeptName` â éå®äººåé¨é¨åç§° |
| | | |
| | | --- |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | ### åºæ¯ç±»åæ©å± |
| | | |
| | | | sceneType å¼ | åºæ¯åç§° | æ°æ®èå´ | æéè¦æ± | |
| | | |--------------|----------|----------|----------| |
| | | | 1 | æè´è´£ç | `owner_user_id = å½åç¨æ·` | `crm:customer:query` | |
| | | | 2 | æåä¸ç | å¢éæåï¼éè´è´£äººï¼ | `crm:customer:query` | |
| | | | 3 | ä¸å±è´è´£ç | ä¸å±ä¸ºè´è´£äºº | `crm:customer:query` | |
| | | | **4ï¼æ°å¢ï¼** | **å
¨é¨** | **ææå®¢æ·ï¼æ è¿æ»¤ï¼** | **`crm:customer:view-all` æ `crm_admin` è§è²** | |
| | | |
| | | ### æéé级è§å |
| | | |
| | | å½ç¨æ·ä»¥ `sceneType=4` è¯·æ±æ°æ®æ¶ï¼ |
| | | - ç¨æ·æ¥æ `crm:customer:view-all` æé **æ** `crm_admin` è§è² â è¿åå
¨é¨å®¢æ· |
| | | - ç¨æ·**没æ**该æé â èªå¨é级为"æè´è´£ç"ï¼`sceneType=1`ï¼ï¼ä»
è¿åèªå·±çå®¢æ· |
| | | |
| | | ### æéæ è¯ |
| | | |
| | | | æéæ è¯ | 说æ | æå±èå | |
| | | |----------|------|----------| |
| | | | `crm:customer:view-all` | æ¥çå
¨é¨å®¢æ· | CRM 客æ·å
¬æµ· | |
| | | |
| | | 该æé已添å å°æ°æ®åº `system_menu` 表ï¼ä½äºã客æ·å
¬æµ·ãèåä¸ï¼id=602583ï¼ï¼è§è²åé
åå³å¯çæã |
| | | |
| | | --- |
| | | |
| | | ## å端修æ¹ç¹ |
| | | |
| | | ### 1. 客æ·å表页 Tab 忢 |
| | | |
| | | å¨ç°æçåºæ¯ç±»å Tabï¼æè´è´£ç/æåä¸ç/ä¸å±è´è´£çï¼åé¢ï¼æ°å¢"å
¨é¨"Tabï¼`sceneType=4`ï¼ã |
| | | |
| | | **å±ç¤ºè§å**ï¼ |
| | | - ä»
å½ç¨æ·æ¥æ `crm:customer:view-all` æéæ `crm_admin` è§è²æ¶ï¼ææ¾ç¤º"å
¨é¨"Tab |
| | | - 夿æ¹å¼ï¼è°ç¨æé夿æ¥å£æä»ç¨æ·æéåè¡¨ä¸æ£æ¥ |
| | | |
| | | ### 2. æé夿 |
| | | |
| | | å端éè¦å¤æå½åç¨æ·æ¯å¦æ `crm:customer:view-all` æéï¼ |
| | | - æ¹å¼ä¸ï¼éè¿ Vue æä»¤ `v-hasPermi="['crm:customer:view-all']"` æ§å¶ Tab æ¾é |
| | | - æ¹å¼äºï¼éè¿è·åç¨æ·æéåè¡¨å¤æ |
| | | |
| | | --- |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - "å
¨é¨"Tab ä»
æ§å¶æ°æ®å¯è§èå´ï¼ä¸æ¹åå
¶ä»åè½æéï¼å¦ç¼è¾ãå é¤ä»éå¯¹åºæéï¼ |
| | | - å¯¼åº Excel æ¶åæ ·æ¯æ `sceneType=4`ï¼æ¥ææéçç¨æ·å¯å¯¼åºå
¨é¨å®¢æ·æ°æ® |
| | | - æéæ°æ®å·²æå
¥æ°æ®åºï¼`system_menu` id=602583ï¼ï¼æ éå端é¢å¤å¤çæé注å |
| | | - 该æéä¸ `crm_admin` è§è²çåºå«ï¼`crm_admin` æ¥æææ CRM 管çæéï¼è `view-all` ä»
æ§å¶å®¢æ·åè¡¨çæ¥çèå´ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 项ç®è¯¦æ
- èµæå®¡æ ¸æ¥è¯¢ä¿®å¤ï¼å端èè°æ¹æ¡ï¼ |
| | | |
| | | ## é®é¢ |
| | | |
| | | 项ç®è¯¦æ
页"èµæå®¡æ ¸" Tab æ¥è¯¢ `/mes/pd/document-audit/page` æ¶æªä¼ å
¥ `projectId`ï¼å¯¼è´è¿åäºææé¡¹ç®çå®¡æ ¸è®°å½ï¼èéå½å项ç®çã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | | é¡µé¢ | è·¯ç± | 说æ | |
| | | |------|------|------| |
| | | | 项ç®è¯¦æ
- èµæå®¡æ ¸ Tab | `/mes/pd/project/detail/{id}` | å¾
ä¿®å¤ | |
| | | |
| | | --- |
| | | |
| | | ## API åæ´ |
| | | |
| | | `GET /mes/pd/document-audit/page` â æ°å¢è¯·æ±åæ°ï¼ |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | projectId | Long | å¦ | é¡¹ç® IDï¼ä¼ å
¥åä»
è¿å该项ç®ä¸èµæçå®¡æ ¸è®°å½ | |
| | | |
| | | **ååºç»æä¸åã** |
| | | |
| | | --- |
| | | |
| | | ## å端修æ¹ç¹ |
| | | |
| | | **æä»¶**: `src/views/mes/pd/project/modules/document-audit-list.vue` |
| | | |
| | | 该ç»ä»¶å·²éè¿ `props.projectId` æ¥æ¶äºé¡¹ç® IDï¼ä½æªä¼ ç»æ¥å£ãå¨ `proxyConfig.ajax.query` ä¸å ä¸å³å¯ï¼ |
| | | |
| | | ```typescript |
| | | // 第 62-67 è¡ï¼åæ¥çï¼ |
| | | query: async ({ page }, formValues) => { |
| | | return await getPdDocumentAuditPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | }); |
| | | }, |
| | | |
| | | // æ¹ä¸ºï¼ |
| | | query: async ({ page }, formValues) => { |
| | | return await getPdDocumentAuditPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | projectId: props.projectId, |
| | | ...formValues, |
| | | }); |
| | | }, |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - 该ç»ä»¶å¨é¡¹ç®ç¶æä¸º `PENDING_AUDIT`ï¼å¾
å®¡æ ¸ï¼æ¶å±ç¤ºï¼éè¿ props æ¥æ¶ `projectId` |
| | | - æ¹å¨ä»
éä¸è¡ï¼æ éä¿®æ¹ API å°è£
彿°æç±»åå®ä¹ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 设å¤å°è´¦æ°å¢å段 - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | | é¡µé¢ | è·¯ç±è·¯å¾ | 说æ | |
| | | |------|----------|------| |
| | | | 设å¤å°è´¦å表 | `/mes/dv-machinery` | å表æ°å¢ç鿡件ãè¡¨æ ¼å | |
| | | | 设å¤å°è´¦è¡¨å | `/mes/dv-machinery` (å¼¹çª) | æ°å¢/ç¼è¾è¡¨åä¸å¢å 3 ä¸ªåæ®µ | |
| | | | 设å¤å°è´¦å¯¼å
¥ | åä¸ï¼å¯¼å
¥å¼¹çªï¼ | Excel æ¨¡æ¿æ°å¢ 3 å | |
| | | |
| | | --- |
| | | |
| | | ## æ°å¢å段说æ |
| | | |
| | | | åæ®µ | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | `productionEfficiency` | BigDecimal | å¦ | ç产æçï¼åä½ï¼æ¯å°æ¶ç产æ°éï¼ç¨äºä¸æäº§èªå¨è®¡ç®ç产æ¶é´ | |
| | | | `conveyorBelt` | Integer | å¦ | ä¼ é履带æ°éï¼ä¾ï¼2 代表ååæç | |
| | | | `workstationId` | Long | å¦ | å·¥ä½ç«ç¼å·ï¼ç¨äºå°è®¾å¤ç»å®å°æå®å·¥ä½ç« | |
| | | |
| | | --- |
| | | |
| | | ## API |
| | | |
| | | ### å·²ææ¥å£ï¼æ éæ°å¢ï¼ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | `/mes/dv/machinery/create` | åå»ºè®¾å¤ | |
| | | | PUT | `/mes/dv/machinery/update` | æ´æ°è®¾å¤ | |
| | | | GET | `/mes/dv/machinery/get?id={id}` | è·å详æ
| |
| | | | GET | `/mes/dv/machinery/page` | å页æ¥è¯¢ | |
| | | | GET | `/mes/dv/machinery/simple-list` | ç²¾ç®å表ï¼ä¸æéé¡¹ï¼ | |
| | | | POST | `/mes/dv/machinery/import` | 导å
¥è®¾å¤ | |
| | | | GET | `/mes/dv/machinery/get-import-template` | ä¸è½½å¯¼å
¥æ¨¡æ¿ | |
| | | |
| | | ### 请æ±åæ° - å建/æ´æ°ï¼`MesDvMachinerySaveReqVO`ï¼ |
| | | |
| | | **æ°å¢å段ï¼** |
| | | |
| | | | åæ®µ | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | productionEfficiency | BigDecimal | å¦ | ç产æçï¼æ¯åéï¼ | |
| | | | conveyorBelt | Integer | å¦ | ä¼ é履带æ°é | |
| | | | workstationId | Long | å¦ | å·¥ä½ç«ç¼å· | |
| | | |
| | | ### å页æ¥è¯¢åæ°ï¼`MesDvMachineryPageReqVO`ï¼ |
| | | |
| | | **æ°å¢çéåæ®µï¼** |
| | | |
| | | | åæ®µ | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | workstationId | Long | å¦ | æå·¥ä½ç«çé | |
| | | |
| | | ### ååºï¼`MesDvMachineryRespVO`ï¼ |
| | | |
| | | **æ°å¢å段ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | productionEfficiency | BigDecimal | ç产æç | |
| | | | conveyorBelt | Integer | ä¼ é履带 | |
| | | | workstationId | Long | å·¥ä½ç«ç¼å· | |
| | | | workstationName | String | å·¥ä½ç«åç§° | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "id": 1, |
| | | "name": "CNC å å·¥ä¸å¿", |
| | | "code": "EQ-001", |
| | | "productionEfficiency": 10.5, |
| | | "conveyorBelt": 2, |
| | | "workstationId": 300, |
| | | "workstationName": "ä¸å·å·¥ä½ç«", |
| | | ... |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## å端修æ¹ç¹ |
| | | |
| | | ### 1. å表页 - çé项 |
| | | |
| | | å¨å表æç´¢æ æ°å¢"å·¥ä½ç«"䏿çéæ¡ï¼è°ç¨ `/mes/md-workstation/simple-list` è·åé项ã |
| | | |
| | | ### 2. å表页 - è¡¨æ ¼å |
| | | |
| | | | æ°å¢å | ç»å®å段 | 说æ | |
| | | |--------|----------|------| |
| | | | ç产æç | `productionEfficiency` | æ¾ç¤ºæ°å¼ | |
| | | | ä¼ é履带 | `conveyorBelt` | æ¾ç¤ºæ°å¼ | |
| | | | å·¥ä½ç« | `workstationName` | æ¾ç¤ºå·¥ä½ç«åç§° | |
| | | |
| | | ### 3. 表å页 - æ°å¢/ç¼è¾ |
| | | |
| | | å¨è¡¨å䏿°å¢ 3 ä¸ªåæ®µï¼ |
| | | |
| | | | åæ®µ | ç»ä»¶ | 说æ | |
| | | |------|------|------| |
| | | | ç产æç | `<el-input-number>` | æ¯æå°æ°ï¼åä½æç¤º"æ¯å°æ¶" | |
| | | | ä¼ é履带 | `<el-input-number>` | æ£æ´æ°ï¼æç¤º"2=ååæç" | |
| | | | å·¥ä½ç« | `<el-select>` | 䏿鿩ï¼è°ç¨å·¥ä½ç«ç²¾ç®å表æ¥å£ | |
| | | |
| | | ### 4. 导å
¥æ¨¡æ¿ |
| | | |
| | | 导å
¥ Excel æ¨¡æ¿æ°å¢ 3 åï¼å¯éåï¼ï¼ |
| | | |
| | | | åå | 说æ | |
| | | |------|------| |
| | | | ç产æç(æ¯å°æ¶) | æ°åï¼å¯é | |
| | | | ä¼ é履带 | æ´æ°ï¼å¯é | |
| | | | å·¥ä½ç«ç¼ç | å·¥ä½ç«ç¼ç ï¼å¯éï¼å¡«äºåæ ¡éªæ¯å¦åå¨ | |
| | | |
| | | --- |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | è§å | 说æ | |
| | | |------|------| |
| | | | ç产æçåä½ | åºå®ä¸º"æ¯å°æ¶ç产æ°é"ï¼åç«¯ç´æ¥å±ç¤º"æ¯å°æ¶" | |
| | | | ä¼ é履带å«ä¹ | æ°å¼ 2 代表ååæçï¼æäº§æ¶ `conveyorBelt à productionEfficiency` å¾å°æç»äº§è½ | |
| | | | å·¥ä½ç«ç»å® | ä¸å°è®¾å¤å¯ç»å®ä¸ä¸ªå·¥ä½ç«ï¼é强å¶ï¼ï¼ä¸ææ°æ®æºä¸º `/mes/md-workstation/simple-list` | |
| | | | 导å
¥æ¶å·¥ä½ç« | å¡«å
¥å·¥ä½ç«ç¼ç ï¼é IDï¼ï¼ç³»ç»èªå¨è½¬æ¢ï¼ç¼ç ä¸åå¨å导å
¥å¤±è´¥ | |
| | | |
| | | --- |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - 3 个æ°å段å为å¯éï¼ä¸å½±åç°ææ°æ® |
| | | - ç产æçè¾å
¥å»ºè®®éå¶æå°å¼ 0ï¼ä¿ç 2 ä½å°æ° |
| | | - ä¼ é履带ä»
å
è®¸æ£æ´æ° |
| | | - å·¥ä½ç«ä¸æä½¿ç¨å·²ææ¥å£ `/mes/md-workstation/simple-list`ï¼æ éæ°å¢ |
| | | - Excel 导å
¥æ¶å·¥ä½ç«åå¡«ç¼ç èé ID |
| | | - 导å
¥æ¨¡æ¿å端æ¥å£ `/mes/dv/machinery/get-import-template` ä¹ä¼è¿åæ°å |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ç产æµç¨ - æ¥ç产åè®¾è®¡å½æ¡£åéä»¶ï¼å端èè°æ¹æ¡ï¼ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | | é¡µé¢ | è·¯ç±è·¯å¾ | 说æ | |
| | | |------|----------|------| |
| | | | ç产工åå表/详æ
| `/mes/pro-workorder` | æ°å¢"æ¥ç彿¡£"æé® | |
| | | | ç产工åä¸å¿ | `/mes/workorder-center` | æ°å¢"æ¥ç彿¡£"æé® | |
| | | | ç产任å¡å表/详æ
| `/mes/pro-task` | æ°å¢"æ¥ç彿¡£"æé® | |
| | | | å¾
æ¥å·¥å°è´¦ | `/mes/pro-task` (pending-feedback) | æ°å¢"æ¥ç彿¡£"æé® | |
| | | | ç产æ¥å·¥å表/详æ
| `/mes/pro-feedback` | æ°å¢"æ¥ç彿¡£"æé® | |
| | | |
| | | --- |
| | | |
| | | ## APIï¼å·²ææ¥å£ï¼æ éæ°å¢ï¼ |
| | | |
| | | ### 彿¡£å页å表 |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/mes/pd/archive/page` | æäº§åç¼ç çé彿¡£å表 | |
| | | |
| | | **请æ±åæ°ï¼å
³é®ï¼ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | productCode | String | æ¯ | 产åç¼ç ï¼ä»å½åè®°å½ç `itemCode` æ `productCode` ä¼ å
¥ | |
| | | | pageNo | Integer | å¦ | 页ç | |
| | | | pageSize | Integer | å¦ | æ¯é¡µæ¡æ° | |
| | | |
| | | ### 彿¡£è¯¦æ
ï¼å«éä»¶ï¼ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/mes/pd/archive/detail-by-product` | æäº§åç¼ç è·å彿¡£è¯¦æ
åéä»¶ | |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | productCode | String | æ¯ | 产åç¼ç | |
| | | |
| | | **ååºç»æï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": [ |
| | | { |
| | | "project": { |
| | | "id": 1, |
| | | "taskCode": "PD2024001", |
| | | "taskName": "æ°äº§å设计任å¡", |
| | | "productCode": "P001", |
| | | "productName": "注å¡äº§åA", |
| | | "version": "V1.0", |
| | | "status": 4, |
| | | "chiefDesigner": 1, |
| | | "chiefDesignerNickname": "å¼ ä¸" |
| | | }, |
| | | "archives": [ |
| | | { |
| | | "id": 1, |
| | | "archiveCode": "ARC2024001", |
| | | "archiver": 1, |
| | | "archiverNickname": "çäº", |
| | | "archiveStatus": 1, |
| | | "archiveTime": "2024-01-15T10:30:00" |
| | | } |
| | | ], |
| | | "documents": [ |
| | | { |
| | | "id": 1, |
| | | "documentType": "1", |
| | | "documentName": "产å设计å¾", |
| | | "documentVersion": "V1.0", |
| | | "fileName": "design.pdf", |
| | | "attachmentList": [ |
| | | { |
| | | "id": "blob-id-xxx", |
| | | "name": "设计å¾çº¸.pdf", |
| | | "url": "/system/storage-blob/preview/xxx" |
| | | } |
| | | ], |
| | | "uploadUserId": 1, |
| | | "uploadUserNickname": "èµµå
", |
| | | "uploadTime": "2024-01-10T09:00:00" |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | --- |
| | | |
| | | ## æ°æ®ä¼ é |
| | | |
| | | ç产æµç¨åç¯èçè®°å½ä¸å·²å
å«äº§åç¼ç ï¼ç´æ¥ä¼ ç»å½æ¡£æ¥å£ï¼ |
| | | |
| | | | æ¥æºé¡µé¢ | åæ®µå | ä¼ ç»å½æ¡£æ¥å£ | |
| | | |----------|--------|-------------| |
| | | | ç产工å | `productCode` | `?productCode={productCode}` | |
| | | | çäº§ä»»å¡ | `itemCode` | `?productCode={itemCode}` | |
| | | | ç产æ¥å·¥ | `itemCode` | `?productCode={itemCode}` | |
| | | | å¾
æ¥å·¥å°è´¦ | `itemCode` | `?productCode={itemCode}` | |
| | | |
| | | --- |
| | | |
| | | ## å端修æ¹ç¹ |
| | | |
| | | ### 1. æ¥ç彿¡£æé® |
| | | |
| | | å¨ç产工åãä»»å¡ãæ¥å·¥å表çæä½åï¼ä»¥å详æ
é¡µï¼æ°å¢"è®¾è®¡å½æ¡£"æé®ã |
| | | |
| | | ç¹å»åå¼¹åºæ½å±æå¼¹çªï¼è°ç¨ `/mes/pd/archive/detail-by-product?productCode={code}` è·å彿¡£è¯¦æ
ã |
| | | |
| | | ### 2. å¼¹çªå
容å±ç¤º |
| | | |
| | | 以 Tab æååºå±ç¤ºä¸é¨åå
å®¹ï¼ |
| | | |
| | | | åºå | å
容 | æ°æ®æ¥æº | |
| | | |------|------|----------| |
| | | | 项ç®ä¿¡æ¯ | ä»»å¡ç¼ç ãä»»å¡åç§°ã产åç¼ç /åç§°ãçæ¬ã主设计å¸ãç¶æ | `response[].project` | |
| | | | 彿¡£è®°å½ | è¡¨æ ¼ï¼å½æ¡£ç¼å·ã彿¡£äººã彿¡£ç¶æã彿¡£æ¶é´ | `response[].archives` | |
| | | | è®¾è®¡èµæ | è¡¨æ ¼ï¼èµæç±»åãåç§°ãçæ¬ãæä»¶åï¼éä»¶å¯ç¹å»ä¸è½½/é¢è§ | `response[].documents` | |
| | | |
| | | ### 3. éä»¶å¤ç |
| | | |
| | | è®¾è®¡èµæä¸ç `attachmentList` 为éä»¶å表ï¼å
¶ä¸ `url` å¯ç´æ¥ç¨äºæä»¶é¢è§/ä¸è½½ã |
| | | |
| | | æä»¶é¢è§ URL æ ¼å¼ï¼ |
| | | - é¢è§ï¼`/system/storage-blob/preview/{fileName}` |
| | | - ä¸è½½ï¼`/system/storage-blob/download/{fileName}` |
| | | |
| | | --- |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | è§å | 说æ | |
| | | |------|------| |
| | | | äº§åæªå½æ¡£ | æ¥å£è¿å空æ°ç»ï¼å¼¹çªæç¤º"è¯¥äº§åææ è®¾è®¡å½æ¡£" | |
| | | | å¤ä¸ªé¡¹ç® | åä¸äº§åå¯è½æå¤ä¸ªè®¾è®¡é¡¹ç®ï¼æé¡¹ç®åç»å±ç¤º | |
| | | | éä»¶æé | éä»¶é¢è§/ä¸è½½èµ° system 模å Storage APIï¼æ éé¢å¤é´æ | |
| | | | 空éä»¶ | `attachmentList` å¯è½ä¸ºç©ºæ°ç»ï¼åç«¯å¤æå䏿¾ç¤ºä¸è½½é¾æ¥ | |
| | | |
| | | --- |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - å表页æä½å宽度æéï¼å»ºè®®æé®æåç®å为"彿¡£" |
| | | - `detail-by-product` æ¥å£è¿åæ°ç»ï¼ä¸ä¸ªäº§åå¯è½å¯¹åºå¤ä¸ªè®¾è®¡é¡¹ç® |
| | | - éä»¶é¢è§ä½¿ç¨ `window.open()` æå¼é¢è§ URL |
| | | - æ¥å£å·²åå¨ï¼åç«¯ç´æ¥è°ç¨ `src/api/mes/pd/archive/index.ts` ä¸çå°è£
æ¹æ³ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # çäº§ä»»å¡ - éå·¥ä½ç«èªå¨è®¡ç®ç产æ¶é¿ï¼å端èè°æ¹æ¡ï¼ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | | é¡µé¢ | è·¯ç±è·¯å¾ | 说æ | |
| | | |------|----------|------| |
| | | | ç产任å¡è¡¨å | `/mes/pro-task` (æ°å¢/ç¼è¾å¼¹çª) | 鿩工ä½ç«åèªå¨è°ç¨æ¥å£è®¡ç®ç产æ¶é¿ | |
| | | |
| | | --- |
| | | |
| | | ## API |
| | | |
| | | ### æ°å¢æ¥å£ï¼è®¡ç®ç产æ¶é¿ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/mes/pro/task/calculate-duration` | æ ¹æ®å·¥ä½ç«åæ°é计ç®ç产æ¶é¿ | |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | workstationId | Long | æ¯ | å·¥ä½ç«ç¼å· | |
| | | | quantity | BigDecimal | æ¯ | æäº§æ°é | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "duration": 3 |
| | | }, |
| | | "msg": "" |
| | | } |
| | | ``` |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | duration | Integer | ç产æ¶é¿ï¼å°æ¶ï¼ï¼æ ç»å®è®¾å¤æ¶è¿å 0 | |
| | | |
| | | --- |
| | | |
| | | ## å端修æ¹ç¹ |
| | | |
| | | ### 1. è§¦åæ¶æº |
| | | |
| | | 卿°å¢/ç¼è¾ç产任å¡ç表åä¸ï¼å½ç¨æ·**鿩工ä½ç«**æ**ä¿®æ¹æäº§æ°é**åï¼èªå¨è°ç¨è®¡ç®æ¥å£ã |
| | | |
| | | ### 2. åæ®µåå¡« |
| | | |
| | | æ¥å£è¿åç `duration` å¼èªå¨å¡«å
¥è¡¨åç"ç产æ¶é¿"åæ®µï¼æ éç¨æ·æå¨è®¡ç®ã |
| | | |
| | | ### 3. è¾¹çæ
åµ |
| | | |
| | | | åºæ¯ | è¡¨ç° | |
| | | |------|------| |
| | | | æªéå·¥ä½ç« | ä¸è°ç¨æ¥å£ | |
| | | | æªå¡«æ°é | ä¸è°ç¨æ¥å£ | |
| | | | å·¥ä½ç«æªç»å®è®¾å¤ | è¿å `duration=0`ï¼åç«¯å¯æç¤º"该工ä½ç«æªç»å®è®¾å¤" | |
| | | | è®¾å¤æªé
ç½®ç产æç | è¿å `duration=0`ï¼åç«¯å¯æç¤º"ç»å®è®¾å¤æªé
ç½®ç产æç" | |
| | | |
| | | --- |
| | | |
| | | ## 计ç®é»è¾è¯´æ |
| | | |
| | | | æ¥éª¤ | 说æ | |
| | | |------|------| |
| | | | 1 | æ¥è¯¢å·¥ä½ç«ç»å®çææè®¾å¤ | |
| | | | 2 | æ»æç = Σ(æ¯å°è®¾å¤ç `productionEfficiency` à `conveyorBelt`) | |
| | | | 3 | ä¼ é履带为 0 æç©ºæ¶é»è®¤å 1 | |
| | | | 4 | ç产æ¶é¿ï¼å°æ¶ï¼= åä¸åæ´(æäº§æ°é / æ»æç) | |
| | | |
| | | --- |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - è°ç¨æ¥å£åéç¡®ä¿ `workstationId` å `quantity` åæå¼ï¼é¿å
æ æè¯·æ± |
| | | - æ¥å£è¿å 0 æ¶ï¼å»ºè®®ç»åºå好æç¤ºï¼èééé» |
| | | - ç¨æ·ä»å¯æå¨ä¿®æ¹è®¡ç®åçç产æ¶é¿ |
| | | - 该æ¥å£ä»
ç¨äºå端è¾
å©è®¡ç®ï¼ä¸å½±åå端å建/æ´æ°ä»»å¡çä¸å¡é»è¾ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================================ |
| | | -- å®å工忍¡å DDL |
| | | -- ============================================================ |
| | | |
| | | -- 1. å®åå·¥å主表 |
| | | DROP TABLE IF EXISTS `after_sale_ticket`; |
| | | CREATE TABLE `after_sale_ticket` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'å·¥åç¼å·', |
| | | `no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'å·¥ååå·', |
| | | `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'å·¥å主é¢/æ é¢', |
| | | `customer_id` bigint NOT NULL COMMENT '客æ·ç¼å·ï¼å
³è crm_customer.id', |
| | | `contact_id` bigint DEFAULT NULL COMMENT 'è系人ç¼å·ï¼å
³è crm_contact.id', |
| | | `sale_order_id` bigint DEFAULT NULL COMMENT 'éå®è®¢åç¼å·ï¼å
³è erp_sale_order.id', |
| | | `sale_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'éå®è®¢åå·(åä½)', |
| | | `contract_id` bigint DEFAULT NULL COMMENT 'ååç¼å·ï¼å
³è crm_contract.id', |
| | | `issue_type` tinyint NOT NULL DEFAULT 0 COMMENT 'é®é¢ç±»å: 0-æªå¤å® 1-ä¸è¬é®é¢ 2-ç»´ä¿®é®é¢ 3-éè´§é®é¢', |
| | | `issue_category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'é®é¢åç±»', |
| | | `issue_description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 'é®é¢æè¿°', |
| | | `severity_level` tinyint DEFAULT 0 COMMENT '严éç¨åº¦: 0-轻微 1-ä¸è¬ 2-严é 3-è´å½', |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT 'ç¶æ: 0-è稿 10-å¤çä¸ 30-å¾
éè´§ 40-å¾
鿬¾/æ¢è´§ 50-å·²å®ç» 60-å·²å
³é 99-已忶', |
| | | `owner_user_id` bigint NOT NULL COMMENT 'è´è´£äººç¨æ·ç¼å·', |
| | | `handler_user_id` bigint DEFAULT NULL COMMENT 'å¤çäººç¨æ·ç¼å·', |
| | | `process_instance_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'BPM工使µå®ä¾ç¼å·', |
| | | `return_id` bigint DEFAULT NULL COMMENT 'å
³èéè´§ç³è¯·ç¼å·', |
| | | `repair_id` bigint DEFAULT NULL COMMENT 'å
³è维修记å½ç¼å·', |
| | | `resolved_time` datetime DEFAULT NULL COMMENT 'è§£å³æ¶é´', |
| | | `closed_time` datetime DEFAULT NULL COMMENT 'å
³éæ¶é´', |
| | | `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | UNIQUE KEY `uk_no` (`no`), |
| | | KEY `idx_customer_id` (`customer_id`), |
| | | KEY `idx_sale_order_id` (`sale_order_id`), |
| | | KEY `idx_owner_user_id` (`owner_user_id`), |
| | | KEY `idx_status` (`status`), |
| | | KEY `idx_create_time` (`create_time`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='å®åå·¥å主表'; |
| | | |
| | | -- 2. å®åå·¥åæç»è¡è¡¨ |
| | | DROP TABLE IF EXISTS `after_sale_ticket_item`; |
| | | CREATE TABLE `after_sale_ticket_item` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `ticket_id` bigint NOT NULL COMMENT 'å·¥åç¼å·ï¼å
³è after_sale_ticket.id', |
| | | `sale_order_item_id` bigint DEFAULT NULL COMMENT 'éå®è®¢åè¡ç¼å·', |
| | | `item_id` bigint NOT NULL COMMENT 'MDMç©æç¼å·', |
| | | `item_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'ç©æç¼ç (åä½)', |
| | | `item_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'ç©æåç§°(åä½)', |
| | | `batch_id` bigint DEFAULT NULL COMMENT 'çäº§æ¹æ¬¡ç¼å·', |
| | | `batch_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'çäº§æ¹æ¬¡å·', |
| | | `sale_quantity` decimal(10,3) NOT NULL DEFAULT 0.000 COMMENT 'é宿°é', |
| | | `return_quantity` decimal(10,3) DEFAULT 0.000 COMMENT 'éè´§æ°é', |
| | | `need_repair` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦éè¦ç»´ä¿®', |
| | | `need_return` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦éè¦éè´§', |
| | | `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_ticket_id` (`ticket_id`), |
| | | KEY `idx_item_id` (`item_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='å®åå·¥åæç»è¡è¡¨'; |
| | | |
| | | -- 3. éè´§ç³è¯·è¡¨ |
| | | DROP TABLE IF EXISTS `after_sale_return`; |
| | | CREATE TABLE `after_sale_return` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'éè´§ç³è¯·ç¼å·', |
| | | `no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'éè´§åå·', |
| | | `ticket_id` bigint NOT NULL COMMENT 'å
³èå·¥åç¼å·ï¼å
³è after_sale_ticket.id', |
| | | `customer_id` bigint NOT NULL COMMENT '客æ·ç¼å·', |
| | | `sale_order_id` bigint DEFAULT NULL COMMENT 'å
³èéå®è®¢åç¼å·', |
| | | `return_type` tinyint NOT NULL COMMENT 'éè´§ç±»å: 1-鿬¾éè´§ 2-æ¢è´§ 3-ä»
鿬¾', |
| | | `return_reason` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'éè´§åå ', |
| | | `defect_category` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '缺é·åç±»', |
| | | `total_return_price` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT 'åºéæ»éé¢', |
| | | `actual_refund_price` decimal(12,2) DEFAULT 0.00 COMMENT 'å®ééé¢', |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT 'ç¶æ: 0-è稿 10-éå®å®¡æ ¸ä¸ 20-å®¡æ ¸éè¿å·²åæ¥MES 30-æ£éªä¸ 40-æ£éªå®æ 50-å·²å
¥åº 60-鿬¾/æ¢è´§å®æ 70-å·²å
³é 99-已忶', |
| | | `audit_user_id` bigint DEFAULT NULL COMMENT 'å®¡æ ¸äºº', |
| | | `audit_time` datetime DEFAULT NULL COMMENT 'å®¡æ ¸æ¶é´', |
| | | `mes_return_id` bigint DEFAULT NULL COMMENT 'MESéè´§åç¼å·ï¼å
³è mes_wm_return_sales.id', |
| | | `mes_return_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'MESéè´§åå·(åä½)', |
| | | `quality_result` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'è´¨æ£ç»è®º: åæ ¼/ç¹é/éè´§/æ¥åº', |
| | | `quality_report_url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'è´¨æ£æ¥åéä»¶URL', |
| | | `return_inbound_time` datetime DEFAULT NULL COMMENT 'éè´§å
¥åºå®ææ¶é´', |
| | | `refund_time` datetime DEFAULT NULL COMMENT '鿬¾/æ¢è´§å®ææ¶é´', |
| | | `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | UNIQUE KEY `uk_no` (`no`), |
| | | KEY `idx_ticket_id` (`ticket_id`), |
| | | KEY `idx_mes_return_id` (`mes_return_id`), |
| | | KEY `idx_status` (`status`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='å®åéè´§ç³è¯·è¡¨'; |
| | | |
| | | -- 4. éè´§æç»è¡è¡¨ |
| | | DROP TABLE IF EXISTS `after_sale_return_item`; |
| | | CREATE TABLE `after_sale_return_item` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `return_id` bigint NOT NULL COMMENT 'éè´§ç³è¯·ç¼å·ï¼å
³è after_sale_return.id', |
| | | `ticket_item_id` bigint NOT NULL COMMENT 'å·¥åæç»è¡ç¼å·ï¼å
³è after_sale_ticket_item.id', |
| | | `item_id` bigint NOT NULL COMMENT 'MDMç©æç¼å·', |
| | | `item_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'ç©æç¼ç (åä½)', |
| | | `item_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'ç©æåç§°(åä½)', |
| | | `batch_id` bigint DEFAULT NULL COMMENT 'æ¹æ¬¡ç¼å·', |
| | | `batch_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'æ¹æ¬¡å·', |
| | | `return_quantity` decimal(10,3) NOT NULL COMMENT 'éè´§æ°é', |
| | | `unit_price` decimal(12,2) NOT NULL COMMENT 'éå®åä»·', |
| | | `return_price` decimal(12,2) NOT NULL COMMENT 'éè´§éé¢', |
| | | `mes_return_line_id` bigint DEFAULT NULL COMMENT 'MESéè´§åè¡ç¼å·', |
| | | `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_return_id` (`return_id`), |
| | | KEY `idx_ticket_item_id` (`ticket_item_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='å®åéè´§æç»è¡è¡¨'; |
| | | |
| | | -- 5. 维修记å½è¡¨ |
| | | DROP TABLE IF EXISTS `after_sale_repair`; |
| | | CREATE TABLE `after_sale_repair` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT '维修记å½ç¼å·', |
| | | `ticket_id` bigint NOT NULL COMMENT 'å
³èå·¥åç¼å·ï¼å
³è after_sale_ticket.id', |
| | | `repair_type` tinyint NOT NULL COMMENT '维修类å: 1-ç°åºç»´ä¿® 2-è¿åç»´ä¿® 3-è¿ç¨æå¯¼', |
| | | `fault_description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 'æ
éæè¿°', |
| | | `repair_action` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT 'ç»´ä¿®æªæ½', |
| | | `repair_result` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'ç»´ä¿®ç»æ: 已修å¤/æ æ³ä¿®å¤/é¨åä¿®å¤', |
| | | `repair_cost` decimal(10,2) DEFAULT 0.00 COMMENT '维修费ç¨', |
| | | `repair_user_id` bigint DEFAULT NULL COMMENT '维修人', |
| | | `status` tinyint NOT NULL DEFAULT 0 COMMENT 'ç¶æ: 0-å¾
å¤ç 10-ç»´ä¿®ä¸ 20-已宿 30-å·²å
³é', |
| | | `start_time` datetime DEFAULT NULL COMMENT 'å¼å§ç»´ä¿®æ¶é´', |
| | | `finish_time` datetime DEFAULT NULL COMMENT 'å®æç»´ä¿®æ¶é´', |
| | | `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_ticket_id` (`ticket_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='å®å维修记å½è¡¨'; |
| | | |
| | | -- 6. å®åæ°æ®æé表 |
| | | DROP TABLE IF EXISTS `after_sale_permission`; |
| | | CREATE TABLE `after_sale_permission` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `biz_type` tinyint NOT NULL COMMENT 'æ°æ®ç±»å: 1-å®åå·¥å 2-éè´§ç³è¯· 3-维修记å½', |
| | | `biz_id` bigint NOT NULL COMMENT 'æ°æ®ç¼å·', |
| | | `user_id` bigint NOT NULL COMMENT 'ç¨æ·ç¼å·', |
| | | `level` tinyint NOT NULL COMMENT 'æé级å«: 1-è´è´£äºº 2-åªè¯» 3-读å', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | KEY `idx_biz` (`biz_type`, `biz_id`), |
| | | KEY `idx_user` (`user_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='å®åæ°æ®æé表'; |
| | |
| | | <!-- SRM ä¾åºåå
³ç³»ç®¡ç模å --> |
| | | <module>yudao-module-srm-api</module> |
| | | <module>yudao-module-srm</module> |
| | | <!-- å®å工忍¡å --> |
| | | <module>yudao-module-aftersales-api</module> |
| | | <module>yudao-module-aftersales</module> |
| | | <!-- 请åè https://doc.iocoder.cn/ai/build/ ææ¡£ï¼å®æ AI 模åçå¯å¨ï¼ï¼ï¼ --> |
| | | <!-- <module>yudao-module-ai</module>--> |
| | | </modules> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================= |
| | | -- MES PD 产å设计模åèååå§å |
| | | -- å¨ MES ç³»ç»(5100) 䏿°å¢"产å设计"äºçº§ç®å½ |
| | | -- 设计项ç®ãè®¾è®¡å½æ¡£ä¸¤ä¸ªé¡µé¢ |
| | | -- ============================================= |
| | | |
| | | -- ä¿®æ£åæ"产å设计"(6809) å½å为"å·¥èºè®¾è®¡"ï¼é¿å
å²çªï¼å
¶å
容为工èºè®¾è®¡ï¼å·¥åºè®¾ç½®ãå·¥èºæµç¨çï¼ |
| | | UPDATE `system_menu` SET `name` = 'å·¥èºè®¾è®¡', `updater` = '1', `update_time` = NOW() WHERE `id` = 6809 AND `name` = '产å设计'; |
| | | |
| | | -- 产å设计ï¼äºçº§ç®å½ï¼æ¾å¨ MES ç³»ç»ä¸ï¼sort=25 ä½äºå·¥èºè®¾è®¡ä¹åï¼ |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (602571, '产å设计', '', 1, 25, 5100, 'pd', 'ep:design', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- 设计项ç®ï¼ä¸çº§èåï¼ |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (602572, '设计项ç®', '', 2, 1, 602571, 'project', 'ep:document', 'mes/pd/project/index', 'MesPdProject', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- è®¾è®¡é¡¹ç® - æé®æé |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES |
| | | (602573, 'è®¾è®¡é¡¹ç®æ¥è¯¢', 'mes:pd-project:query', 3, 1, 602572, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602574, '设计项ç®å建', 'mes:pd-project:create', 3, 2, 602572, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602575, 'è®¾è®¡é¡¹ç®æ´æ°', 'mes:pd-project:update', 3, 3, 602572, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602576, '设计项ç®å é¤', 'mes:pd-project:delete', 3, 4, 602572, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602577, '设计项ç®å¯¼åº', 'mes:pd-project:export', 3, 5, 602572, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- è®¾è®¡å½æ¡£ï¼ä¸çº§èåï¼ |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (602578, 'è®¾è®¡å½æ¡£', '', 2, 2, 602571, 'archive', 'ep:folder', 'mes/pd/archive/index', 'MesPdArchive', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- è®¾è®¡å½æ¡£ - æé®æé |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES |
| | | (602579, 'è®¾è®¡å½æ¡£æ¥è¯¢', 'mes:pd-archive:query', 3, 1, 602578, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602580, 'è®¾è®¡å½æ¡£æ´æ°', 'mes:pd-archive:update', 3, 2, 602578, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602581, 'è®¾è®¡å½æ¡£å é¤', 'mes:pd-archive:delete', 3, 3, 602578, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (602582, 'è®¾è®¡å½æ¡£å¯¼åº', 'mes:pd-archive:export', 3, 4, 602578, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao</artifactId> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <artifactId>yudao-module-aftersales-api</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <name>${project.artifactId}</name> |
| | | <description> |
| | | å®å工忍¡åç API æ¥å£å®ä¹ï¼ä¾å
¶ä»æ¨¡åå¼ç¨ |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-common</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Swagger 注解 --> |
| | | <dependency> |
| | | <groupId>org.springdoc</groupId> |
| | | <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> |
| | | <scope>provided</scope> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.api; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.module.aftersales.api.dto.AfterSaleReturnRespDTO; |
| | | import cn.iocoder.yudao.module.aftersales.api.dto.AfterSaleTicketRespDTO; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * å®åå·¥å API æ¥å£ï¼ä¾ MES/ERP 跨模åè°ç¨ï¼ |
| | | */ |
| | | public interface AfterSaleTicketApi { |
| | | |
| | | String PREFIX = "/rpc-api/aftersales/ticket"; |
| | | |
| | | /** |
| | | * MES éè´§è´¨æ£å®æååè° |
| | | * |
| | | * @param returnId éè´§ç³è¯·ç¼å· |
| | | * @param qualityResult è´¨æ£ç»è®º |
| | | * @param reportUrl è´¨æ£æ¥å URL |
| | | */ |
| | | CommonResult<Boolean> onReturnQualityFinished(Long returnId, String qualityResult, String reportUrl); |
| | | |
| | | /** |
| | | * MES éè´§å
¥åºå®æååè° |
| | | * |
| | | * @param returnId éè´§ç³è¯·ç¼å· |
| | | */ |
| | | CommonResult<Boolean> onReturnInboundFinished(Long returnId); |
| | | |
| | | /** |
| | | * ERP 鿬¾å®æååè° |
| | | * |
| | | * @param returnId éè´§ç³è¯·ç¼å· |
| | | * @param actualRefundPrice å®ééé¢ |
| | | */ |
| | | CommonResult<Boolean> onRefundCompleted(Long returnId, BigDecimal actualRefundPrice); |
| | | |
| | | /** |
| | | * æ¥è¯¢å®åå·¥åï¼ä¾ MES/ERP æ¥è¯¢å
³èä¿¡æ¯ï¼ |
| | | * |
| | | * @param id å·¥åç¼å· |
| | | */ |
| | | CommonResult<AfterSaleTicketRespDTO> getTicket(Long id); |
| | | |
| | | /** |
| | | * æ¥è¯¢éè´§ç³è¯·ï¼ä¾ MES/ERP æ¥è¯¢å
³èä¿¡æ¯ï¼ |
| | | * |
| | | * @param id éè´§ç³è¯·ç¼å· |
| | | */ |
| | | CommonResult<AfterSaleReturnRespDTO> getReturn(Long id); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.api.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯·ååº DTOï¼ä¾ RPC è°ç¨ä½¿ç¨ï¼ |
| | | */ |
| | | @Data |
| | | public class AfterSaleReturnRespDTO { |
| | | |
| | | private Long id; |
| | | private String no; |
| | | private Long ticketId; |
| | | private Long customerId; |
| | | private Long saleOrderId; |
| | | private Integer returnType; |
| | | private String returnReason; |
| | | private BigDecimal totalReturnPrice; |
| | | private BigDecimal actualRefundPrice; |
| | | private Integer status; |
| | | private Long mesReturnId; |
| | | private String mesReturnCode; |
| | | private String qualityResult; |
| | | private String qualityReportUrl; |
| | | private LocalDateTime returnInboundTime; |
| | | private LocalDateTime refundTime; |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.api.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å®åå·¥åååº DTOï¼ä¾ RPC è°ç¨ä½¿ç¨ï¼ |
| | | */ |
| | | @Data |
| | | public class AfterSaleTicketRespDTO { |
| | | |
| | | private Long id; |
| | | private String no; |
| | | private String name; |
| | | private Long customerId; |
| | | private Long saleOrderId; |
| | | private String saleOrderNo; |
| | | private Integer issueType; |
| | | private String issueCategory; |
| | | private String issueDescription; |
| | | private Integer severityLevel; |
| | | private Integer status; |
| | | private Long ownerUserId; |
| | | private Long handlerUserId; |
| | | private Long returnId; |
| | | private Long repairId; |
| | | private LocalDateTime resolvedTime; |
| | | private LocalDateTime createTime; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <parent> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao</artifactId> |
| | | <version>${revision}</version> |
| | | </parent> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <artifactId>yudao-module-aftersales</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <name>${project.artifactId}</name> |
| | | <description> |
| | | aftersales å
ä¸ï¼å®åæå¡ç®¡çï¼After-sales Service Managementï¼ã |
| | | ä¾å¦è¯´ï¼å®åå·¥åãéè´§ç³è¯·ã维修记å½çç |
| | | </description> |
| | | |
| | | <dependencies> |
| | | <!-- å®å API 模å --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-aftersales-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- CRM API 模å --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-crm-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-system</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-infra</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-bpm</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- MDM ä¸»æ°æ®ç®¡ç API --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-mdm-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- ERP éå®è®¢å API --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-erp-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- MES API --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-mes-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- HRM APIï¼æ°æ®äº¤æ¥ï¼ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-hrm-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- ä¸å¡ç»ä»¶ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Web ç¸å
³ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-web</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-security</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- DB ç¸å
³ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- å·¥å
·ç±»ç¸å
³ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-excel</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- Test æµè¯ç¸å
³ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-spring-boot-starter-test</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | </project> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.api; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.aftersales.api.dto.AfterSaleReturnRespDTO; |
| | | import cn.iocoder.yudao.module.aftersales.api.dto.AfterSaleTicketRespDTO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO; |
| | | import cn.iocoder.yudao.module.aftersales.service.returnobj.AfterSaleReturnService; |
| | | import cn.iocoder.yudao.module.aftersales.service.ticket.AfterSaleTicketService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | /** |
| | | * å®åå·¥å API å®ç°ç±»ï¼ä¾ MES/ERP 跨模åè°ç¨ï¼ |
| | | */ |
| | | @RestController |
| | | public class AfterSaleTicketApiImpl implements AfterSaleTicketApi { |
| | | |
| | | @Resource |
| | | private AfterSaleTicketService ticketService; |
| | | @Resource |
| | | private AfterSaleReturnService returnService; |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> onReturnQualityFinished(Long returnId, String qualityResult, String reportUrl) { |
| | | returnService.onQualityFinished(returnId, qualityResult, reportUrl); |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> onReturnInboundFinished(Long returnId) { |
| | | returnService.onInboundFinished(returnId); |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> onRefundCompleted(Long returnId, BigDecimal actualRefundPrice) { |
| | | returnService.onRefundCompleted(returnId, actualRefundPrice); |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<AfterSaleTicketRespDTO> getTicket(Long id) { |
| | | AfterSaleTicketDO ticket = ticketService.getTicket(id); |
| | | return success(BeanUtils.toBean(ticket, AfterSaleTicketRespDTO.class)); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<AfterSaleReturnRespDTO> getReturn(Long id) { |
| | | AfterSaleReturnDO returnDO = returnService.getReturn(id); |
| | | return success(BeanUtils.toBean(returnDO, AfterSaleReturnRespDTO.class)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.returnobj; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo.AfterSaleReturnPageReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo.AfterSaleReturnRespVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo.AfterSaleReturnSaveReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnItemDO; |
| | | import cn.iocoder.yudao.module.aftersales.service.returnobj.AfterSaleReturnService; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | |
| | | @Tag(name = "管çåå° - å®åéè´§ç³è¯·") |
| | | @RestController |
| | | @RequestMapping("/aftersales/return") |
| | | @Validated |
| | | public class AfterSaleReturnController { |
| | | |
| | | @Resource |
| | | private AfterSaleReturnService returnService; |
| | | |
| | | @Resource |
| | | private CrmCustomerApi customerApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建éè´§ç³è¯·") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:return:create')") |
| | | public CommonResult<Long> createReturn(@Valid @RequestBody AfterSaleReturnSaveReqVO createReqVO) { |
| | | return success(returnService.createReturn(createReqVO, getLoginUserId())); |
| | | } |
| | | |
| | | @PutMapping("/approve") |
| | | @Operation(summary = "å®¡æ ¸éè¿éè´§ç³è¯·") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:return:approve')") |
| | | public CommonResult<Boolean> approveReturn(@RequestParam("id") Long id) { |
| | | returnService.approveReturn(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾éè´§ç³è¯·") |
| | | @Parameter(name = "id", description = "éè´§ç³è¯·ç¼å·", required = true, example = "1") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:return:query')") |
| | | public CommonResult<AfterSaleReturnRespVO> getReturn(@RequestParam("id") Long id) { |
| | | AfterSaleReturnDO returnDO = returnService.getReturn(id); |
| | | List<AfterSaleReturnItemDO> items = returnService.getReturnItemListByReturnId(id); |
| | | List<AfterSaleReturnRespVO> enrichedList = buildReturnDetailList(List.of(returnDO)); |
| | | AfterSaleReturnRespVO respVO = enrichedList.get(0); |
| | | respVO.setItems(BeanUtils.toBean(items, AfterSaleReturnRespVO.Item.class)); |
| | | return success(respVO); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾éè´§ç³è¯·å页") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:return:query')") |
| | | public CommonResult<PageResult<AfterSaleReturnRespVO>> getReturnPage(@Valid AfterSaleReturnPageReqVO pageReqVO) { |
| | | PageResult<AfterSaleReturnDO> pageResult = returnService.getReturnPage(pageReqVO, getLoginUserId()); |
| | | List<AfterSaleReturnRespVO> list = buildReturnDetailList(pageResult.getList()); |
| | | return success(new PageResult<>(list, pageResult.getTotal())); |
| | | } |
| | | |
| | | // ========== å
鍿¹æ³ï¼æ¹éæ¼è£
å
³èåç§° ========== |
| | | |
| | | private List<AfterSaleReturnRespVO> buildReturnDetailList(List<AfterSaleReturnDO> returnList) { |
| | | if (CollUtil.isEmpty(returnList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // æ¹éå 载客æ·åç§° |
| | | Set<Long> customerIds = convertSet(returnList, AfterSaleReturnDO::getCustomerId); |
| | | Map<Long, CrmCustomerRespDTO> customerMap = customerApi.getCustomerMap(customerIds); |
| | | // æ¼è£
åç§°åæ®µ |
| | | return BeanUtils.toBean(returnList, AfterSaleReturnRespVO.class, vo -> { |
| | | CrmCustomerRespDTO customer = customerMap.get(vo.getCustomerId()); |
| | | if (customer != null) vo.setCustomerName(customer.getName()); |
| | | }); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯·å页æ¥è¯¢ VO |
| | | */ |
| | | @Schema(description = "å®åéè´§ç³è¯· - å页æ¥è¯¢ Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class AfterSaleReturnPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "éè´§åå·", example = "RT20240101000001") |
| | | private String no; |
| | | |
| | | @Schema(description = "å
³èå·¥åç¼å·", example = "1") |
| | | private Long ticketId; |
| | | |
| | | @Schema(description = "客æ·ç¼å·", example = "1") |
| | | private Long customerId; |
| | | |
| | | @Schema(description = "éè´§ç¶æ", example = "10") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "åºæ¯ç±»å", example = "1") |
| | | private Integer sceneType; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯·ååº VO |
| | | */ |
| | | @Schema(description = "å®åéè´§ç³è¯· - ååº VO") |
| | | @Data |
| | | public class AfterSaleReturnRespVO { |
| | | |
| | | @Schema(description = "éè´§ç³è¯·ç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´§åå·", example = "RT20240101000001") |
| | | private String no; |
| | | |
| | | @Schema(description = "å
³èå·¥åç¼å·", example = "1") |
| | | private Long ticketId; |
| | | |
| | | @Schema(description = "客æ·ç¼å·", example = "1") |
| | | private Long customerId; |
| | | |
| | | @Schema(description = "客æ·åç§°") |
| | | private String customerName; |
| | | |
| | | @Schema(description = "å
³èéå®è®¢åç¼å·", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éè´§ç±»å: 1-鿬¾éè´§ 2-æ¢è´§ 3-ä»
鿬¾", example = "1") |
| | | private Integer returnType; |
| | | |
| | | @Schema(description = "éè´§åå ", example = "产åå¤è§ç¼ºé·") |
| | | private String returnReason; |
| | | |
| | | @Schema(description = "缺é·åç±»", example = "å¤è§ç¼ºé·") |
| | | private String defectCategory; |
| | | |
| | | @Schema(description = "åºéæ»éé¢", example = "1000.00") |
| | | private BigDecimal totalReturnPrice; |
| | | |
| | | @Schema(description = "å®ééé¢", example = "950.00") |
| | | private BigDecimal actualRefundPrice; |
| | | |
| | | @Schema(description = "ç¶æ", example = "10") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å®¡æ ¸äºº", example = "1") |
| | | private Long auditUserId; |
| | | |
| | | @Schema(description = "å®¡æ ¸æ¶é´") |
| | | private LocalDateTime auditTime; |
| | | |
| | | @Schema(description = "MESéè´§åç¼å·", example = "1") |
| | | private Long mesReturnId; |
| | | |
| | | @Schema(description = "MESéè´§åå·", example = "MES-RT-001") |
| | | private String mesReturnCode; |
| | | |
| | | @Schema(description = "è´¨æ£ç»è®º", example = "åæ ¼") |
| | | private String qualityResult; |
| | | |
| | | @Schema(description = "è´¨æ£æ¥åéä»¶URL") |
| | | private String qualityReportUrl; |
| | | |
| | | @Schema(description = "éè´§å
¥åºå®ææ¶é´") |
| | | private LocalDateTime returnInboundTime; |
| | | |
| | | @Schema(description = "鿬¾/æ¢è´§å®ææ¶é´") |
| | | private LocalDateTime refundTime; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建è
") |
| | | private String creator; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "æ´æ°è
") |
| | | private String updater; |
| | | |
| | | @Schema(description = "æ´æ°æ¶é´") |
| | | private LocalDateTime updateTime; |
| | | |
| | | @Schema(description = "éè´§æç»è¡å表") |
| | | private List<Item> items; |
| | | |
| | | @Schema(description = "éè´§æç»è¡") |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "ç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "éè´§ç³è¯·ç¼å·", example = "1") |
| | | private Long returnId; |
| | | |
| | | @Schema(description = "å·¥åæç»è¡ç¼å·", example = "1") |
| | | private Long ticketItemId; |
| | | |
| | | @Schema(description = "MDMç©æç¼å·", example = "1") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ç©æç¼ç ", example = "MAT-001") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "ç©æåç§°", example = "çµåå
å¨ä»¶") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "æ¹æ¬¡ç¼å·", example = "1") |
| | | private Long batchId; |
| | | |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BATCH-2024-001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "éè´§æ°é", example = "10.000") |
| | | private BigDecimal returnQuantity; |
| | | |
| | | @Schema(description = "éå®åä»·", example = "100.00") |
| | | private BigDecimal unitPrice; |
| | | |
| | | @Schema(description = "éè´§éé¢", example = "1000.00") |
| | | private BigDecimal returnPrice; |
| | | |
| | | @Schema(description = "MESéè´§åè¡ç¼å·", example = "1") |
| | | private Long mesReturnLineId; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯·ä¿å VO |
| | | */ |
| | | @Schema(description = "å®åéè´§ç³è¯· - ä¿å Request VO") |
| | | @Data |
| | | public class AfterSaleReturnSaveReqVO { |
| | | |
| | | @Schema(description = "éè´§ç³è¯·ç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å
³èå·¥åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "å
³èå·¥åä¸è½ä¸ºç©º") |
| | | private Long ticketId; |
| | | |
| | | @Schema(description = "客æ·ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "客æ·ä¸è½ä¸ºç©º") |
| | | private Long customerId; |
| | | |
| | | @Schema(description = "å
³èéå®è®¢åç¼å·", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éè´§ç±»å: 1-鿬¾éè´§ 2-æ¢è´§ 3-ä»
鿬¾", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "éè´§ç±»åä¸è½ä¸ºç©º") |
| | | private Integer returnType; |
| | | |
| | | @Schema(description = "éè´§åå ", requiredMode = Schema.RequiredMode.REQUIRED, example = "产åå¤è§ç¼ºé·") |
| | | @NotEmpty(message = "éè´§åå ä¸è½ä¸ºç©º") |
| | | private String returnReason; |
| | | |
| | | @Schema(description = "缺é·åç±»", example = "å¤è§ç¼ºé·") |
| | | private String defectCategory; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "éè´§æç»è¡å表") |
| | | private List<Item> items; |
| | | |
| | | @Schema(description = "éè´§æç»è¡") |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "å·¥åæç»è¡ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "å·¥åæç»è¡ä¸è½ä¸ºç©º") |
| | | private Long ticketItemId; |
| | | |
| | | @Schema(description = "MDMç©æç¼å·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "ç©æä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ç©æç¼ç ", example = "MAT-001") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "ç©æåç§°", example = "çµåå
å¨ä»¶") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "æ¹æ¬¡ç¼å·", example = "1") |
| | | private Long batchId; |
| | | |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BATCH-2024-001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "éè´§æ°é", requiredMode = Schema.RequiredMode.REQUIRED, example = "10.000") |
| | | @NotNull(message = "éè´§æ°éä¸è½ä¸ºç©º") |
| | | private BigDecimal returnQuantity; |
| | | |
| | | @Schema(description = "éå®åä»·", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| | | @NotNull(message = "éå®åä»·ä¸è½ä¸ºç©º") |
| | | private BigDecimal unitPrice; |
| | | |
| | | @Schema(description = "éè´§éé¢", example = "1000.00") |
| | | private BigDecimal returnPrice; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.ticket; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketPageReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketRespVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketSaveReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketItemDO; |
| | | import cn.iocoder.yudao.module.aftersales.service.ticket.AfterSaleTicketService; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | |
| | | @Tag(name = "管çåå° - å®åå·¥å") |
| | | @RestController |
| | | @RequestMapping("/aftersales/ticket") |
| | | @Validated |
| | | public class AfterSaleTicketController { |
| | | |
| | | @Resource |
| | | private AfterSaleTicketService ticketService; |
| | | |
| | | @Resource |
| | | private CrmCustomerApi customerApi; |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建å®åå·¥å") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:create')") |
| | | public CommonResult<Long> createTicket(@Valid @RequestBody AfterSaleTicketSaveReqVO createReqVO) { |
| | | return success(ticketService.createTicket(createReqVO, getLoginUserId())); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°å®åå·¥å") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:update')") |
| | | public CommonResult<Boolean> updateTicket(@Valid @RequestBody AfterSaleTicketSaveReqVO updateReqVO) { |
| | | ticketService.updateTicket(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤å®åå·¥å") |
| | | @Parameter(name = "id", description = "å·¥åç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:delete')") |
| | | public CommonResult<Boolean> deleteTicket(@RequestParam("id") Long id) { |
| | | ticketService.deleteTicket(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾å®åå·¥å") |
| | | @Parameter(name = "id", description = "å·¥åç¼å·", required = true, example = "1") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:query')") |
| | | public CommonResult<AfterSaleTicketRespVO> getTicket(@RequestParam("id") Long id) { |
| | | AfterSaleTicketDO ticket = ticketService.getTicket(id); |
| | | List<AfterSaleTicketItemDO> items = ticketService.getTicketItemListByTicketId(id); |
| | | // æ¹éå è½½å
³èåç§° |
| | | List<AfterSaleTicketRespVO> enrichedList = buildTicketDetailList(List.of(ticket)); |
| | | AfterSaleTicketRespVO respVO = enrichedList.get(0); |
| | | respVO.setItems(BeanUtils.toBean(items, AfterSaleTicketRespVO.Item.class)); |
| | | return success(respVO); |
| | | } |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾å®åå·¥åå页") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:query')") |
| | | public CommonResult<PageResult<AfterSaleTicketRespVO>> getTicketPage(@Valid AfterSaleTicketPageReqVO pageReqVO) { |
| | | PageResult<AfterSaleTicketDO> pageResult = ticketService.getTicketPage(pageReqVO, getLoginUserId()); |
| | | List<AfterSaleTicketRespVO> list = buildTicketDetailList(pageResult.getList()); |
| | | return success(new PageResult<>(list, pageResult.getTotal())); |
| | | } |
| | | |
| | | @PostMapping("/assign") |
| | | @Operation(summary = "åé
å¤ç人") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:update')") |
| | | public CommonResult<Boolean> assignTicket(@RequestParam("id") Long id, |
| | | @RequestParam("handlerUserId") Long handlerUserId) { |
| | | ticketService.assignTicket(id, handlerUserId); |
| | | return success(true); |
| | | } |
| | | |
| | | @PostMapping("/classify") |
| | | @Operation(summary = "é®é¢å¤å®") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:update')") |
| | | public CommonResult<Boolean> classifyTicket(@RequestParam("id") Long id, |
| | | @RequestParam("issueType") Integer issueType, |
| | | @RequestParam(value = "issueCategory", required = false) String issueCategory, |
| | | @RequestParam(value = "severityLevel", required = false) Integer severityLevel) { |
| | | ticketService.classifyTicket(id, issueType, issueCategory, severityLevel); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/resolve") |
| | | @Operation(summary = "å®ç»å·¥å") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:update')") |
| | | public CommonResult<Boolean> resolveTicket(@RequestParam("id") Long id) { |
| | | ticketService.resolveTicket(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/close") |
| | | @Operation(summary = "å
³éå·¥å") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:update')") |
| | | public CommonResult<Boolean> closeTicket(@RequestParam("id") Long id) { |
| | | ticketService.closeTicket(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/cancel") |
| | | @Operation(summary = "åæ¶å·¥å") |
| | | @PreAuthorize("@ss.hasPermission('aftersales:ticket:update')") |
| | | public CommonResult<Boolean> cancelTicket(@RequestParam("id") Long id) { |
| | | ticketService.cancelTicket(id); |
| | | return success(true); |
| | | } |
| | | |
| | | // ========== å
鍿¹æ³ï¼æ¹éæ¼è£
å
³èåç§° ========== |
| | | |
| | | private List<AfterSaleTicketRespVO> buildTicketDetailList(List<AfterSaleTicketDO> ticketList) { |
| | | if (CollUtil.isEmpty(ticketList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // 1. æ¹éå 载客æ·åç§° |
| | | Set<Long> customerIds = convertSet(ticketList, AfterSaleTicketDO::getCustomerId); |
| | | Map<Long, CrmCustomerRespDTO> customerMap = customerApi.getCustomerMap(customerIds); |
| | | // 2. æ¹éå è½½ç¨æ·åç§°ï¼è´è´£äºº + å¤çäººï¼ |
| | | Set<Long> userIds = new HashSet<>(); |
| | | ticketList.forEach(t -> { |
| | | if (t.getOwnerUserId() != null) userIds.add(t.getOwnerUserId()); |
| | | if (t.getHandlerUserId() != null) userIds.add(t.getHandlerUserId()); |
| | | }); |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); |
| | | // 3. æ¼è£
åç§°åæ®µ |
| | | return BeanUtils.toBean(ticketList, AfterSaleTicketRespVO.class, vo -> { |
| | | CrmCustomerRespDTO customer = customerMap.get(vo.getCustomerId()); |
| | | if (customer != null) vo.setCustomerName(customer.getName()); |
| | | AdminUserRespDTO ownerUser = userMap.get(vo.getOwnerUserId()); |
| | | if (ownerUser != null) vo.setOwnerUserName(ownerUser.getNickname()); |
| | | AdminUserRespDTO handlerUser = userMap.get(vo.getHandlerUserId()); |
| | | if (handlerUser != null) vo.setHandlerUserName(handlerUser.getNickname()); |
| | | }); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * å®åå·¥åå页æ¥è¯¢ VO |
| | | */ |
| | | @Schema(description = "å®åå·¥å - å页æ¥è¯¢ Request VO") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | public class AfterSaleTicketPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "å·¥ååå·", example = "AS20240101000001") |
| | | private String no; |
| | | |
| | | @Schema(description = "å·¥å主é¢", example = "产åå¤è§ç¼ºé·") |
| | | private String name; |
| | | |
| | | @Schema(description = "客æ·ç¼å·", example = "1") |
| | | private Long customerId; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "å·¥åç¶æ", example = "10") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "é®é¢ç±»å", example = "1") |
| | | private Integer issueType; |
| | | |
| | | @Schema(description = "åºæ¯ç±»å", example = "1") |
| | | private Integer sceneType; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åå·¥åååº VO |
| | | */ |
| | | @Schema(description = "å®åå·¥å - ååº VO") |
| | | @Data |
| | | public class AfterSaleTicketRespVO { |
| | | |
| | | @Schema(description = "å·¥åç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å·¥ååå·", example = "AS20240101000001") |
| | | private String no; |
| | | |
| | | @Schema(description = "å·¥å主é¢", example = "产åå¤è§ç¼ºé·") |
| | | private String name; |
| | | |
| | | @Schema(description = "客æ·ç¼å·", example = "1") |
| | | private Long customerId; |
| | | |
| | | @Schema(description = "客æ·åç§°") |
| | | private String customerName; |
| | | |
| | | @Schema(description = "è系人ç¼å·", example = "1") |
| | | private Long contactId; |
| | | |
| | | @Schema(description = "è系人åç§°") |
| | | private String contactName; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éå®è®¢åå·", example = "SO202401010001") |
| | | private String saleOrderNo; |
| | | |
| | | @Schema(description = "ååç¼å·", example = "1") |
| | | private Long contractId; |
| | | |
| | | @Schema(description = "é®é¢ç±»å: 1-ä¸è¬é®é¢ 2-ç»´ä¿®é®é¢ 3-éè´§é®é¢", example = "1") |
| | | private Integer issueType; |
| | | |
| | | @Schema(description = "é®é¢åç±»", example = "å¤è§ç¼ºé·") |
| | | private String issueCategory; |
| | | |
| | | @Schema(description = "é®é¢æè¿°", example = "æ¶å°è´§ååç°äº§åè¡¨é¢æåç") |
| | | private String issueDescription; |
| | | |
| | | @Schema(description = "严éç¨åº¦: 0-轻微 1-ä¸è¬ 2-严é 3-è´å½", example = "1") |
| | | private Integer severityLevel; |
| | | |
| | | @Schema(description = "ç¶æ: 0-è稿 10-å¤çä¸ 30-å¾
éè´§ 40-å¾
鿬¾/æ¢è´§ 50-å·²å®ç» 60-å·²å
³é 99-已忶", example = "0") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "è´è´£äººç¨æ·ç¼å·", example = "1") |
| | | private Long ownerUserId; |
| | | |
| | | @Schema(description = "è´è´£äººåç§°") |
| | | private String ownerUserName; |
| | | |
| | | @Schema(description = "å¤çäººç¨æ·ç¼å·", example = "2") |
| | | private Long handlerUserId; |
| | | |
| | | @Schema(description = "å¤ç人åç§°") |
| | | private String handlerUserName; |
| | | |
| | | @Schema(description = "BPM 工使µå®ä¾ç¼å·") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "å
³èéè´§ç³è¯·ç¼å·", example = "1") |
| | | private Long returnId; |
| | | |
| | | @Schema(description = "å
³è维修记å½ç¼å·", example = "1") |
| | | private Long repairId; |
| | | |
| | | @Schema(description = "è§£å³æ¶é´") |
| | | private LocalDateTime resolvedTime; |
| | | |
| | | @Schema(description = "å
³éæ¶é´") |
| | | private LocalDateTime closedTime; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å建è
") |
| | | private String creator; |
| | | |
| | | @Schema(description = "å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "æ´æ°è
") |
| | | private String updater; |
| | | |
| | | @Schema(description = "æ´æ°æ¶é´") |
| | | private LocalDateTime updateTime; |
| | | |
| | | @Schema(description = "æç»è¡å表") |
| | | private List<Item> items; |
| | | |
| | | @Schema(description = "å·¥åæç»è¡") |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "ç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å·¥åç¼å·", example = "1") |
| | | private Long ticketId; |
| | | |
| | | @Schema(description = "éå®è®¢åè¡ç¼å·", example = "1") |
| | | private Long saleOrderItemId; |
| | | |
| | | @Schema(description = "MDMç©æç¼å·", example = "1") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ç©æç¼ç ", example = "MAT-001") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "ç©æåç§°", example = "çµåå
å¨ä»¶") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡ç¼å·", example = "1") |
| | | private Long batchId; |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡å·", example = "BATCH-2024-001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "é宿°é", example = "100.000") |
| | | private BigDecimal saleQuantity; |
| | | |
| | | @Schema(description = "éè´§æ°é", example = "10.000") |
| | | private BigDecimal returnQuantity; |
| | | |
| | | @Schema(description = "æ¯å¦éè¦ç»´ä¿®", example = "false") |
| | | private Boolean needRepair; |
| | | |
| | | @Schema(description = "æ¯å¦éè¦éè´§", example = "true") |
| | | private Boolean needReturn; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åå·¥åä¿å VO |
| | | */ |
| | | @Schema(description = "å®åå·¥å - ä¿å Request VO") |
| | | @Data |
| | | public class AfterSaleTicketSaveReqVO { |
| | | |
| | | @Schema(description = "å·¥åç¼å·", example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "å·¥å主é¢", requiredMode = Schema.RequiredMode.REQUIRED, example = "产åå¤è§ç¼ºé·") |
| | | @NotEmpty(message = "å·¥å主é¢ä¸è½ä¸ºç©º") |
| | | private String name; |
| | | |
| | | @Schema(description = "客æ·ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | @NotNull(message = "客æ·ä¸è½ä¸ºç©º") |
| | | private Long customerId; |
| | | |
| | | @Schema(description = "è系人ç¼å·", example = "1") |
| | | private Long contactId; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éå®è®¢åå·", example = "SO202401010001") |
| | | private String saleOrderNo; |
| | | |
| | | @Schema(description = "ååç¼å·", example = "1") |
| | | private Long contractId; |
| | | |
| | | @Schema(description = "é®é¢æè¿°", example = "æ¶å°è´§ååç°äº§åè¡¨é¢æåç") |
| | | private String issueDescription; |
| | | |
| | | @Schema(description = "夿³¨", example = "客æ·è¦æ±å°½å¿«å¤ç") |
| | | private String remark; |
| | | |
| | | @Schema(description = "æç»è¡å表") |
| | | private List<Item> items; |
| | | |
| | | @Schema(description = "å·¥åæç»è¡") |
| | | @Data |
| | | public static class Item { |
| | | |
| | | @Schema(description = "éå®è®¢åè¡ç¼å·", example = "1") |
| | | private Long saleOrderItemId; |
| | | |
| | | @Schema(description = "MDMç©æç¼å·", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "ç©æä¸è½ä¸ºç©º") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ç©æç¼ç ", example = "MAT-001") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "ç©æåç§°", example = "çµåå
å¨ä»¶") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡ç¼å·", example = "1") |
| | | private Long batchId; |
| | | |
| | | @Schema(description = "çäº§æ¹æ¬¡å·", example = "BATCH-2024-001") |
| | | private String batchCode; |
| | | |
| | | @Schema(description = "é宿°é", example = "100.000") |
| | | private BigDecimal saleQuantity; |
| | | |
| | | @Schema(description = "éè´§æ°é", example = "10.000") |
| | | private BigDecimal returnQuantity; |
| | | |
| | | @Schema(description = "æ¯å¦éè¦ç»´ä¿®", example = "false") |
| | | private Boolean needRepair; |
| | | |
| | | @Schema(description = "æ¯å¦éè¦éè´§", example = "true") |
| | | private Boolean needReturn; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.dataobject.permission; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSalePermissionLevelEnum; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | /** |
| | | * å®åæ¨¡åæ°æ®æé DO |
| | | */ |
| | | @TableName("after_sale_permission") |
| | | @KeySequence("after_sale_permission_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AfterSalePermissionDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å·ï¼ä¸»é®èªå¢ |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | |
| | | /** |
| | | * æ°æ®ç±»å |
| | | * |
| | | * æä¸¾ {@link AfterSaleBizTypeEnum} |
| | | */ |
| | | private Integer bizType; |
| | | /** |
| | | * æ°æ®ç¼å· |
| | | * |
| | | * å
³è {@link AfterSaleBizTypeEnum} å¯¹åºæ¨¡å DO ç id åæ®µ |
| | | */ |
| | | private Long bizId; |
| | | |
| | | /** |
| | | * ç¨æ·ç¼å· |
| | | */ |
| | | private Long userId; |
| | | |
| | | /** |
| | | * æéçº§å« |
| | | * |
| | | * æä¸¾ {@link AfterSalePermissionLevelEnum} |
| | | */ |
| | | private Integer level; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.dataobject.repair; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleRepairStatusEnum; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å®åç»´ä¿®è®°å½ DO |
| | | */ |
| | | @TableName("after_sale_repair") |
| | | @KeySequence("after_sale_repair_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AfterSaleRepairDO extends BaseDO { |
| | | |
| | | /** |
| | | * 维修记å½ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * å
³èå·¥åç¼å·ï¼å
³è after_sale_ticket.id |
| | | */ |
| | | private Long ticketId; |
| | | /** |
| | | * 维修类å: 1-ç°åºç»´ä¿® 2-è¿åç»´ä¿® 3-è¿ç¨æå¯¼ |
| | | */ |
| | | private Integer repairType; |
| | | /** |
| | | * æ
éæè¿° |
| | | */ |
| | | private String faultDescription; |
| | | /** |
| | | * ç»´ä¿®æªæ½ |
| | | */ |
| | | private String repairAction; |
| | | /** |
| | | * ç»´ä¿®ç»æ: 已修å¤/æ æ³ä¿®å¤/é¨åä¿®å¤ |
| | | */ |
| | | private String repairResult; |
| | | /** |
| | | * ç»´ä¿®è´¹ç¨ |
| | | */ |
| | | private BigDecimal repairCost; |
| | | /** |
| | | * 维修人 |
| | | */ |
| | | private Long repairUserId; |
| | | /** |
| | | * ç»´ä¿®ç¶æ |
| | | * |
| | | * æä¸¾ {@link AfterSaleRepairStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * å¼å§ç»´ä¿®æ¶é´ |
| | | */ |
| | | private LocalDateTime startTime; |
| | | /** |
| | | * å®æç»´ä¿®æ¶é´ |
| | | */ |
| | | private LocalDateTime finishTime; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj; |
| | | |
| | | // 注ï¼package åä½¿ç¨ returnobj é¿å
ä¸ Java å
³é®å return å²çª |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleReturnStatusEnum; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯· DO |
| | | */ |
| | | @TableName("after_sale_return") |
| | | @KeySequence("after_sale_return_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AfterSaleReturnDO extends BaseDO { |
| | | |
| | | /** |
| | | * éè´§ç³è¯·ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * éè´§åå· |
| | | */ |
| | | private String no; |
| | | /** |
| | | * å
³èå·¥åç¼å·ï¼å
³è after_sale_ticket.id |
| | | */ |
| | | private Long ticketId; |
| | | /** |
| | | * 客æ·ç¼å· |
| | | */ |
| | | private Long customerId; |
| | | /** |
| | | * å
³èéå®è®¢åç¼å· |
| | | */ |
| | | private Long saleOrderId; |
| | | /** |
| | | * éè´§ç±»å: 1-鿬¾éè´§ 2-æ¢è´§ 3-ä»
鿬¾ |
| | | */ |
| | | private Integer returnType; |
| | | /** |
| | | * éè´§åå |
| | | */ |
| | | private String returnReason; |
| | | /** |
| | | * 缺é·åç±» |
| | | */ |
| | | private String defectCategory; |
| | | /** |
| | | * åºéæ»éé¢ |
| | | */ |
| | | private BigDecimal totalReturnPrice; |
| | | /** |
| | | * å®ééé¢ |
| | | */ |
| | | private BigDecimal actualRefundPrice; |
| | | /** |
| | | * éè´§ç¶æ |
| | | * |
| | | * æä¸¾ {@link AfterSaleReturnStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * å®¡æ ¸äºº |
| | | */ |
| | | private Long auditUserId; |
| | | /** |
| | | * å®¡æ ¸æ¶é´ |
| | | */ |
| | | private LocalDateTime auditTime; |
| | | /** |
| | | * MES éè´§åç¼å·ï¼å
³è mes_wm_return_sales.id |
| | | */ |
| | | private Long mesReturnId; |
| | | /** |
| | | * MES éè´§åå·(åä½) |
| | | */ |
| | | private String mesReturnCode; |
| | | /** |
| | | * è´¨æ£ç»è®º: åæ ¼/ç¹é/éè´§/æ¥åº |
| | | */ |
| | | private String qualityResult; |
| | | /** |
| | | * è´¨æ£æ¥åéä»¶URL |
| | | */ |
| | | private String qualityReportUrl; |
| | | /** |
| | | * éè´§å
¥åºå®ææ¶é´ |
| | | */ |
| | | private LocalDateTime returnInboundTime; |
| | | /** |
| | | * 鿬¾/æ¢è´§å®ææ¶é´ |
| | | */ |
| | | private LocalDateTime refundTime; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * å®åéè´§æç»è¡ DO |
| | | */ |
| | | @TableName("after_sale_return_item") |
| | | @KeySequence("after_sale_return_item_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AfterSaleReturnItemDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * éè´§ç³è¯·ç¼å·ï¼å
³è after_sale_return.id |
| | | */ |
| | | private Long returnId; |
| | | /** |
| | | * å·¥åæç»è¡ç¼å· |
| | | */ |
| | | private Long ticketItemId; |
| | | /** |
| | | * MDM ç©æç¼å· |
| | | */ |
| | | private Long itemId; |
| | | /** |
| | | * ç©æç¼ç (åä½) |
| | | */ |
| | | private String itemCode; |
| | | /** |
| | | * ç©æåç§°(åä½) |
| | | */ |
| | | private String itemName; |
| | | /** |
| | | * æ¹æ¬¡ç¼å· |
| | | */ |
| | | private Long batchId; |
| | | /** |
| | | * æ¹æ¬¡å· |
| | | */ |
| | | private String batchCode; |
| | | /** |
| | | * éè´§æ°é |
| | | */ |
| | | private BigDecimal returnQuantity; |
| | | /** |
| | | * éå®åä»· |
| | | */ |
| | | private BigDecimal unitPrice; |
| | | /** |
| | | * éè´§éé¢ |
| | | */ |
| | | private BigDecimal returnPrice; |
| | | /** |
| | | * MES éè´§åè¡ç¼å· |
| | | */ |
| | | private Long mesReturnLineId; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleIssueTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleTicketStatusEnum; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å®åå·¥å DO |
| | | */ |
| | | @TableName("after_sale_ticket") |
| | | @KeySequence("after_sale_ticket_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AfterSaleTicketDO extends BaseDO { |
| | | |
| | | /** |
| | | * å·¥åç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * å·¥ååå· |
| | | */ |
| | | private String no; |
| | | /** |
| | | * å·¥å主é¢/æ é¢ |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 客æ·ç¼å·ï¼å
³è crm_customer.id |
| | | */ |
| | | private Long customerId; |
| | | /** |
| | | * è系人ç¼å·ï¼å
³è crm_contact.id |
| | | */ |
| | | private Long contactId; |
| | | /** |
| | | * éå®è®¢åç¼å·ï¼å
³è erp_sale_order.id |
| | | */ |
| | | private Long saleOrderId; |
| | | /** |
| | | * éå®è®¢åå·(åä½) |
| | | */ |
| | | private String saleOrderNo; |
| | | /** |
| | | * ååç¼å·ï¼å
³è crm_contract.id |
| | | */ |
| | | private Long contractId; |
| | | /** |
| | | * é®é¢ç±»å |
| | | * |
| | | * æä¸¾ {@link AfterSaleIssueTypeEnum} |
| | | */ |
| | | private Integer issueType; |
| | | /** |
| | | * é®é¢åç±»: å¤è§ç¼ºé·/åè½æ
é/尺寸åå·®/å
è£
ç ´æ/å
¶ä» |
| | | */ |
| | | private String issueCategory; |
| | | /** |
| | | * é®é¢æè¿° |
| | | */ |
| | | private String issueDescription; |
| | | /** |
| | | * 严éç¨åº¦: 0-轻微 1-ä¸è¬ 2-严é 3-è´å½ |
| | | */ |
| | | private Integer severityLevel; |
| | | /** |
| | | * å·¥åç¶æ |
| | | * |
| | | * æä¸¾ {@link AfterSaleTicketStatusEnum} |
| | | */ |
| | | private Integer status; |
| | | /** |
| | | * è´è´£äººç¨æ·ç¼å· |
| | | */ |
| | | private Long ownerUserId; |
| | | /** |
| | | * å¤çäººç¨æ·ç¼å· |
| | | */ |
| | | private Long handlerUserId; |
| | | /** |
| | | * BPM 工使µå®ä¾ç¼å· |
| | | */ |
| | | private String processInstanceId; |
| | | /** |
| | | * å
³èéè´§ç³è¯·ç¼å·ï¼å
³è after_sale_return.id |
| | | */ |
| | | private Long returnId; |
| | | /** |
| | | * å
³è维修记å½ç¼å·ï¼å
³è after_sale_repair.id |
| | | */ |
| | | private Long repairId; |
| | | /** |
| | | * è§£å³æ¶é´ |
| | | */ |
| | | private LocalDateTime resolvedTime; |
| | | /** |
| | | * å
³éæ¶é´ |
| | | */ |
| | | private LocalDateTime closedTime; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * å®åå·¥åæç»è¡ DO |
| | | */ |
| | | @TableName("after_sale_ticket_item") |
| | | @KeySequence("after_sale_ticket_item_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class AfterSaleTicketItemDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * å·¥åç¼å·ï¼å
³è after_sale_ticket.id |
| | | */ |
| | | private Long ticketId; |
| | | /** |
| | | * éå®è®¢åè¡ç¼å· |
| | | */ |
| | | private Long saleOrderItemId; |
| | | /** |
| | | * MDM ç©æç¼å· |
| | | */ |
| | | private Long itemId; |
| | | /** |
| | | * ç©æç¼ç (åä½) |
| | | */ |
| | | private String itemCode; |
| | | /** |
| | | * ç©æåç§°(åä½) |
| | | */ |
| | | private String itemName; |
| | | /** |
| | | * çäº§æ¹æ¬¡ç¼å· |
| | | */ |
| | | private Long batchId; |
| | | /** |
| | | * çäº§æ¹æ¬¡å· |
| | | */ |
| | | private String batchCode; |
| | | /** |
| | | * é宿°é |
| | | */ |
| | | private BigDecimal saleQuantity; |
| | | /** |
| | | * éè´§æ°é |
| | | */ |
| | | private BigDecimal returnQuantity; |
| | | /** |
| | | * æ¯å¦éè¦ç»´ä¿® |
| | | */ |
| | | private Boolean needRepair; |
| | | /** |
| | | * æ¯å¦éè¦éè´§ |
| | | */ |
| | | private Boolean needReturn; |
| | | /** |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.mysql.permission; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.permission.AfterSalePermissionDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åæ¨¡åæ°æ®æé Mapper |
| | | */ |
| | | @Mapper |
| | | public interface AfterSalePermissionMapper extends BaseMapperX<AfterSalePermissionDO> { |
| | | |
| | | default List<AfterSalePermissionDO> selectListByBiz(Integer bizType, Long bizId) { |
| | | return selectList(new LambdaQueryWrapperX<AfterSalePermissionDO>() |
| | | .eq(AfterSalePermissionDO::getBizType, bizType) |
| | | .eq(AfterSalePermissionDO::getBizId, bizId)); |
| | | } |
| | | |
| | | default List<AfterSalePermissionDO> selectListByBiz(Integer bizType, Collection<Long> bizIds) { |
| | | return selectList(new LambdaQueryWrapperX<AfterSalePermissionDO>() |
| | | .eq(AfterSalePermissionDO::getBizType, bizType) |
| | | .in(AfterSalePermissionDO::getBizId, bizIds)); |
| | | } |
| | | |
| | | default List<AfterSalePermissionDO> selectListByBizTypeAndUserId(Integer bizType, Long userId) { |
| | | return selectList(new LambdaQueryWrapperX<AfterSalePermissionDO>() |
| | | .eq(AfterSalePermissionDO::getBizType, bizType) |
| | | .eq(AfterSalePermissionDO::getUserId, userId)); |
| | | } |
| | | |
| | | default AfterSalePermissionDO selectByBizAndUser(Integer bizType, Long bizId, Long userId) { |
| | | return selectOne(new LambdaQueryWrapperX<AfterSalePermissionDO>() |
| | | .eq(AfterSalePermissionDO::getBizType, bizType) |
| | | .eq(AfterSalePermissionDO::getBizId, bizId) |
| | | .eq(AfterSalePermissionDO::getUserId, userId)); |
| | | } |
| | | |
| | | default void deleteByBiz(Integer bizType, Long bizId) { |
| | | delete(new LambdaQueryWrapperX<AfterSalePermissionDO>() |
| | | .eq(AfterSalePermissionDO::getBizType, bizType) |
| | | .eq(AfterSalePermissionDO::getBizId, bizId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.mysql.repair; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.repair.AfterSaleRepairDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åç»´ä¿®è®°å½ Mapper |
| | | */ |
| | | @Mapper |
| | | public interface AfterSaleRepairMapper extends BaseMapperX<AfterSaleRepairDO> { |
| | | |
| | | default AfterSaleRepairDO selectByTicketId(Long ticketId) { |
| | | return selectOne(AfterSaleRepairDO::getTicketId, ticketId); |
| | | } |
| | | |
| | | default List<AfterSaleRepairDO> selectListByTicketId(Long ticketId) { |
| | | return selectList(new LambdaQueryWrapperX<AfterSaleRepairDO>() |
| | | .eq(AfterSaleRepairDO::getTicketId, ticketId)); |
| | | } |
| | | |
| | | default PageResult<AfterSaleRepairDO> selectPage(PageParam pageParam, Long ticketId, Integer status) { |
| | | return selectPage(pageParam, new LambdaQueryWrapperX<AfterSaleRepairDO>() |
| | | .eqIfPresent(AfterSaleRepairDO::getTicketId, ticketId) |
| | | .eqIfPresent(AfterSaleRepairDO::getStatus, status) |
| | | .orderByDesc(AfterSaleRepairDO::getId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.mysql.returnobj; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnItemDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åéè´§æç»è¡ Mapper |
| | | */ |
| | | @Mapper |
| | | public interface AfterSaleReturnItemMapper extends BaseMapperX<AfterSaleReturnItemDO> { |
| | | |
| | | default List<AfterSaleReturnItemDO> selectListByReturnId(Long returnId) { |
| | | return selectList(new LambdaQueryWrapperX<AfterSaleReturnItemDO>() |
| | | .eq(AfterSaleReturnItemDO::getReturnId, returnId)); |
| | | } |
| | | |
| | | default void deleteByReturnId(Long returnId) { |
| | | delete(new LambdaQueryWrapperX<AfterSaleReturnItemDO>() |
| | | .eq(AfterSaleReturnItemDO::getReturnId, returnId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.mysql.returnobj; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.util.AfterSalePermissionUtils; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯· Mapper |
| | | */ |
| | | @Mapper |
| | | public interface AfterSaleReturnMapper extends BaseMapperX<AfterSaleReturnDO> { |
| | | |
| | | default AfterSaleReturnDO selectByNo(String no) { |
| | | return selectOne(AfterSaleReturnDO::getNo, no); |
| | | } |
| | | |
| | | default AfterSaleReturnDO selectByTicketId(Long ticketId) { |
| | | return selectOne(AfterSaleReturnDO::getTicketId, ticketId); |
| | | } |
| | | |
| | | default PageResult<AfterSaleReturnDO> selectPage(PageParam pageParam, Long userId, Integer sceneType, |
| | | String no, Long ticketId, |
| | | Long customerId, Integer status) { |
| | | MPJLambdaWrapperX<AfterSaleReturnDO> query = new MPJLambdaWrapperX<>(); |
| | | // æ°æ®æé |
| | | AfterSalePermissionUtils.appendPermissionCondition(query, AfterSaleBizTypeEnum.AFTER_SALE_RETURN.getType(), |
| | | AfterSaleReturnDO::getId, userId, sceneType); |
| | | // æ¥è¯¢æ¡ä»¶ |
| | | query.selectAll(AfterSaleReturnDO.class) |
| | | .likeIfPresent(AfterSaleReturnDO::getNo, no) |
| | | .eqIfPresent(AfterSaleReturnDO::getTicketId, ticketId) |
| | | .eqIfPresent(AfterSaleReturnDO::getCustomerId, customerId) |
| | | .eqIfPresent(AfterSaleReturnDO::getStatus, status) |
| | | .orderByDesc(AfterSaleReturnDO::getId); |
| | | return selectJoinPage(pageParam, AfterSaleReturnDO.class, query); |
| | | } |
| | | |
| | | default AfterSaleReturnDO selectByMesReturnId(Long mesReturnId) { |
| | | return selectOne(AfterSaleReturnDO::getMesReturnId, mesReturnId); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.mysql.ticket; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketItemDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åå·¥åæç»è¡ Mapper |
| | | */ |
| | | @Mapper |
| | | public interface AfterSaleTicketItemMapper extends BaseMapperX<AfterSaleTicketItemDO> { |
| | | |
| | | default List<AfterSaleTicketItemDO> selectListByTicketId(Long ticketId) { |
| | | return selectList(new LambdaQueryWrapperX<AfterSaleTicketItemDO>() |
| | | .eq(AfterSaleTicketItemDO::getTicketId, ticketId)); |
| | | } |
| | | |
| | | default void deleteByTicketId(Long ticketId) { |
| | | delete(new LambdaQueryWrapperX<AfterSaleTicketItemDO>() |
| | | .eq(AfterSaleTicketItemDO::getTicketId, ticketId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.mysql.ticket; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.util.AfterSalePermissionUtils; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åå·¥å Mapper |
| | | */ |
| | | @Mapper |
| | | public interface AfterSaleTicketMapper extends BaseMapperX<AfterSaleTicketDO> { |
| | | |
| | | default AfterSaleTicketDO selectByNo(String no) { |
| | | return selectOne(AfterSaleTicketDO::getNo, no); |
| | | } |
| | | |
| | | default PageResult<AfterSaleTicketDO> selectPage(PageParam pageParam, Long userId, Integer sceneType, |
| | | String no, String name, |
| | | Long customerId, Long saleOrderId, |
| | | Integer status, Integer issueType) { |
| | | MPJLambdaWrapperX<AfterSaleTicketDO> query = new MPJLambdaWrapperX<>(); |
| | | // æ°æ®æé |
| | | AfterSalePermissionUtils.appendPermissionCondition(query, AfterSaleBizTypeEnum.AFTER_SALE_TICKET.getType(), |
| | | AfterSaleTicketDO::getId, userId, sceneType); |
| | | // æ¥è¯¢æ¡ä»¶ |
| | | query.selectAll(AfterSaleTicketDO.class) |
| | | .likeIfPresent(AfterSaleTicketDO::getNo, no) |
| | | .likeIfPresent(AfterSaleTicketDO::getName, name) |
| | | .eqIfPresent(AfterSaleTicketDO::getCustomerId, customerId) |
| | | .eqIfPresent(AfterSaleTicketDO::getSaleOrderId, saleOrderId) |
| | | .eqIfPresent(AfterSaleTicketDO::getStatus, status) |
| | | .eqIfPresent(AfterSaleTicketDO::getIssueType, issueType) |
| | | .orderByDesc(AfterSaleTicketDO::getId); |
| | | return selectJoinPage(pageParam, AfterSaleTicketDO.class, query); |
| | | } |
| | | |
| | | default List<AfterSaleTicketDO> selectListByCustomerId(Long customerId) { |
| | | return selectList(new LambdaQueryWrapperX<AfterSaleTicketDO>() |
| | | .eq(AfterSaleTicketDO::getCustomerId, customerId)); |
| | | } |
| | | |
| | | default AfterSaleTicketDO selectBySaleOrderId(Long saleOrderId) { |
| | | return selectOne(AfterSaleTicketDO::getSaleOrderId, saleOrderId); |
| | | } |
| | | |
| | | default Long selectCountByOwnerUserId(Long ownerUserId) { |
| | | return selectCount(AfterSaleTicketDO::getOwnerUserId, ownerUserId); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.redis; |
| | | |
| | | /** |
| | | * å®å模å Redis Key 常é |
| | | */ |
| | | public interface RedisKeyConstants { |
| | | |
| | | /** |
| | | * åºå·çç¼å |
| | | * |
| | | * KEY æ ¼å¼ï¼aftersales:seq_no:{prefix} |
| | | * VALUE æ°æ®æ ¼å¼ï¼ç¼å·èªå¢ |
| | | */ |
| | | String NO = "aftersales:seq_no:"; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.dal.redis.no; |
| | | |
| | | import cn.hutool.core.date.DatePattern; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.iocoder.yudao.module.aftersales.dal.redis.RedisKeyConstants; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.data.redis.core.StringRedisTemplate; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.time.Duration; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * å®å模ååå· Redis DAO |
| | | */ |
| | | @Repository |
| | | public class AfterSaleNoRedisDAO { |
| | | |
| | | /** |
| | | * å®åå·¥å {@link cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO} |
| | | */ |
| | | public static final String TICKET_NO_PREFIX = "AS"; |
| | | |
| | | /** |
| | | * éè´§ç³è¯· {@link cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnDO} |
| | | */ |
| | | public static final String RETURN_NO_PREFIX = "RT"; |
| | | |
| | | @Resource |
| | | private StringRedisTemplate stringRedisTemplate; |
| | | |
| | | /** |
| | | * çæåºå·ï¼ä½¿ç¨å½åæ¥æï¼æ ¼å¼ä¸º {PREFIX} + yyyyMMdd + 6 ä½èªå¢ |
| | | * |
| | | * @param prefix åç¼ |
| | | * @return åºå· |
| | | */ |
| | | public String generate(String prefix) { |
| | | String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATE_PATTERN); |
| | | String key = RedisKeyConstants.NO + noPrefix; |
| | | Long no = stringRedisTemplate.opsForValue().increment(key); |
| | | stringRedisTemplate.expire(key, Duration.ofDays(1L)); |
| | | return noPrefix + String.format("%06d", no); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * å®åä¸å¡ç±»åæä¸¾ |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum AfterSaleBizTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | AFTER_SALE_TICKET(1, "å®åå·¥å"), |
| | | AFTER_SALE_RETURN(2, "éè´§ç³è¯·"), |
| | | AFTER_SALE_REPAIR(3, "维修记å½"), |
| | | ; |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(AfterSaleBizTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | private final Integer type; |
| | | private final String name; |
| | | |
| | | public static String getNameByType(Integer type) { |
| | | AfterSaleBizTypeEnum typeEnum = CollUtil.findOne(CollUtil.newArrayList(AfterSaleBizTypeEnum.values()), |
| | | item -> ObjUtil.equal(item.type, type)); |
| | | return typeEnum == null ? null : typeEnum.getName(); |
| | | } |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * å®åé®é¢ç±»åæä¸¾ |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum AfterSaleIssueTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | UNCLASSIFIED(0, "æªå¤å®"), |
| | | GENERAL(1, "ä¸è¬é®é¢"), |
| | | REPAIR(2, "ç»´ä¿®é®é¢"), |
| | | RETURN(3, "éè´§é®é¢"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(AfterSaleIssueTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | private final Integer type; |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * å®åç»´ä¿®ç¶ææä¸¾ |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum AfterSaleRepairStatusEnum implements ArrayValuable<Integer> { |
| | | |
| | | PENDING(0, "å¾
å¤ç"), |
| | | IN_PROGRESS(10, "ç»´ä¿®ä¸"), |
| | | COMPLETED(20, "已宿"), |
| | | CLOSED(30, "å·²å
³é"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(AfterSaleRepairStatusEnum::getStatus).toArray(Integer[]::new); |
| | | |
| | | private final Integer status; |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * å®åéè´§ç¶ææä¸¾ |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum AfterSaleReturnStatusEnum implements ArrayValuable<Integer> { |
| | | |
| | | DRAFT(0, "è稿"), |
| | | AUDITING(10, "éå®å®¡æ ¸ä¸"), |
| | | APPROVED(20, "å®¡æ ¸éè¿-已忥MES"), |
| | | INSPECTING(30, "æ£éªä¸"), |
| | | INSPECTED(40, "æ£éªå®æ"), |
| | | INBOUND(50, "å·²å
¥åº"), |
| | | REFUNDED(60, "鿬¾/æ¢è´§å®æ"), |
| | | CLOSED(70, "å·²å
³é"), |
| | | CANCELED(99, "已忶"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(AfterSaleReturnStatusEnum::getStatus).toArray(Integer[]::new); |
| | | |
| | | private final Integer status; |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.Getter; |
| | | import lombok.RequiredArgsConstructor; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * å®åå·¥åç¶ææä¸¾ |
| | | */ |
| | | @RequiredArgsConstructor |
| | | @Getter |
| | | public enum AfterSaleTicketStatusEnum implements ArrayValuable<Integer> { |
| | | |
| | | DRAFT(0, "è稿"), |
| | | PROCESSING(10, "å¤çä¸"), |
| | | WAITING_RETURN(30, "å¾
éè´§"), |
| | | WAITING_REFUND(40, "å¾
鿬¾/æ¢è´§"), |
| | | COMPLETED(50, "å·²å®ç»"), |
| | | CLOSED(60, "å·²å
³é"), |
| | | CANCELED(99, "已忶"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()) |
| | | .map(AfterSaleTicketStatusEnum::getStatus).toArray(Integer[]::new); |
| | | |
| | | private final Integer status; |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums; |
| | | |
| | | import cn.iocoder.yudao.framework.common.exception.ErrorCode; |
| | | |
| | | /** |
| | | * å®å模åéè¯¯ç æä¸¾ç±» |
| | | * <p> |
| | | * aftersales ç³»ç»ï¼ä½¿ç¨ 1-022-000-000 段 |
| | | */ |
| | | public interface ErrorCodeConstants { |
| | | |
| | | // ========== å®åå·¥å 1-022-000-000 ========== |
| | | ErrorCode TICKET_NOT_EXISTS = new ErrorCode(1_022_000_000, "å®åå·¥åä¸åå¨"); |
| | | ErrorCode TICKET_NO_EXISTS = new ErrorCode(1_022_000_001, "çæå·¥åå·éå¤ï¼è¯·éè¯"); |
| | | ErrorCode TICKET_DELETE_FAIL_NOT_DRAFT = new ErrorCode(1_022_000_002, "å·¥å䏿¯èç¨¿ç¶æï¼æ æ³å é¤"); |
| | | ErrorCode TICKET_UPDATE_FAIL_STATUS = new ErrorCode(1_022_000_003, "æ´æ°å·¥åç¶æå¤±è´¥ï¼åå ï¼å·²ç»æ¯è¯¥ç¶æ"); |
| | | ErrorCode TICKET_RESOLVE_FAIL = new ErrorCode(1_022_000_004, "å®ç»å·¥å失败ï¼åå ï¼å·¥å䏿¯å¤çä¸ç¶æ"); |
| | | ErrorCode TICKET_CLOSE_FAIL = new ErrorCode(1_022_000_005, "å
³éå·¥å失败ï¼åå ï¼å·¥åæªå®ç»"); |
| | | ErrorCode TICKET_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_022_000_006, "æäº¤å·¥å审æ¹å¤±è´¥ï¼åå ï¼å·¥å䏿¯èç¨¿ç¶æ"); |
| | | ErrorCode TICKET_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_022_000_007, "å®åå·¥åå®¡æ¹æµç¨ä¸åå¨ææªæ¿æ´»ï¼è¯·æ£æ¥ BPM é
ç½®"); |
| | | ErrorCode TICKET_STATUS_ERROR = new ErrorCode(1_022_000_008, "å·¥åå½åç¶æä¸å
è®¸æ¤æä½"); |
| | | |
| | | // ========== å®åå·¥åæç»è¡ 1-022-001-000 ========== |
| | | ErrorCode TICKET_ITEM_NOT_EXISTS = new ErrorCode(1_022_001_000, "å·¥åæç»è¡ä¸åå¨"); |
| | | ErrorCode TICKET_ITEM_EMPTY = new ErrorCode(1_022_001_001, "å·¥åæç»è¡ä¸è½ä¸ºç©º"); |
| | | |
| | | // ========== éè´§ç³è¯· 1-022-002-000 ========== |
| | | ErrorCode RETURN_NOT_EXISTS = new ErrorCode(1_022_002_000, "éè´§ç³è¯·ä¸åå¨"); |
| | | ErrorCode RETURN_NO_EXISTS = new ErrorCode(1_022_002_001, "çæéè´§åå·éå¤ï¼è¯·éè¯"); |
| | | ErrorCode RETURN_APPROVE_FAIL = new ErrorCode(1_022_002_002, "å®¡æ ¸éè´§ç³è¯·å¤±è´¥ï¼åå ï¼ä¸æ¯å¾
å®¡æ ¸ç¶æ"); |
| | | ErrorCode RETURN_ITEM_EMPTY = new ErrorCode(1_022_002_003, "éè´§æç»è¡ä¸è½ä¸ºç©º"); |
| | | ErrorCode RETURN_DELETE_FAIL_NOT_DRAFT = new ErrorCode(1_022_002_004, "éè´§ç³è¯·ä¸æ¯èç¨¿ç¶æï¼æ æ³å é¤"); |
| | | |
| | | // ========== ç»´ä¿®è®°å½ 1-022-003-000 ========== |
| | | ErrorCode REPAIR_NOT_EXISTS = new ErrorCode(1_022_003_000, "维修记å½ä¸åå¨"); |
| | | ErrorCode REPAIR_UPDATE_FAIL_STATUS = new ErrorCode(1_022_003_001, "æ´æ°ç»´ä¿®ç¶æå¤±è´¥ï¼åå ï¼å·²ç»æ¯è¯¥ç¶æ"); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums; |
| | | |
| | | /** |
| | | * å®å模åæä½æ¥å¿å¸¸é |
| | | */ |
| | | public interface LogRecordConstants { |
| | | |
| | | // ======================= å®åå·¥å ======================= |
| | | |
| | | String AFTER_SALE_TICKET_TYPE = "å®åå·¥å"; |
| | | String AFTER_SALE_TICKET_CREATE_SUB_TYPE = "å建å®åå·¥å"; |
| | | String AFTER_SALE_TICKET_CREATE_SUCCESS = "å建äºå®åå·¥åã{{#ticket.name}}ã"; |
| | | String AFTER_SALE_TICKET_UPDATE_SUB_TYPE = "æ´æ°å®åå·¥å"; |
| | | String AFTER_SALE_TICKET_UPDATE_SUCCESS = "æ´æ°äºå®åå·¥åã{{#ticketName}}ã: {_DIFF{#updateReqVO}}"; |
| | | String AFTER_SALE_TICKET_DELETE_SUB_TYPE = "å é¤å®åå·¥å"; |
| | | String AFTER_SALE_TICKET_DELETE_SUCCESS = "å é¤äºå®åå·¥åã{{#ticketName}}ã"; |
| | | String AFTER_SALE_TICKET_ASSIGN_SUB_TYPE = "åé
å¤ç人"; |
| | | String AFTER_SALE_TICKET_ASSIGN_SUCCESS = "å°å®åå·¥åã{{#ticketName}}ãåé
ç»ã{getAdminUserById{#handlerUserId}}ã"; |
| | | String AFTER_SALE_TICKET_CLASSIFY_SUB_TYPE = "é®é¢å¤å®"; |
| | | String AFTER_SALE_TICKET_CLASSIFY_SUCCESS = "对å®åå·¥åã{{#ticketName}}ãè¿è¡äºé®é¢å¤å®ï¼ã{{#issueTypeName}}ã"; |
| | | String AFTER_SALE_TICKET_RESOLVE_SUB_TYPE = "å®ç»å·¥å"; |
| | | String AFTER_SALE_TICKET_RESOLVE_SUCCESS = "å®ç»äºå®åå·¥åã{{#ticketName}}ã"; |
| | | String AFTER_SALE_TICKET_CLOSE_SUB_TYPE = "å
³éå·¥å"; |
| | | String AFTER_SALE_TICKET_CLOSE_SUCCESS = "å
³éäºå®åå·¥åã{{#ticketName}}ã"; |
| | | String AFTER_SALE_TICKET_CANCEL_SUB_TYPE = "åæ¶å·¥å"; |
| | | String AFTER_SALE_TICKET_CANCEL_SUCCESS = "åæ¶äºå®åå·¥åã{{#ticketName}}ã"; |
| | | String AFTER_SALE_TICKET_SUBMIT_SUB_TYPE = "æäº¤å·¥å审æ¹"; |
| | | String AFTER_SALE_TICKET_SUBMIT_SUCCESS = "æäº¤å®åå·¥åã{{#ticketName}}ãå®¡æ¹æå"; |
| | | |
| | | // ======================= éè´§ç³è¯· ======================= |
| | | |
| | | String AFTER_SALE_RETURN_TYPE = "å®åéè´§"; |
| | | String AFTER_SALE_RETURN_CREATE_SUB_TYPE = "å建éè´§ç³è¯·"; |
| | | String AFTER_SALE_RETURN_CREATE_SUCCESS = "å建äºéè´§ç³è¯·ã{{#returnDO.no}}ã"; |
| | | String AFTER_SALE_RETURN_APPROVE_SUB_TYPE = "å®¡æ ¸éè´§ç³è¯·"; |
| | | String AFTER_SALE_RETURN_APPROVE_SUCCESS = "å®¡æ ¸éè¿äºéè´§ç³è¯·ã{{#returnNo}}ãï¼å·²åæ¥å°MESéè´§"; |
| | | String AFTER_SALE_RETURN_DELETE_SUB_TYPE = "å é¤éè´§ç³è¯·"; |
| | | String AFTER_SALE_RETURN_DELETE_SUCCESS = "å é¤äºéè´§ç³è¯·ã{{#returnNo}}ã"; |
| | | |
| | | // ======================= ç»´ä¿®è®°å½ ======================= |
| | | |
| | | String AFTER_SALE_REPAIR_TYPE = "å®åç»´ä¿®"; |
| | | String AFTER_SALE_REPAIR_CREATE_SUB_TYPE = "å建维修记å½"; |
| | | String AFTER_SALE_REPAIR_CREATE_SUCCESS = "å建äºç»´ä¿®è®°å½ã{{#repair.id}}ã"; |
| | | String AFTER_SALE_REPAIR_COMPLETE_SUB_TYPE = "å®æç»´ä¿®"; |
| | | String AFTER_SALE_REPAIR_COMPLETE_SUCCESS = "宿äºç»´ä¿®è®°å½ã{{#repairId}}ãï¼ç»´ä¿®ç»æï¼ã{{#repairResult}}ã"; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums.permission; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * å®åæ¨¡åæ°æ®æéçº§å«æä¸¾ |
| | | * |
| | | * OWNER > WRITE > READ |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum AfterSalePermissionLevelEnum implements ArrayValuable<Integer> { |
| | | |
| | | OWNER(1, "è´è´£äºº"), |
| | | READ(2, "åªè¯»"), |
| | | WRITE(3, "读å"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(AfterSalePermissionLevelEnum::getLevel).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * çº§å« |
| | | */ |
| | | private final Integer level; |
| | | /** |
| | | * 级å«åç§° |
| | | */ |
| | | private final String name; |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | public static boolean isOwner(Integer level) { |
| | | return ObjUtil.equal(OWNER.level, level); |
| | | } |
| | | |
| | | public static boolean isRead(Integer level) { |
| | | return ObjUtil.equal(READ.level, level); |
| | | } |
| | | |
| | | public static boolean isWrite(Integer level) { |
| | | return ObjUtil.equal(WRITE.level, level); |
| | | } |
| | | |
| | | public static String getNameByLevel(Integer level) { |
| | | AfterSalePermissionLevelEnum typeEnum = CollUtil.findOne(CollUtil.newArrayList(AfterSalePermissionLevelEnum.values()), |
| | | item -> ObjUtil.equal(item.level, level)); |
| | | return typeEnum == null ? null : typeEnum.getName(); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.enums.permission; |
| | | |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * å®å模åå表æ£ç´¢åºæ¯ |
| | | */ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public enum AfterSaleSceneTypeEnum implements ArrayValuable<Integer> { |
| | | |
| | | OWNER(1, "æè´è´£ç"), |
| | | INVOLVED(2, "æåä¸ç"), |
| | | SUBORDINATE(3, "ä¸å±è´è´£ç"), |
| | | ALL(4, "å
¨é¨"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(AfterSaleSceneTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | | /** |
| | | * åºæ¯ç±»å |
| | | */ |
| | | private final Integer type; |
| | | /** |
| | | * åºæ¯åç§° |
| | | */ |
| | | private final String name; |
| | | |
| | | public static boolean isOwner(Integer type) { |
| | | return ObjUtil.equal(OWNER.getType(), type); |
| | | } |
| | | |
| | | public static boolean isInvolved(Integer type) { |
| | | return ObjUtil.equal(INVOLVED.getType(), type); |
| | | } |
| | | |
| | | public static boolean isSubordinate(Integer type) { |
| | | return ObjUtil.equal(SUBORDINATE.getType(), type); |
| | | } |
| | | |
| | | public static boolean isAll(Integer type) { |
| | | return ObjUtil.equal(ALL.getType(), type); |
| | | } |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.permission; |
| | | |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.permission.AfterSalePermissionDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSalePermissionLevelEnum; |
| | | import cn.iocoder.yudao.module.aftersales.service.permission.bo.AfterSalePermissionCreateReqBO; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åæ¨¡åæ°æ®æé Service æ¥å£ |
| | | */ |
| | | public interface AfterSalePermissionService { |
| | | |
| | | /** |
| | | * åå»ºæ°æ®æéï¼è´è´£äººæéï¼ |
| | | * |
| | | * @param createReqBO åå»ºä¿¡æ¯ |
| | | * @return ç¼å· |
| | | */ |
| | | Long createPermission(AfterSalePermissionCreateReqBO createReqBO); |
| | | |
| | | /** |
| | | * å 餿°æ®æé |
| | | * |
| | | * @param bizType æ°æ®ç±»åï¼å
³è {@link AfterSaleBizTypeEnum} |
| | | * @param bizId æ°æ®ç¼å· |
| | | */ |
| | | void deletePermission(Integer bizType, Long bizId); |
| | | |
| | | /** |
| | | * è·åæ°æ®æéå表 |
| | | * |
| | | * @param bizType æ°æ®ç±»å |
| | | * @param bizId æ°æ®ç¼å· |
| | | * @return æéå表 |
| | | */ |
| | | List<AfterSalePermissionDO> getPermissionListByBiz(Integer bizType, Long bizId); |
| | | |
| | | /** |
| | | * è·åæ°æ®æéåè¡¨ï¼æ¹éï¼ |
| | | * |
| | | * @param bizType æ°æ®ç±»å |
| | | * @param bizIds æ°æ®ç¼å·å表 |
| | | * @return æéå表 |
| | | */ |
| | | List<AfterSalePermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds); |
| | | |
| | | /** |
| | | * æ ¡éªæ¯å¦ææå®æ°æ®çæä½æé |
| | | * |
| | | * @param bizType æ°æ®ç±»å |
| | | * @param bizId æ°æ®ç¼å· |
| | | * @param userId ç¨æ·ç¼å· |
| | | * @param level æéçº§å« |
| | | * @return æ¯å¦ææé |
| | | */ |
| | | boolean hasPermission(Integer bizType, Long bizId, Long userId, AfterSalePermissionLevelEnum level); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.permission; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.permission.AfterSalePermissionDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.permission.AfterSalePermissionMapper; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSalePermissionLevelEnum; |
| | | import cn.iocoder.yudao.module.aftersales.service.permission.bo.AfterSalePermissionCreateReqBO; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åæ¨¡åæ°æ®æé Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class AfterSalePermissionServiceImpl implements AfterSalePermissionService { |
| | | |
| | | @Resource |
| | | private AfterSalePermissionMapper afterSalePermissionMapper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createPermission(AfterSalePermissionCreateReqBO createReqBO) { |
| | | AfterSalePermissionDO permission = BeanUtils.toBean(createReqBO, AfterSalePermissionDO.class); |
| | | afterSalePermissionMapper.insert(permission); |
| | | return permission.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deletePermission(Integer bizType, Long bizId) { |
| | | afterSalePermissionMapper.deleteByBiz(bizType, bizId); |
| | | } |
| | | |
| | | @Override |
| | | public List<AfterSalePermissionDO> getPermissionListByBiz(Integer bizType, Long bizId) { |
| | | return afterSalePermissionMapper.selectListByBiz(bizType, bizId); |
| | | } |
| | | |
| | | @Override |
| | | public List<AfterSalePermissionDO> getPermissionListByBiz(Integer bizType, Collection<Long> bizIds) { |
| | | if (CollUtil.isEmpty(bizIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return afterSalePermissionMapper.selectListByBiz(bizType, bizIds); |
| | | } |
| | | |
| | | @Override |
| | | public boolean hasPermission(Integer bizType, Long bizId, Long userId, AfterSalePermissionLevelEnum level) { |
| | | List<AfterSalePermissionDO> permissionList = getPermissionListByBiz(bizType, bizId); |
| | | return permissionList.stream() |
| | | .anyMatch(p -> ObjUtil.equal(p.getUserId(), userId) |
| | | && ObjUtil.equal(p.getLevel(), level.getLevel())); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.permission.bo; |
| | | |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSalePermissionLevelEnum; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * å®åæ¨¡åæ°æ®æéå建 Request BO |
| | | */ |
| | | @Data |
| | | public class AfterSalePermissionCreateReqBO { |
| | | |
| | | /** |
| | | * æ°æ®ç±»åï¼å
³è {@link AfterSaleBizTypeEnum} |
| | | */ |
| | | @NotNull(message = "æ°æ®ç±»åä¸è½ä¸ºç©º") |
| | | private Integer bizType; |
| | | |
| | | /** |
| | | * æ°æ®ç¼å· |
| | | */ |
| | | @NotNull(message = "æ°æ®ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long bizId; |
| | | |
| | | /** |
| | | * ç¨æ·ç¼å· |
| | | */ |
| | | @NotNull(message = "ç¨æ·ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long userId; |
| | | |
| | | /** |
| | | * æé级å«ï¼å
³è {@link AfterSalePermissionLevelEnum} |
| | | */ |
| | | @NotNull(message = "æé级å«ä¸è½ä¸ºç©º") |
| | | private Integer level; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.repair; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.repair.AfterSaleRepairDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åç»´ä¿®è®°å½ Service æ¥å£ |
| | | */ |
| | | public interface AfterSaleRepairService { |
| | | |
| | | /** |
| | | * åå»ºç»´ä¿®è®°å½ |
| | | * |
| | | * @param repairDO ç»´ä¿®ä¿¡æ¯ |
| | | * @return ç¼å· |
| | | */ |
| | | Long createRepair(@Valid AfterSaleRepairDO repairDO); |
| | | |
| | | /** |
| | | * æ´æ°ç»´ä¿®è®°å½ |
| | | * |
| | | * @param repairDO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updateRepair(@Valid AfterSaleRepairDO repairDO); |
| | | |
| | | /** |
| | | * å®æç»´ä¿® |
| | | * |
| | | * @param id 维修记å½ç¼å· |
| | | */ |
| | | void completeRepair(Long id); |
| | | |
| | | /** |
| | | * è·å¾ç»´ä¿®è®°å½ |
| | | * |
| | | * @param id ç¼å· |
| | | * @return ç»´ä¿®è®°å½ |
| | | */ |
| | | AfterSaleRepairDO getRepair(Long id); |
| | | |
| | | /** |
| | | * è·å¾ç»´ä¿®è®°å½å表 |
| | | * |
| | | * @param ids ç¼å·å表 |
| | | * @return 维修记å½å表 |
| | | */ |
| | | List<AfterSaleRepairDO> getRepairList(Collection<Long> ids); |
| | | |
| | | /** |
| | | * è·å¾ç»´ä¿®è®°å½å页 |
| | | * |
| | | * @param pageParam å页忰 |
| | | * @param ticketId å
³èå·¥åç¼å· |
| | | * @param status ç»´ä¿®ç¶æ |
| | | * @return 维修记å½å页 |
| | | */ |
| | | PageResult<AfterSaleRepairDO> getRepairPage(Object pageParam, Long ticketId, Integer status); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.repair; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.repair.AfterSaleRepairDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.repair.AfterSaleRepairMapper; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.ticket.AfterSaleTicketMapper; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleRepairStatusEnum; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.aftersales.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * å®åç»´ä¿®è®°å½ Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class AfterSaleRepairServiceImpl implements AfterSaleRepairService { |
| | | |
| | | @Resource |
| | | private AfterSaleRepairMapper repairMapper; |
| | | @Resource |
| | | private AfterSaleTicketMapper ticketMapper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createRepair(AfterSaleRepairDO repairDO) { |
| | | // æ ¡éªå·¥ååå¨ |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(repairDO.getTicketId()); |
| | | if (ticket == null) { |
| | | throw exception(TICKET_NOT_EXISTS); |
| | | } |
| | | |
| | | repairDO.setStatus(AfterSaleRepairStatusEnum.PENDING.getStatus()); |
| | | repairMapper.insert(repairDO); |
| | | |
| | | // æ´æ°å·¥åå
³èç»´ä¿®è®°å½ |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(ticket.getId()) |
| | | .setRepairId(repairDO.getId())); |
| | | |
| | | return repairDO.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateRepair(AfterSaleRepairDO repairDO) { |
| | | validateRepairExists(repairDO.getId()); |
| | | repairMapper.updateById(repairDO); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void completeRepair(Long id) { |
| | | AfterSaleRepairDO repair = validateRepairExists(id); |
| | | repairMapper.updateById(new AfterSaleRepairDO().setId(id) |
| | | .setStatus(AfterSaleRepairStatusEnum.COMPLETED.getStatus()) |
| | | .setFinishTime(LocalDateTime.now())); |
| | | // æ´æ°å·¥åç¶æ |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(repair.getTicketId()); |
| | | if (ticket != null) { |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(ticket.getId()) |
| | | .setStatus(cn.iocoder.yudao.module.aftersales.enums.AfterSaleTicketStatusEnum.COMPLETED.getStatus()) |
| | | .setResolvedTime(LocalDateTime.now())); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public AfterSaleRepairDO getRepair(Long id) { |
| | | return validateRepairExists(id); |
| | | } |
| | | |
| | | @Override |
| | | public List<AfterSaleRepairDO> getRepairList(Collection<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return List.of(); |
| | | } |
| | | return repairMapper.selectBatchIds(ids); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<AfterSaleRepairDO> getRepairPage(Object pageParam, Long ticketId, Integer status) { |
| | | if (pageParam instanceof PageParam) { |
| | | return repairMapper.selectPage((PageParam) pageParam, ticketId, status); |
| | | } |
| | | return repairMapper.selectPage(new PageParam(), ticketId, status); |
| | | } |
| | | |
| | | // ========== å
鍿¹æ³ ========== |
| | | |
| | | private AfterSaleRepairDO validateRepairExists(Long id) { |
| | | AfterSaleRepairDO repair = repairMapper.selectById(id); |
| | | if (repair == null) { |
| | | throw exception(REPAIR_NOT_EXISTS); |
| | | } |
| | | return repair; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.returnobj; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo.AfterSaleReturnPageReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo.AfterSaleReturnSaveReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnItemDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯· Service æ¥å£ |
| | | */ |
| | | public interface AfterSaleReturnService { |
| | | |
| | | /** |
| | | * å建éè´§ç³è¯· |
| | | * |
| | | * @param createReqVO åå»ºä¿¡æ¯ |
| | | * @param userId ç¨æ·ç¼å· |
| | | * @return ç¼å· |
| | | */ |
| | | Long createReturn(@Valid AfterSaleReturnSaveReqVO createReqVO, Long userId); |
| | | |
| | | /** |
| | | * å®¡æ ¸éè¿ï¼è§¦å MES éè´§æµç¨ï¼ |
| | | * |
| | | * @param id éè´§ç³è¯·ç¼å· |
| | | */ |
| | | void approveReturn(Long id); |
| | | |
| | | /** |
| | | * è·å¾éè´§ç³è¯· |
| | | * |
| | | * @param id ç¼å· |
| | | * @return éè´§ç³è¯· |
| | | */ |
| | | AfterSaleReturnDO getReturn(Long id); |
| | | |
| | | /** |
| | | * è·å¾éè´§ç³è¯·å表 |
| | | * |
| | | * @param ids ç¼å·å表 |
| | | * @return éè´§ç³è¯·å表 |
| | | */ |
| | | List<AfterSaleReturnDO> getReturnList(Collection<Long> ids); |
| | | |
| | | /** |
| | | * è·å¾éè´§ç³è¯·å页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | | * @param userId ç¨æ·ç¼å· |
| | | * @return éè´§ç³è¯·å页 |
| | | */ |
| | | PageResult<AfterSaleReturnDO> getReturnPage(AfterSaleReturnPageReqVO pageReqVO, Long userId); |
| | | |
| | | /** |
| | | * è·å¾éè´§æç»è¡å表 |
| | | * |
| | | * @param returnId éè´§ç³è¯·ç¼å· |
| | | * @return æç»è¡å表 |
| | | */ |
| | | List<AfterSaleReturnItemDO> getReturnItemListByReturnId(Long returnId); |
| | | |
| | | /** |
| | | * MES è´¨æ£å®æåè° |
| | | * |
| | | * @param returnId éè´§ç³è¯·ç¼å· |
| | | * @param qualityResult è´¨æ£ç»è®º |
| | | * @param reportUrl è´¨æ£æ¥å URL |
| | | */ |
| | | void onQualityFinished(Long returnId, String qualityResult, String reportUrl); |
| | | |
| | | /** |
| | | * MES éè´§å
¥åºå®æåè° |
| | | * |
| | | * @param returnId éè´§ç³è¯·ç¼å· |
| | | */ |
| | | void onInboundFinished(Long returnId); |
| | | |
| | | /** |
| | | * ERP 鿬¾å®æåè° |
| | | * |
| | | * @param returnId éè´§ç³è¯·ç¼å· |
| | | * @param actualRefundPrice å®ééé¢ |
| | | */ |
| | | void onRefundCompleted(Long returnId, BigDecimal actualRefundPrice); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.returnobj; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo.AfterSaleReturnPageReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.returnobj.vo.AfterSaleReturnSaveReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.returnobj.AfterSaleReturnItemDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.returnobj.AfterSaleReturnItemMapper; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.returnobj.AfterSaleReturnMapper; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.ticket.AfterSaleTicketMapper; |
| | | import cn.iocoder.yudao.module.aftersales.dal.redis.no.AfterSaleNoRedisDAO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleReturnStatusEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleTicketStatusEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSalePermissionLevelEnum; |
| | | import cn.iocoder.yudao.module.aftersales.service.permission.AfterSalePermissionService; |
| | | import cn.iocoder.yudao.module.aftersales.service.permission.bo.AfterSalePermissionCreateReqBO; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.MesWmReturnSalesApi; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesCreateReqDTO; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.aftersales.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * å®åéè´§ç³è¯· Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class AfterSaleReturnServiceImpl implements AfterSaleReturnService { |
| | | |
| | | @Resource |
| | | private AfterSaleReturnMapper returnMapper; |
| | | @Resource |
| | | private AfterSaleReturnItemMapper returnItemMapper; |
| | | @Resource |
| | | private AfterSaleTicketMapper ticketMapper; |
| | | |
| | | @Resource |
| | | private AfterSaleNoRedisDAO noRedisDAO; |
| | | |
| | | @Resource |
| | | private AfterSalePermissionService permissionService; |
| | | |
| | | @Resource |
| | | private MesWmReturnSalesApi mesWmReturnSalesApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createReturn(AfterSaleReturnSaveReqVO createReqVO, Long userId) { |
| | | // 1. æ ¡éªå·¥ååå¨ |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(createReqVO.getTicketId()); |
| | | if (ticket == null) { |
| | | throw exception(TICKET_NOT_EXISTS); |
| | | } |
| | | |
| | | // 2. çæåå· |
| | | String no = noRedisDAO.generate(AfterSaleNoRedisDAO.RETURN_NO_PREFIX); |
| | | if (returnMapper.selectByNo(no) != null) { |
| | | throw exception(RETURN_NO_EXISTS); |
| | | } |
| | | |
| | | // 3. 计ç®åºéæ»éé¢ |
| | | BigDecimal totalReturnPrice = BigDecimal.ZERO; |
| | | if (CollUtil.isNotEmpty(createReqVO.getItems())) { |
| | | totalReturnPrice = createReqVO.getItems().stream() |
| | | .map(item -> item.getReturnPrice() != null ? item.getReturnPrice() : BigDecimal.ZERO) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | } |
| | | |
| | | // 4. æå
¥éè´§ç³è¯· |
| | | AfterSaleReturnDO returnDO = BeanUtils.toBean(createReqVO, AfterSaleReturnDO.class) |
| | | .setNo(no) |
| | | .setTotalReturnPrice(totalReturnPrice) |
| | | .setStatus(AfterSaleReturnStatusEnum.DRAFT.getStatus()); |
| | | returnMapper.insert(returnDO); |
| | | |
| | | // 5. æå
¥éè´§æç»è¡ |
| | | if (CollUtil.isNotEmpty(createReqVO.getItems())) { |
| | | createReqVO.getItems().forEach(item -> { |
| | | AfterSaleReturnItemDO itemDO = BeanUtils.toBean(item, AfterSaleReturnItemDO.class); |
| | | itemDO.setReturnId(returnDO.getId()); |
| | | returnItemMapper.insert(itemDO); |
| | | }); |
| | | } |
| | | |
| | | // 6. åå»ºæ°æ®æé |
| | | AfterSalePermissionCreateReqBO permBO = new AfterSalePermissionCreateReqBO(); |
| | | permBO.setBizType(AfterSaleBizTypeEnum.AFTER_SALE_RETURN.getType()); |
| | | permBO.setBizId(returnDO.getId()); |
| | | permBO.setUserId(userId); |
| | | permBO.setLevel(AfterSalePermissionLevelEnum.OWNER.getLevel()); |
| | | permissionService.createPermission(permBO); |
| | | |
| | | // 7. æ´æ°å·¥åç¶æä¸ºå¾
éè´§ |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(ticket.getId()) |
| | | .setReturnId(returnDO.getId()) |
| | | .setStatus(AfterSaleTicketStatusEnum.WAITING_RETURN.getStatus())); |
| | | |
| | | return returnDO.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void approveReturn(Long id) { |
| | | // 1. æ ¡éªéè´§ç³è¯· |
| | | AfterSaleReturnDO returnDO = validateReturnExists(id); |
| | | if (!AfterSaleReturnStatusEnum.DRAFT.getStatus().equals(returnDO.getStatus())) { |
| | | throw exception(RETURN_APPROVE_FAIL); |
| | | } |
| | | |
| | | // 2. è·åå
³èå·¥åï¼ç¨äºè·åéå®è®¢åå·çåä½ä¿¡æ¯ï¼ |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(returnDO.getTicketId()); |
| | | |
| | | // 3. è°ç¨ MES å建éå®éè´§å |
| | | MesWmReturnSalesCreateReqDTO mesReqDTO = new MesWmReturnSalesCreateReqDTO(); |
| | | mesReqDTO.setCode(returnDO.getNo()); |
| | | mesReqDTO.setName("å®åéè´§-" + returnDO.getNo()); |
| | | mesReqDTO.setSaleOrderId(returnDO.getSaleOrderId()); |
| | | mesReqDTO.setSalesOrderCode(ticket != null ? ticket.getSaleOrderNo() : null); |
| | | mesReqDTO.setClientId(returnDO.getCustomerId()); |
| | | mesReqDTO.setReturnDate(LocalDate.now()); |
| | | mesReqDTO.setReturnReason(returnDO.getReturnReason()); |
| | | mesReqDTO.setRemark("å®åå·¥åéè´§ - å·¥åå·: " + (ticket != null ? ticket.getNo() : "")); |
| | | mesReqDTO.setAfterSaleReturnId(returnDO.getId()); |
| | | Long mesReturnId = mesWmReturnSalesApi.createReturnSales(mesReqDTO); |
| | | |
| | | // 4. æ´æ°éè´§ç³è¯·ç¶æ |
| | | returnMapper.updateById(new AfterSaleReturnDO().setId(id) |
| | | .setStatus(AfterSaleReturnStatusEnum.APPROVED.getStatus()) |
| | | .setMesReturnId(mesReturnId) |
| | | .setMesReturnCode(returnDO.getNo()) |
| | | .setAuditTime(LocalDateTime.now())); |
| | | } |
| | | |
| | | @Override |
| | | public AfterSaleReturnDO getReturn(Long id) { |
| | | return validateReturnExists(id); |
| | | } |
| | | |
| | | @Override |
| | | public List<AfterSaleReturnDO> getReturnList(Collection<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return List.of(); |
| | | } |
| | | return returnMapper.selectBatchIds(ids); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<AfterSaleReturnDO> getReturnPage(AfterSaleReturnPageReqVO pageReqVO, Long userId) { |
| | | return returnMapper.selectPage(pageReqVO, userId, pageReqVO.getSceneType(), |
| | | pageReqVO.getNo(), pageReqVO.getTicketId(), |
| | | pageReqVO.getCustomerId(), pageReqVO.getStatus()); |
| | | } |
| | | |
| | | @Override |
| | | public List<AfterSaleReturnItemDO> getReturnItemListByReturnId(Long returnId) { |
| | | return returnItemMapper.selectListByReturnId(returnId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void onQualityFinished(Long returnId, String qualityResult, String reportUrl) { |
| | | AfterSaleReturnDO returnDO = validateReturnExists(returnId); |
| | | returnMapper.updateById(new AfterSaleReturnDO().setId(returnId) |
| | | .setQualityResult(qualityResult) |
| | | .setQualityReportUrl(reportUrl) |
| | | .setStatus(AfterSaleReturnStatusEnum.INSPECTED.getStatus())); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void onInboundFinished(Long returnId) { |
| | | AfterSaleReturnDO returnDO = validateReturnExists(returnId); |
| | | returnMapper.updateById(new AfterSaleReturnDO().setId(returnId) |
| | | .setStatus(AfterSaleReturnStatusEnum.INBOUND.getStatus()) |
| | | .setReturnInboundTime(LocalDateTime.now())); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void onRefundCompleted(Long returnId, BigDecimal actualRefundPrice) { |
| | | AfterSaleReturnDO returnDO = validateReturnExists(returnId); |
| | | returnMapper.updateById(new AfterSaleReturnDO().setId(returnId) |
| | | .setActualRefundPrice(actualRefundPrice) |
| | | .setStatus(AfterSaleReturnStatusEnum.REFUNDED.getStatus()) |
| | | .setRefundTime(LocalDateTime.now())); |
| | | |
| | | // æ´æ°å
³èå·¥åç¶æä¸ºå¾
鿬¾/æ¢è´§å®æ |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(returnDO.getTicketId()); |
| | | if (ticket != null) { |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(ticket.getId()) |
| | | .setStatus(AfterSaleTicketStatusEnum.WAITING_REFUND.getStatus())); |
| | | } |
| | | } |
| | | |
| | | // ========== å
鍿¹æ³ ========== |
| | | |
| | | private AfterSaleReturnDO validateReturnExists(Long id) { |
| | | AfterSaleReturnDO returnDO = returnMapper.selectById(id); |
| | | if (returnDO == null) { |
| | | throw exception(RETURN_NOT_EXISTS); |
| | | } |
| | | return returnDO; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.ticket; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketPageReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketSaveReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketItemDO; |
| | | import jakarta.validation.Valid; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å®åå·¥å Service æ¥å£ |
| | | */ |
| | | public interface AfterSaleTicketService { |
| | | |
| | | /** |
| | | * å建工å |
| | | * |
| | | * @param createReqVO åå»ºä¿¡æ¯ |
| | | * @param userId ç¨æ·ç¼å· |
| | | * @return ç¼å· |
| | | */ |
| | | Long createTicket(@Valid AfterSaleTicketSaveReqVO createReqVO, Long userId); |
| | | |
| | | /** |
| | | * æ´æ°å·¥å |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | | */ |
| | | void updateTicket(@Valid AfterSaleTicketSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * å é¤å·¥å |
| | | * |
| | | * @param id ç¼å· |
| | | */ |
| | | void deleteTicket(Long id); |
| | | |
| | | /** |
| | | * è·å¾å·¥å |
| | | * |
| | | * @param id ç¼å· |
| | | * @return å·¥å |
| | | */ |
| | | AfterSaleTicketDO getTicket(Long id); |
| | | |
| | | /** |
| | | * è·å¾å·¥åå表 |
| | | * |
| | | * @param ids ç¼å·å表 |
| | | * @return å·¥åå表 |
| | | */ |
| | | List<AfterSaleTicketDO> getTicketList(Collection<Long> ids); |
| | | |
| | | /** |
| | | * è·å¾å·¥åå页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | | * @param userId ç¨æ·ç¼å· |
| | | * @return å·¥åå页 |
| | | */ |
| | | PageResult<AfterSaleTicketDO> getTicketPage(AfterSaleTicketPageReqVO pageReqVO, Long userId); |
| | | |
| | | /** |
| | | * è·å¾å·¥åæç»è¡å表 |
| | | * |
| | | * @param ticketId å·¥åç¼å· |
| | | * @return æç»è¡å表 |
| | | */ |
| | | List<AfterSaleTicketItemDO> getTicketItemListByTicketId(Long ticketId); |
| | | |
| | | /** |
| | | * åé
å¤ç人 |
| | | * |
| | | * @param id å·¥åç¼å· |
| | | * @param handlerUserId å¤çäººç¨æ·ç¼å· |
| | | */ |
| | | void assignTicket(Long id, Long handlerUserId); |
| | | |
| | | /** |
| | | * é®é¢å¤å®ï¼ç¡®å®é®é¢ç±»åãåç±»ã严éç¨åº¦ï¼ |
| | | * |
| | | * @param id å·¥åç¼å· |
| | | * @param issueType é®é¢ç±»å |
| | | * @param issueCategory é®é¢åç±» |
| | | * @param severityLevel 严éç¨åº¦ |
| | | */ |
| | | void classifyTicket(Long id, Integer issueType, String issueCategory, Integer severityLevel); |
| | | |
| | | /** |
| | | * å®ç»å·¥å |
| | | * |
| | | * @param id å·¥åç¼å· |
| | | */ |
| | | void resolveTicket(Long id); |
| | | |
| | | /** |
| | | * å
³éå·¥å |
| | | * |
| | | * @param id å·¥åç¼å· |
| | | */ |
| | | void closeTicket(Long id); |
| | | |
| | | /** |
| | | * åæ¶å·¥å |
| | | * |
| | | * @param id å·¥åç¼å· |
| | | */ |
| | | void cancelTicket(Long id); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.service.ticket; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketPageReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketSaveReqVO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketItemDO; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.ticket.AfterSaleTicketItemMapper; |
| | | import cn.iocoder.yudao.module.aftersales.dal.mysql.ticket.AfterSaleTicketMapper; |
| | | import cn.iocoder.yudao.module.aftersales.dal.redis.no.AfterSaleNoRedisDAO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleTicketStatusEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSalePermissionLevelEnum; |
| | | import cn.iocoder.yudao.module.aftersales.service.permission.AfterSalePermissionService; |
| | | import cn.iocoder.yudao.module.aftersales.service.permission.bo.AfterSalePermissionCreateReqBO; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.aftersales.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * å®åå·¥å Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class AfterSaleTicketServiceImpl implements AfterSaleTicketService { |
| | | |
| | | @Resource |
| | | private AfterSaleTicketMapper ticketMapper; |
| | | @Resource |
| | | private AfterSaleTicketItemMapper ticketItemMapper; |
| | | |
| | | @Resource |
| | | private AfterSaleNoRedisDAO noRedisDAO; |
| | | |
| | | @Resource |
| | | private AfterSalePermissionService permissionService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createTicket(AfterSaleTicketSaveReqVO createReqVO, Long userId) { |
| | | // 1. çæåå· |
| | | String no = noRedisDAO.generate(AfterSaleNoRedisDAO.TICKET_NO_PREFIX); |
| | | if (ticketMapper.selectByNo(no) != null) { |
| | | throw exception(TICKET_NO_EXISTS); |
| | | } |
| | | |
| | | // 2. æå
¥å·¥å |
| | | AfterSaleTicketDO ticket = BeanUtils.toBean(createReqVO, AfterSaleTicketDO.class) |
| | | .setNo(no) |
| | | .setStatus(AfterSaleTicketStatusEnum.DRAFT.getStatus()) |
| | | .setOwnerUserId(userId); |
| | | ticketMapper.insert(ticket); |
| | | |
| | | // 3. æå
¥æç»è¡ |
| | | if (CollUtil.isNotEmpty(createReqVO.getItems())) { |
| | | createReqVO.getItems().forEach(item -> { |
| | | AfterSaleTicketItemDO itemDO = BeanUtils.toBean(item, AfterSaleTicketItemDO.class); |
| | | itemDO.setTicketId(ticket.getId()); |
| | | ticketItemMapper.insert(itemDO); |
| | | }); |
| | | } |
| | | |
| | | // 4. åå»ºæ°æ®æéï¼è´è´£äººï¼ |
| | | AfterSalePermissionCreateReqBO permBO = new AfterSalePermissionCreateReqBO(); |
| | | permBO.setBizType(AfterSaleBizTypeEnum.AFTER_SALE_TICKET.getType()); |
| | | permBO.setBizId(ticket.getId()); |
| | | permBO.setUserId(userId); |
| | | permBO.setLevel(AfterSalePermissionLevelEnum.OWNER.getLevel()); |
| | | permissionService.createPermission(permBO); |
| | | |
| | | return ticket.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateTicket(AfterSaleTicketSaveReqVO updateReqVO) { |
| | | // 1. æ ¡éªåå¨ |
| | | AfterSaleTicketDO ticket = validateTicketExists(updateReqVO.getId()); |
| | | validateTicketStatus(ticket, AfterSaleTicketStatusEnum.DRAFT); |
| | | |
| | | // 2. æ´æ°å·¥å |
| | | AfterSaleTicketDO updateObj = BeanUtils.toBean(updateReqVO, AfterSaleTicketDO.class); |
| | | ticketMapper.updateById(updateObj); |
| | | |
| | | // 3. æ´æ°æç»è¡ï¼å
å åå¢ï¼ |
| | | ticketItemMapper.deleteByTicketId(ticket.getId()); |
| | | if (CollUtil.isNotEmpty(updateReqVO.getItems())) { |
| | | updateReqVO.getItems().forEach(item -> { |
| | | AfterSaleTicketItemDO itemDO = BeanUtils.toBean(item, AfterSaleTicketItemDO.class); |
| | | itemDO.setTicketId(ticket.getId()); |
| | | ticketItemMapper.insert(itemDO); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteTicket(Long id) { |
| | | AfterSaleTicketDO ticket = validateTicketExists(id); |
| | | validateTicketStatus(ticket, AfterSaleTicketStatusEnum.DRAFT, AfterSaleTicketStatusEnum.CANCELED); |
| | | // 软å é¤ |
| | | ticketMapper.deleteById(id); |
| | | ticketItemMapper.deleteByTicketId(id); |
| | | permissionService.deletePermission(AfterSaleBizTypeEnum.AFTER_SALE_TICKET.getType(), id); |
| | | } |
| | | |
| | | @Override |
| | | public AfterSaleTicketDO getTicket(Long id) { |
| | | return validateTicketExists(id); |
| | | } |
| | | |
| | | @Override |
| | | public List<AfterSaleTicketDO> getTicketList(Collection<Long> ids) { |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return List.of(); |
| | | } |
| | | return ticketMapper.selectBatchIds(ids); |
| | | } |
| | | |
| | | @Override |
| | | public PageResult<AfterSaleTicketDO> getTicketPage(AfterSaleTicketPageReqVO pageReqVO, Long userId) { |
| | | return ticketMapper.selectPage(pageReqVO, userId, pageReqVO.getSceneType(), |
| | | pageReqVO.getNo(), pageReqVO.getName(), |
| | | pageReqVO.getCustomerId(), pageReqVO.getSaleOrderId(), |
| | | pageReqVO.getStatus(), pageReqVO.getIssueType()); |
| | | } |
| | | |
| | | @Override |
| | | public List<AfterSaleTicketItemDO> getTicketItemListByTicketId(Long ticketId) { |
| | | return ticketItemMapper.selectListByTicketId(ticketId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void assignTicket(Long id, Long handlerUserId) { |
| | | AfterSaleTicketDO ticket = validateTicketExists(id); |
| | | validateTicketStatus(ticket, AfterSaleTicketStatusEnum.DRAFT, AfterSaleTicketStatusEnum.PROCESSING); |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(id).setHandlerUserId(handlerUserId) |
| | | .setStatus(AfterSaleTicketStatusEnum.PROCESSING.getStatus())); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void classifyTicket(Long id, Integer issueType, String issueCategory, Integer severityLevel) { |
| | | AfterSaleTicketDO ticket = validateTicketExists(id); |
| | | validateTicketStatus(ticket, AfterSaleTicketStatusEnum.PROCESSING); |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(id) |
| | | .setIssueType(issueType).setIssueCategory(issueCategory).setSeverityLevel(severityLevel)); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void resolveTicket(Long id) { |
| | | AfterSaleTicketDO ticket = validateTicketExists(id); |
| | | validateTicketStatus(ticket, AfterSaleTicketStatusEnum.PROCESSING, |
| | | AfterSaleTicketStatusEnum.WAITING_RETURN, AfterSaleTicketStatusEnum.WAITING_REFUND); |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(id) |
| | | .setStatus(AfterSaleTicketStatusEnum.COMPLETED.getStatus()) |
| | | .setResolvedTime(LocalDateTime.now())); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void closeTicket(Long id) { |
| | | AfterSaleTicketDO ticket = validateTicketExists(id); |
| | | validateTicketStatus(ticket, AfterSaleTicketStatusEnum.COMPLETED); |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(id) |
| | | .setStatus(AfterSaleTicketStatusEnum.CLOSED.getStatus()) |
| | | .setClosedTime(LocalDateTime.now())); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cancelTicket(Long id) { |
| | | AfterSaleTicketDO ticket = validateTicketExists(id); |
| | | validateTicketStatus(ticket, AfterSaleTicketStatusEnum.DRAFT, AfterSaleTicketStatusEnum.PROCESSING); |
| | | ticketMapper.updateById(new AfterSaleTicketDO().setId(id) |
| | | .setStatus(AfterSaleTicketStatusEnum.CANCELED.getStatus())); |
| | | } |
| | | |
| | | // ========== å
鍿¹æ³ ========== |
| | | |
| | | private AfterSaleTicketDO validateTicketExists(Long id) { |
| | | AfterSaleTicketDO ticket = ticketMapper.selectById(id); |
| | | if (ticket == null) { |
| | | throw exception(TICKET_NOT_EXISTS); |
| | | } |
| | | return ticket; |
| | | } |
| | | |
| | | private void validateTicketStatus(AfterSaleTicketDO ticket, AfterSaleTicketStatusEnum... allowedStatuses) { |
| | | for (AfterSaleTicketStatusEnum status : allowedStatuses) { |
| | | if (status.getStatus().equals(ticket.getStatus())) { |
| | | return; |
| | | } |
| | | } |
| | | throw exception(TICKET_STATUS_ERROR); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.aftersales.util; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.extra.spring.SpringUtil; |
| | | import cn.iocoder.yudao.framework.common.biz.system.permission.PermissionCommonApi; |
| | | import cn.iocoder.yudao.module.aftersales.dal.dataobject.permission.AfterSalePermissionDO; |
| | | import cn.iocoder.yudao.module.aftersales.enums.AfterSaleBizTypeEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSalePermissionLevelEnum; |
| | | import cn.iocoder.yudao.module.aftersales.enums.permission.AfterSaleSceneTypeEnum; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import com.baomidou.mybatisplus.core.toolkit.support.SFunction; |
| | | import com.github.yulichang.autoconfigure.MybatisPlusJoinProperties; |
| | | import com.github.yulichang.wrapper.MPJLambdaWrapper; |
| | | import org.springframework.util.Assert; |
| | | |
| | | import java.util.List; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | |
| | | /** |
| | | * å®åæ¨¡åæ°æ®æéå·¥å
·ç±» |
| | | */ |
| | | public class AfterSalePermissionUtils { |
| | | |
| | | /** |
| | | * æ ¡éªç¨æ·æ¯å¦æ¯å®å管çå |
| | | * |
| | | * @return æ¯/å¦ |
| | | */ |
| | | public static boolean isAftersaleAdmin() { |
| | | PermissionCommonApi permissionApi = SpringUtil.getBean(PermissionCommonApi.class); |
| | | return permissionApi.hasAnyRoles(getLoginUserId(), "aftersales_admin"); |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªç¨æ·æ¯å¦ææ¥çå
¨é¨å®åæ°æ®çæé |
| | | */ |
| | | private static boolean hasViewAllPermission() { |
| | | PermissionCommonApi permissionApi = SpringUtil.getBean(PermissionCommonApi.class); |
| | | return permissionApi.hasAnyPermissions(getLoginUserId(), "aftersales:view-all"); |
| | | } |
| | | |
| | | /** |
| | | * æé å®åæ¨¡åæ°æ®ãåé¡µãæ¥è¯¢æ¡ä»¶ |
| | | * |
| | | * @param query è¿è¡¨æ¥è¯¢å¯¹è±¡ |
| | | * @param bizType æ°æ®ç±»å {@link AfterSaleBizTypeEnum} |
| | | * @param bizId æ°æ®ç¼å· |
| | | * @param userId ç¨æ·ç¼å· |
| | | * @param sceneType åºæ¯ç±»å |
| | | */ |
| | | public static <T extends MPJLambdaWrapper<?>, S> void appendPermissionCondition(T query, Integer bizType, |
| | | SFunction<S, ?> bizId, |
| | | Long userId, Integer sceneType) { |
| | | MybatisPlusJoinProperties mybatisPlusJoinProperties = SpringUtil.getBean(MybatisPlusJoinProperties.class); |
| | | final String ownerUserIdField = mybatisPlusJoinProperties.getTableAlias() + ".owner_user_id"; |
| | | // åºæ¯ä¸ï¼æè´è´£çæ°æ® |
| | | if (AfterSaleSceneTypeEnum.isOwner(sceneType)) { |
| | | query.eq(ownerUserIdField, userId); |
| | | } |
| | | // åºæ¯äºï¼æåä¸çæ°æ®ï¼ææè¯»æåæéï¼å¹¶ä¸ä¸æ¯è´è´£äººï¼ |
| | | if (AfterSaleSceneTypeEnum.isInvolved(sceneType)) { |
| | | if (isAftersaleAdmin()) { |
| | | return; |
| | | } |
| | | query.innerJoin(AfterSalePermissionDO.class, on -> on.eq(AfterSalePermissionDO::getBizType, bizType) |
| | | .eq(AfterSalePermissionDO::getBizId, bizId) |
| | | .in(AfterSalePermissionDO::getLevel, AfterSalePermissionLevelEnum.READ.getLevel(), |
| | | AfterSalePermissionLevelEnum.WRITE.getLevel()) |
| | | .eq(AfterSalePermissionDO::getUserId, userId)); |
| | | query.ne(ownerUserIdField, userId); |
| | | } |
| | | // åºæ¯ä¸ï¼ä¸å±è´è´£çæ°æ®ï¼ä¸å±æ¯è´è´£äººï¼ |
| | | if (AfterSaleSceneTypeEnum.isSubordinate(sceneType)) { |
| | | AdminUserApi adminUserApi = SpringUtil.getBean(AdminUserApi.class); |
| | | List<AdminUserRespDTO> subordinateUsers = adminUserApi.getUserListBySubordinate(userId); |
| | | if (CollUtil.isEmpty(subordinateUsers)) { |
| | | query.eq(ownerUserIdField, -1); |
| | | } else { |
| | | query.in(ownerUserIdField, convertSet(subordinateUsers, AdminUserRespDTO::getId)); |
| | | } |
| | | } |
| | | // åºæ¯åï¼å
¨é¨æ°æ®ï¼éè¦æ view-all æéæå®å管çåï¼ |
| | | if (AfterSaleSceneTypeEnum.isAll(sceneType)) { |
| | | if (isAftersaleAdmin() || hasViewAllPermission()) { |
| | | return; |
| | | } |
| | | query.eq(ownerUserIdField, userId); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long ownerUserId) { |
| | | MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>(); |
| | | // æ¼æ¥æ°æ®æéçæ¥è¯¢æ¡ä»¶ |
| | | if (Boolean.TRUE.equals(pageReqVO.getPool())) { |
| | | if (CrmSceneTypeEnum.isAll(pageReqVO.getSceneType())) { |
| | | // åºæ¯åï¼å
¨é¨æ°æ®ï¼ä¸åºåå
¬æµ·/éå
¬æµ·ï¼ç± appendPermissionCondition ç»ä¸å¤ç |
| | | CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), |
| | | CrmCustomerDO::getId, ownerUserId, pageReqVO.getSceneType()); |
| | | } else if (Boolean.TRUE.equals(pageReqVO.getPool())) { |
| | | query.isNull(CrmCustomerDO::getOwnerUserId); |
| | | } else { |
| | | CrmPermissionUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), |
| | |
| | | |
| | | OWNER(1, "æè´è´£ç"), |
| | | INVOLVED(2, "æåä¸ç"), |
| | | SUBORDINATE(3, "ä¸å±è´è´£ç"); |
| | | SUBORDINATE(3, "ä¸å±è´è´£ç"), |
| | | ALL(4, "å
¨é¨"); |
| | | |
| | | public static final Integer[] ARRAYS = Arrays.stream(values()).map(CrmSceneTypeEnum::getType).toArray(Integer[]::new); |
| | | |
| | |
| | | return ObjUtil.equal(SUBORDINATE.getType(), type); |
| | | } |
| | | |
| | | public static boolean isAll(Integer type) { |
| | | return ObjUtil.equal(ALL.getType(), type); |
| | | } |
| | | |
| | | @Override |
| | | public Integer[] array() { |
| | | return ARRAYS; |
| | |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªç¨æ·æ¯å¦ææ¥çå
¨é¨å®¢æ·çæé |
| | | * |
| | | * @return æ¯/å¦ |
| | | */ |
| | | private static boolean hasCustomerViewAllPermission() { |
| | | PermissionCommonApi permissionApi = SpringUtil.getBean(PermissionCommonApi.class); |
| | | return permissionApi.hasAnyPermissions(getLoginUserId(), "crm:customer:view-all"); |
| | | } |
| | | |
| | | /** |
| | | * æé CRM æ°æ®ç±»åæ°æ®ãåé¡µãæ¥è¯¢æ¡ä»¶ |
| | | * |
| | | * @param query è¿è¡¨æ¥è¯¢å¯¹è±¡ |
| | |
| | | query.in(ownerUserIdField, convertSet(subordinateUsers, AdminUserRespDTO::getId)); |
| | | } |
| | | } |
| | | // åºæ¯åï¼å
¨é¨æ°æ®ï¼éè¦æ view-all æéæ CRM 管çåï¼ |
| | | if (CrmSceneTypeEnum.isAll(sceneType)) { |
| | | if (isCrmAdmin() || hasCustomerViewAllPermission()) { |
| | | return; // è·³è¿è¿æ»¤ï¼æ¥çå
¨é¨ |
| | | } |
| | | // æ æéåé级为"æè´è´£ç" |
| | | query.eq(ownerUserIdField, userId); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | |
| | | private BigDecimal taxPrice; |
| | | |
| | | @Schema(description = "éæ±æ¥æ") |
| | | private LocalDateTime demandTime; |
| | | private LocalDate demandTime; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | |
| | | private BigDecimal taxPercent; |
| | | |
| | | @Schema(description = "éæ±æ¥æ") |
| | | private LocalDateTime demandTime; |
| | | private LocalDate demandTime; |
| | | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mes.api.mps.MesProMpsApi; |
| | | import cn.iocoder.yudao.module.mes.api.productsales.MesWmProductSalesLineApi; |
| | | import cn.iocoder.yudao.module.mes.api.salesnotice.MesWmSalesNoticeApi; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | |
| | | private AdminUserApi adminUserApi; |
| | | @Resource |
| | | private MesWmSalesNoticeApi salesNoticeApi; |
| | | @Resource |
| | | private MesWmProductSalesLineApi productSalesLineApi; |
| | | @Resource |
| | | private MesProMpsApi mpsApi; |
| | | @Resource |
| | |
| | | List<ErpSaleOrderItemDO> saleOrderItemList = saleOrderService.getSaleOrderItemListByOrderId(id); |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(saleOrderItemList, ErpSaleOrderItemDO::getProductId)); |
| | | Map<Long, String> batchCodeMap = productSalesLineApi.getBatchCodesBySaleOrderItemIds( |
| | | convertSet(saleOrderItemList, ErpSaleOrderItemDO::getId)); |
| | | return success(BeanUtils.toBean(saleOrder, ErpSaleOrderRespVO.class, saleOrderVO -> |
| | | saleOrderVO.setItems(BeanUtils.toBean(saleOrderItemList, ErpSaleOrderRespVO.Item.class, item -> { |
| | | // åºåä¿¡æ¯æä¸æ¥è¯¢ï¼ä»å¨ç©æµæ¨¡åï¼ |
| | | item.setStockCount(BigDecimal.ZERO); |
| | | item.setBatchCode(batchCodeMap.get(item.getId())); |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | })).setAttachmentList(storageAttachmentApi.listAttachments("erp_sale_order", id)))); |
| | |
| | | // 1.5 åè´§éç¥åä¿¡æ¯ |
| | | Map<Long, Boolean> salesNoticeMap = salesNoticeApi.checkSalesNoticeBySaleOrderIds( |
| | | convertSet(pageResult.getList(), ErpSaleOrderDO::getId)); |
| | | // 1.6 æ£æ¥æ¯å¦å¯ä»¥çæåè´§éç¥åï¼éè¦ç产çæç»å¯¹åºç MPS æ¯å¦å·²å®æï¼ |
| | | // 1.6 åºåºæ¹å· |
| | | Map<Long, String> batchCodeMap = productSalesLineApi.getBatchCodesBySaleOrderItemIds( |
| | | convertSet(saleOrderItemList, ErpSaleOrderItemDO::getId)); |
| | | // 1.7 æ£æ¥æ¯å¦å¯ä»¥çæåè´§éç¥åï¼éè¦ç产çæç»å¯¹åºç MPS æ¯å¦å·²å®æï¼ |
| | | // çéåºéè¦ç产çæç»ID |
| | | List<Long> needProductionItemIds = saleOrderItemList.stream() |
| | | .filter(item -> item.getNeedProduction() != null && item.getNeedProduction() == 1) |
| | |
| | | // 2. å¼å§æ¼æ¥ |
| | | return BeanUtils.toBean(pageResult, ErpSaleOrderRespVO.class, saleOrder -> { |
| | | saleOrder.setItems(BeanUtils.toBean(saleOrderItemMap.get(saleOrder.getId()), ErpSaleOrderRespVO.Item.class, |
| | | item -> MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())))); |
| | | item -> { |
| | | item.setBatchCode(batchCodeMap.get(item.getId())); |
| | | MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName()) |
| | | .setProductBarCode(mdmItem.getBarCode())); |
| | | })); |
| | | saleOrder.setProductNames(CollUtil.join(saleOrder.getItems(), "ï¼", ErpSaleOrderRespVO.Item::getProductName)); |
| | | MapUtils.findAndThen(customerMap, saleOrder.getCustomerId(), supplier -> saleOrder.setCustomerName(supplier.getName())); |
| | | MapUtils.findAndThen(userMap, Long.parseLong(saleOrder.getCreator()), user -> saleOrder.setCreatorName(user.getNickname())); |
| | |
| | | @Schema(description = "éå®ç¶æ", example = "2") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "åºåºç¶æ", example = "3") |
| | | private Integer outStatus; |
| | | |
| | | @Schema(description = "çäº§ç¶æ", example = "0") |
| | | private Integer productionStatus; |
| | | |
| | | @Schema(description = "æ¯å¦éè¦ç产", example = "1") |
| | | private Integer needProduction; |
| | | |
| | | @Schema(description = "å建è
") |
| | | private String creator; |
| | | |
| | |
| | | @Schema(description = "å
³èç MPS ç¼å·", example = "1024") |
| | | private Long mpsId; |
| | | |
| | | // ========== åºåºæ¹å· ========== |
| | | |
| | | @Schema(description = "åºåºæ¹å·", example = "B2026001ãB2026002") |
| | | private String batchCode; |
| | | |
| | | // ========== å
³èåæ®µ ========== |
| | | |
| | | @Schema(description = "产ååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "å·§å
å") |
| | |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalDate; |
| | | |
| | | /** |
| | | * ERP éè´ç³è¯·æç» DO |
| | |
| | | /** |
| | | * éæ±æ¥æ |
| | | */ |
| | | private LocalDateTime demandTime; |
| | | private LocalDate demandTime; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | |
| | | .eqIfPresent(ErpSaleOrderDO::getCustomerId, reqVO.getCustomerId()) |
| | | .betweenIfPresent(ErpSaleOrderDO::getOrderTime, reqVO.getOrderTime()) |
| | | .eqIfPresent(ErpSaleOrderDO::getStatus, reqVO.getStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getOutStatus, reqVO.getOutStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getProductionStatus, reqVO.getProductionStatus()) |
| | | .likeIfPresent(ErpSaleOrderDO::getRemark, reqVO.getRemark()) |
| | | .eqIfPresent(ErpSaleOrderDO::getCreator, reqVO.getCreator()) |
| | | .orderByDesc(ErpSaleOrderDO::getId); |
| | | if (reqVO.getProductId() != null) { |
| | | if (reqVO.getProductId() != null || reqVO.getNeedProduction() != null) { |
| | | query.leftJoin(ErpSaleOrderItemDO.class, ErpSaleOrderItemDO::getOrderId, ErpSaleOrderDO::getId) |
| | | .eq(reqVO.getProductId() != null, ErpSaleOrderItemDO::getProductId, reqVO.getProductId()) |
| | | .eq(reqVO.getNeedProduction() != null, ErpSaleOrderItemDO::getNeedProduction, reqVO.getNeedProduction()) |
| | | .groupBy(ErpSaleOrderDO::getId); // é¿å
1 坹夿¥è¯¢ï¼äº§çç¸åç 1 |
| | | } |
| | | return selectJoinPage(reqVO, ErpSaleOrderDO.class, query); |
| | |
| | | .eqIfPresent(ErpSaleOrderDO::getCustomerId, reqVO.getCustomerId()) |
| | | .betweenIfPresent(ErpSaleOrderDO::getOrderTime, reqVO.getOrderTime()) |
| | | .eqIfPresent(ErpSaleOrderDO::getStatus, reqVO.getStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getOutStatus, reqVO.getOutStatus()) |
| | | .eqIfPresent(ErpSaleOrderDO::getProductionStatus, reqVO.getProductionStatus()) |
| | | .likeIfPresent(ErpSaleOrderDO::getRemark, reqVO.getRemark()) |
| | | .eqIfPresent(ErpSaleOrderDO::getCreator, reqVO.getCreator()) |
| | | .orderByDesc(ErpSaleOrderDO::getId); |
| | |
| | | } |
| | | query.in(ErpSaleOrderDO::getCustomerId, permittedCustomerIds); |
| | | } |
| | | if (reqVO.getProductId() != null) { |
| | | if (reqVO.getProductId() != null || reqVO.getNeedProduction() != null) { |
| | | query.leftJoin(ErpSaleOrderItemDO.class, ErpSaleOrderItemDO::getOrderId, ErpSaleOrderDO::getId) |
| | | .eq(reqVO.getProductId() != null, ErpSaleOrderItemDO::getProductId, reqVO.getProductId()) |
| | | .eq(reqVO.getNeedProduction() != null, ErpSaleOrderItemDO::getNeedProduction, reqVO.getNeedProduction()) |
| | | .groupBy(ErpSaleOrderDO::getId); // é¿å
1 坹夿¥è¯¢ï¼äº§çç¸åç 1 |
| | | } |
| | | return selectJoinPage(reqVO, ErpSaleOrderDO.class, query); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.productsales; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * MES éå®åºåºåè¡ API æ¥å£ |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | public interface MesWmProductSalesLineApi { |
| | | |
| | | /** |
| | | * æ ¹æ®éå®è®¢åæç» ID å表æ¥è¯¢åºåºæ¹å· |
| | | * |
| | | * @param saleOrderItemIds éå®è®¢åæç» ID å表 |
| | | * @return Map<éå®è®¢åæç»ID, æ¹å·ä¸²èå符串> |
| | | */ |
| | | Map<Long, String> getBatchCodesBySaleOrderItemIds(Collection<Long> saleOrderItemIds); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.returnsales; |
| | | |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesCreateReqDTO; |
| | | |
| | | /** |
| | | * MES éå®éè´§å API æ¥å£ |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | public interface MesWmReturnSalesApi { |
| | | |
| | | /** |
| | | * å建éå®éè´§åï¼ç±å®å模åè°ç¨ï¼ |
| | | * |
| | | * @param reqDTO å建请æ±åæ° |
| | | * @return å建çéå®éè´§åç¼å· |
| | | */ |
| | | Long createReturnSales(MesWmReturnSalesCreateReqDTO reqDTO); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.returnsales.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDate; |
| | | |
| | | /** |
| | | * MES éå®éè´§åå建 Request DTO |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Schema(description = "RPC æå¡ - MES éå®éè´§åå建 Request DTO") |
| | | @Data |
| | | public class MesWmReturnSalesCreateReqDTO { |
| | | |
| | | @Schema(description = "éè´§åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "RS202603010001") |
| | | private String code; |
| | | |
| | | @Schema(description = "éè´§ååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "å®åéè´§") |
| | | private String name; |
| | | |
| | | @Schema(description = "éå®è®¢å ID", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·", example = "SO202603010001") |
| | | private String salesOrderCode; |
| | | |
| | | @Schema(description = "å®¢æ· ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long clientId; |
| | | |
| | | @Schema(description = "éè´§æ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private LocalDate returnDate; |
| | | |
| | | @Schema(description = "éè´§åå ", requiredMode = Schema.RequiredMode.REQUIRED, example = "è´¨éé®é¢") |
| | | private String returnReason; |
| | | |
| | | @Schema(description = "夿³¨", example = "å®åéè´§ç³è¯·å
³è") |
| | | private String remark; |
| | | |
| | | @Schema(description = "å®åéè´§ç³è¯·ç¼å·ï¼å
³è after_sale_return.idï¼", example = "1") |
| | | private Long afterSaleReturnId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.productsales; |
| | | |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * MES éå®åºåºåè¡ API å®ç°ç±» |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class MesWmProductSalesLineApiImpl implements MesWmProductSalesLineApi { |
| | | |
| | | @Resource |
| | | private MesWmProductSalesLineMapper productSalesLineMapper; |
| | | |
| | | @Override |
| | | public Map<Long, String> getBatchCodesBySaleOrderItemIds(Collection<Long> saleOrderItemIds) { |
| | | return productSalesLineMapper.selectBatchCodesBySaleOrderItemIds(saleOrderItemIds); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.api.returnsales; |
| | | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.api.returnsales.dto.MesWmReturnSalesCreateReqDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.MesWmReturnSalesSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * MES éå®éè´§å API å®ç°ç±» |
| | | * |
| | | * @author èéæºç |
| | | */ |
| | | @Service |
| | | public class MesWmReturnSalesApiImpl implements MesWmReturnSalesApi { |
| | | |
| | | @Resource |
| | | private MesWmReturnSalesService returnSalesService; |
| | | |
| | | @Override |
| | | public Long createReturnSales(MesWmReturnSalesCreateReqDTO reqDTO) { |
| | | MesWmReturnSalesSaveReqVO createReqVO = BeanUtils.toBean(reqDTO, MesWmReturnSalesSaveReqVO.class); |
| | | return returnSalesService.createReturnSales(createReqVO); |
| | | } |
| | | |
| | | } |
| | |
| | | private MesDvMachineryTypeService machineryTypeService; |
| | | @Resource |
| | | private MesMdWorkshopService workshopService; |
| | | @Resource |
| | | private cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService workstationService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建设å¤") |
| | |
| | | if (CollUtil.isEmpty(list)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // 1. æ¹éè·å设å¤ç±»åå车é´ä¿¡æ¯ |
| | | // 1. æ¹éè·å设å¤ç±»åã车é´åå·¥ä½ç«ä¿¡æ¯ |
| | | Map<Long, MesDvMachineryTypeDO> machineryTypeMap = machineryTypeService.getMachineryTypeMap( |
| | | convertSet(list, MesDvMachineryDO::getMachineryTypeId)); |
| | | Map<Long, MesMdWorkshopDO> workshopMap = workshopService.getWorkshopMap( |
| | | convertSet(list, MesDvMachineryDO::getWorkshopId)); |
| | | Map<Long, cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO> workstationMap = |
| | | workstationService.getWorkstationMap(convertSet(list, MesDvMachineryDO::getWorkstationId)); |
| | | // 2. æ¼æ¥ VO |
| | | return BeanUtils.toBean(list, MesDvMachineryRespVO.class, vo -> { |
| | | MapUtils.findAndThen(machineryTypeMap, vo.getMachineryTypeId(), |
| | | machineryType -> vo.setMachineryTypeName(machineryType.getName())); |
| | | MapUtils.findAndThen(workshopMap, vo.getWorkshopId(), |
| | | workshop -> vo.setWorkshopName(workshop.getName())); |
| | | MapUtils.findAndThen(workstationMap, vo.getWorkstationId(), |
| | | workstation -> vo.setWorkstationName(workstation.getName())); |
| | | }); |
| | | } |
| | | |
| | |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | @ExcelProperty("ç产æç(æ¯å°æ¶)") |
| | | private java.math.BigDecimal productionEfficiency; |
| | | |
| | | @ExcelProperty("ä¼ é履带") |
| | | private Integer conveyorBelt; |
| | | |
| | | @ExcelProperty("å·¥ä½ç«ç¼ç ") |
| | | private String workstationCode; |
| | | |
| | | } |
| | |
| | | @Schema(description = "设å¤ç¶æ", example = "1") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å·¥ä½ç«ç¼å·", example = "300") |
| | | private Long workstationId; |
| | | |
| | | } |
| | |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "ç产æçï¼æ¯å°æ¶ï¼", example = "10.5") |
| | | @ExcelProperty("ç产æç(æ¯å°æ¶)") |
| | | private java.math.BigDecimal productionEfficiency; |
| | | |
| | | @Schema(description = "ä¼ é履带ï¼2=ååæçï¼", example = "2") |
| | | @ExcelProperty("ä¼ é履带") |
| | | private Integer conveyorBelt; |
| | | |
| | | @Schema(description = "å·¥ä½ç«ç¼å·", example = "300") |
| | | private Long workstationId; |
| | | |
| | | @Schema(description = "å·¥ä½ç«åç§°", example = "ä¸å·å·¥ä½ç«") |
| | | @ExcelProperty("å·¥ä½ç«") |
| | | private String workstationName; |
| | | |
| | | @Schema(description = "å建æ¶é´", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "ç产æçï¼æ¯å°æ¶ï¼", example = "10.5") |
| | | private java.math.BigDecimal productionEfficiency; |
| | | |
| | | @Schema(description = "ä¼ é履带ï¼2=ååæçï¼", example = "2") |
| | | private Integer conveyorBelt; |
| | | |
| | | @Schema(description = "å·¥ä½ç«ç¼å·", example = "300") |
| | | private Long workstationId; |
| | | |
| | | } |
| | |
| | | @Schema(description = "å®¡æ ¸ç¶æ", example = "0") |
| | | private Integer auditStatus; |
| | | |
| | | @Schema(description = "项ç®ID", example = "1") |
| | | private Long projectId; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/calculate-duration") |
| | | @Operation(summary = "计ç®ç产æ¶é¿", description = "æ ¹æ®å·¥ä½ç«ç»å®è®¾å¤çç产æçåä¼ é履带ï¼èªå¨è®¡ç®ç产æ¶é¿ï¼å°æ¶ï¼") |
| | | @Parameters({ |
| | | @Parameter(name = "workstationId", description = "å·¥ä½ç«ç¼å·", required = true), |
| | | @Parameter(name = "quantity", description = "æäº§æ°é", required = true) |
| | | }) |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-task:query')") |
| | | public CommonResult<java.util.Map<String, Object>> calculateDuration( |
| | | @RequestParam("workstationId") Long workstationId, |
| | | @RequestParam("quantity") BigDecimal quantity) { |
| | | Integer duration = taskService.calculateDuration(workstationId, quantity); |
| | | return success(java.util.Map.of("duration", duration)); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤ç产任å¡") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | |
| | | import lombok.EqualsAndHashCode; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalDate; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| | | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; |
| | | |
| | | /** |
| | | * 管çåå° - MES éå®éè´§ç¸å
³ |
| | |
| | | @Schema(description = "éè´§ååç§°", example = "éå®éè´§") |
| | | private String name; |
| | | |
| | | @Schema(description = "éå®è®¢å ID", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·", example = "SO202603010001") |
| | | private String salesOrderCode; |
| | | |
| | |
| | | private Integer status; |
| | | |
| | | @Schema(description = "éè´§æ¥æ") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] returnDate; |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) |
| | | private LocalDate[] returnDate; |
| | | |
| | | } |
| | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | |
| | | @Schema(description = "éè´§ååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "éå®éè´§") |
| | | private String name; |
| | | |
| | | @Schema(description = "éå®è®¢å ID", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·", example = "SO202603010001") |
| | | private String salesOrderCode; |
| | | |
| | |
| | | private String clientName; |
| | | |
| | | @Schema(description = "éè´§æ¥æ") |
| | | private LocalDateTime returnDate; |
| | | private LocalDate returnDate; |
| | | |
| | | @Schema(description = "éè´§åå ", example = "è´¨éé®é¢") |
| | | private String returnReason; |
| | |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalDate; |
| | | |
| | | /** |
| | | * 管çåå° - MES éå®éè´§åæ°å¢/ä¿®æ¹ Request VO |
| | |
| | | @NotBlank(message = "éè´§ååç§°ä¸è½ä¸ºç©º") |
| | | private String name; |
| | | |
| | | @Schema(description = "éå®è®¢å ID", example = "1") |
| | | private Long saleOrderId; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·", example = "SO202603010001") |
| | | private String salesOrderCode; |
| | | |
| | |
| | | |
| | | @Schema(description = "éè´§æ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "éè´§æ¥æä¸è½ä¸ºç©º") |
| | | private LocalDateTime returnDate; |
| | | private LocalDate returnDate; |
| | | |
| | | @Schema(description = "éè´§åå ", requiredMode = Schema.RequiredMode.REQUIRED, example = "è´¨éé®é¢") |
| | | @NotBlank(message = "éè´§åå ä¸è½ä¸ºç©º") |
| | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES ä¾åºåéè´§å Response VO") |
| | |
| | | private String vendorNickname; |
| | | |
| | | @Schema(description = "éè´§æ¥æ") |
| | | private LocalDateTime returnDate; |
| | | private LocalDate returnDate; |
| | | |
| | | @Schema(description = "éè´§åå ", example = "è´¨éä¸åæ ¼") |
| | | private String returnReason; |
| | |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalDate; |
| | | |
| | | @Schema(description = "管çåå° - MES ä¾åºåéè´§åæ°å¢/ä¿®æ¹ Request VO") |
| | | @Data |
| | |
| | | |
| | | @Schema(description = "éè´§æ¥æ", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | @NotNull(message = "éè´§æ¥æä¸è½ä¸ºç©º") |
| | | private LocalDateTime returnDate; |
| | | private LocalDate returnDate; |
| | | |
| | | @Schema(description = "éè´§åå ", example = "è´¨éä¸åæ ¼") |
| | | private String returnReason; |
| | |
| | | * 夿³¨ |
| | | */ |
| | | private String remark; |
| | | /** |
| | | * ç产æçï¼æ¯å°æ¶ï¼ |
| | | */ |
| | | private java.math.BigDecimal productionEfficiency; |
| | | /** |
| | | * ä¼ é履带ï¼2=ååæçï¼ |
| | | */ |
| | | private Integer conveyorBelt; |
| | | /** |
| | | * å·¥ä½ç«ç¼å· |
| | | * |
| | | * å
³è {@link cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO#getId()} |
| | | */ |
| | | private Long workstationId; |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalDate; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | |
| | | /** |
| | |
| | | */ |
| | | private String name; |
| | | /** |
| | | * éå®è®¢å ID |
| | | */ |
| | | private Long saleOrderId; |
| | | /** |
| | | * éå®è®¢åç¼å· |
| | | */ |
| | | private String salesOrderCode; |
| | |
| | | /** |
| | | * éè´§æ¥æ |
| | | */ |
| | | private LocalDateTime returnDate; |
| | | private LocalDate returnDate; |
| | | /** |
| | | * éè´§åå |
| | | */ |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalDate; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * éè´§æ¥æ |
| | | */ |
| | | private LocalDateTime returnDate; |
| | | private LocalDate returnDate; |
| | | /** |
| | | * éè´§åå |
| | | */ |
| | |
| | | .eqIfPresent(MesDvMachineryDO::getMachineryTypeId, reqVO.getMachineryTypeId()) |
| | | .inIfPresent(MesDvMachineryDO::getMachineryTypeId, reqVO.getMachineryTypeIds()) |
| | | .eqIfPresent(MesDvMachineryDO::getWorkshopId, reqVO.getWorkshopId()) |
| | | .eqIfPresent(MesDvMachineryDO::getWorkstationId, reqVO.getWorkstationId()) |
| | | .eqIfPresent(MesDvMachineryDO::getStatus, reqVO.getStatus()) |
| | | .orderByDesc(MesDvMachineryDO::getId)); |
| | | } |
| | |
| | | .orderByDesc(MesPdDocumentAuditDO::getId)); |
| | | } |
| | | |
| | | default PageResult<MesPdDocumentAuditDO> selectPage(MesPdDocumentAuditPageReqVO reqVO, |
| | | Collection<Long> documentIds) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesPdDocumentAuditDO>() |
| | | .eqIfPresent(MesPdDocumentAuditDO::getDocumentId, reqVO.getDocumentId()) |
| | | .likeIfPresent(MesPdDocumentAuditDO::getAuditNo, reqVO.getAuditNo()) |
| | | .eqIfPresent(MesPdDocumentAuditDO::getAuditStatus, reqVO.getAuditStatus()) |
| | | .inIfPresent(MesPdDocumentAuditDO::getDocumentId, documentIds) |
| | | .orderByDesc(MesPdDocumentAuditDO::getId)); |
| | | } |
| | | |
| | | default List<MesPdDocumentAuditDO> selectListByDocumentId(Long documentId) { |
| | | return selectList(MesPdDocumentAuditDO::getDocumentId, documentId); |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * MES éå®åºåºåè¡ Mapper |
| | |
| | | .orderByDesc(MesWmProductSalesLineDO::getId)); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®éå®è®¢åæç» ID å表æ¥è¯¢åºåºè¡ï¼æ saleOrderItemId åç»è¿åæ¹å· |
| | | */ |
| | | default Map<Long, String> selectBatchCodesBySaleOrderItemIds(java.util.Collection<Long> saleOrderItemIds) { |
| | | if (saleOrderItemIds == null || saleOrderItemIds.isEmpty()) { |
| | | return java.util.Collections.emptyMap(); |
| | | } |
| | | List<MesWmProductSalesLineDO> lines = selectList(new LambdaQueryWrapperX<MesWmProductSalesLineDO>() |
| | | .in(MesWmProductSalesLineDO::getSaleOrderItemId, saleOrderItemIds)); |
| | | return lines.stream() |
| | | .filter(l -> l.getBatchCode() != null && !l.getBatchCode().isEmpty()) |
| | | .collect(java.util.stream.Collectors.groupingBy( |
| | | MesWmProductSalesLineDO::getSaleOrderItemId, |
| | | java.util.LinkedHashMap::new, |
| | | java.util.stream.Collectors.collectingAndThen( |
| | | java.util.stream.Collectors.mapping(MesWmProductSalesLineDO::getBatchCode, |
| | | java.util.stream.Collectors.toSet()), |
| | | codes -> String.join("ã", codes)))); |
| | | } |
| | | |
| | | default void updateQualityStatusByIds(List<Long> ids, Integer qualityStatus) { |
| | | update(new MesWmProductSalesLineDO().setQualityStatus(qualityStatus), |
| | | new LambdaUpdateWrapper<MesWmProductSalesLineDO>().in(MesWmProductSalesLineDO::getId, ids)); |
| | |
| | | ErrorCode DV_MACHINERY_HAS_CHECK_RECORD = new ErrorCode(1_040_301_004, "设å¤å·²å
³èç¹æ£è®°å½ï¼æ æ³å é¤"); |
| | | ErrorCode DV_MACHINERY_HAS_MAINTEN_RECORD = new ErrorCode(1_040_301_005, "设å¤å·²å
³èä¿å
»è®°å½ï¼æ æ³å é¤"); |
| | | ErrorCode DV_MACHINERY_HAS_REPAIR = new ErrorCode(1_040_301_006, "设å¤å·²å
³è维修工åï¼æ æ³å é¤"); |
| | | ErrorCode DV_MACHINERY_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_301_008, "å·¥ä½ç«ç¼ç ä¸åå¨"); |
| | | |
| | | // ========== MES 设å¤ç®¡ç-ç¹æ£ä¿å
»é¡¹ç®ï¼1-040-304-000ï¼ ========== |
| | | ErrorCode DV_SUBJECT_NOT_EXISTS = new ErrorCode(1_040_304_000, "ç¹æ£ä¿å
»é¡¹ç®ä¸åå¨"); |
| | |
| | | @Lazy |
| | | private MesMdWorkshopService workshopService; |
| | | @Resource |
| | | @Lazy |
| | | private cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService workstationService; |
| | | @Resource |
| | | private MesWmBarcodeService barcodeService; |
| | | @Resource |
| | | @Lazy |
| | |
| | | throw exception(DV_MACHINERY_IMPORT_LIST_IS_EMPTY); |
| | | } |
| | | |
| | | // 2. æ¹éå 载设å¤ç±»åå车é´ï¼æå»ºç¼ç å°å®ä½çæ å° |
| | | // 2. æ¹éå 载设å¤ç±»åã车é´åå·¥ä½ç«ï¼æå»ºç¼ç å°å®ä½çæ å° |
| | | List<MesDvMachineryTypeDO> allTypes = machineryTypeService.getMachineryTypeList( |
| | | new cn.iocoder.yudao.module.mes.controller.admin.dv.machinery.vo.type.MesDvMachineryTypeListReqVO()); |
| | | Map<String, MesDvMachineryTypeDO> typeCodeMap = allTypes.stream() |
| | |
| | | cn.iocoder.yudao.framework.common.enums.CommonStatusEnum.ENABLE.getStatus()); |
| | | Map<String, MesMdWorkshopDO> workshopCodeMap = allWorkshops.stream() |
| | | .collect(Collectors.toMap(MesMdWorkshopDO::getCode, w -> w, (a, b) -> a)); |
| | | List<cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO> allWorkstations = |
| | | workstationService.getWorkstationListByStatus( |
| | | cn.iocoder.yudao.framework.common.enums.CommonStatusEnum.ENABLE.getStatus()); |
| | | Map<String, cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO> workstationCodeMap = |
| | | allWorkstations.stream().collect(Collectors.toMap( |
| | | cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO::getCode, |
| | | w -> w, (a, b) -> a)); |
| | | |
| | | // 3. éåï¼é个å建 or æ´æ° |
| | | MesDvMachineryImportRespVO respVO = MesDvMachineryImportRespVO.builder() |
| | |
| | | return; |
| | | } |
| | | |
| | | // 3.4 夿ï¼å建 or æ´æ° |
| | | // 3.4 æ ¡éªå·¥ä½ç«ç¼ç ï¼å¯éï¼ |
| | | Long workstationId = null; |
| | | if (StrUtil.isNotBlank(importItem.getWorkstationCode())) { |
| | | cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO workstation = |
| | | workstationCodeMap.get(importItem.getWorkstationCode()); |
| | | if (workstation == null) { |
| | | respVO.getFailureCodes().put(key, "å·¥ä½ç«ç¼ç [" + importItem.getWorkstationCode() + "]ä¸åå¨"); |
| | | return; |
| | | } |
| | | workstationId = workstation.getId(); |
| | | } |
| | | |
| | | // 3.5 夿ï¼å建 or æ´æ° |
| | | MesDvMachineryDO existMachinery = machineryMapper.selectByCode(importItem.getCode()); |
| | | if (existMachinery == null) { |
| | | // 3.4.1 å建 |
| | | // 3.5.1 å建 |
| | | MesDvMachineryDO machinery = BeanUtils.toBean(importItem, MesDvMachineryDO.class); |
| | | machinery.setMachineryTypeId(machineryType.getId()); |
| | | machinery.setWorkshopId(workshop.getId()); |
| | | machinery.setWorkstationId(workstationId); |
| | | machineryMapper.insert(machinery); |
| | | // èªå¨çææ¡ç |
| | | barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.MACHINERY.getValue(), |
| | | machinery.getId(), machinery.getCode(), machinery.getName()); |
| | | respVO.getCreateCodes().add(importItem.getCode()); |
| | | } else if (updateSupport) { |
| | | // 3.4.2 æ´æ° |
| | | // 3.5.2 æ´æ° |
| | | MesDvMachineryDO updateObj = BeanUtils.toBean(importItem, MesDvMachineryDO.class); |
| | | updateObj.setId(existMachinery.getId()); |
| | | updateObj.setMachineryTypeId(machineryType.getId()); |
| | | updateObj.setWorkshopId(workshop.getId()); |
| | | updateObj.setWorkstationId(workstationId); |
| | | machineryMapper.updateById(updateObj); |
| | | respVO.getUpdateCodes().add(importItem.getCode()); |
| | | } else { |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pd.documentaudit.vo.MesPdDocumentAuditPageReqVO; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pd.documentaudit.vo.MesPdDocumentAuditSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pd.documentaudit.MesPdDocumentAuditDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pd.documentaudit.MesPdDocumentAuditMapper; |
| | | import cn.iocoder.yudao.module.mes.service.pd.document.MesPdDocumentService; |
| | |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PD_DOCUMENT_AUDIT_NOT_EXISTS; |
| | |
| | | |
| | | @Override |
| | | public PageResult<MesPdDocumentAuditDO> getDocumentAuditPage(MesPdDocumentAuditPageReqVO pageReqVO) { |
| | | // æé¡¹ç®çéï¼å
æ¥åºé¡¹ç®ä¸ææèµæï¼åæèµæ ID è¿æ»¤å®¡æ ¸è®°å½ |
| | | if (pageReqVO.getProjectId() != null) { |
| | | List<MesPdDocumentDO> documents = documentService.getDocumentListByProjectId( |
| | | pageReqVO.getProjectId()); |
| | | if (CollUtil.isEmpty(documents)) { |
| | | return PageResult.empty(); |
| | | } |
| | | List<Long> documentIds = documents.stream() |
| | | .map(MesPdDocumentDO::getId).collect(Collectors.toList()); |
| | | return documentAuditMapper.selectPage(pageReqVO, documentIds); |
| | | } |
| | | return documentAuditMapper.selectPage(pageReqVO); |
| | | } |
| | | |
| | |
| | | void cancelTaskByOrderId(Long workOrderId); |
| | | |
| | | /** |
| | | * æ ¹æ®å·¥ä½ç«ç»å®è®¾å¤çç产æçåä¼ é履带ï¼è®¡ç®ç产æ¶é¿ï¼åä½ï¼å°æ¶ï¼ |
| | | * |
| | | * @param workstationId å·¥ä½ç«ç¼å· |
| | | * @param quantity æäº§æ°é |
| | | * @return ç产æ¶é¿ï¼å°æ¶ï¼ï¼æ 设å¤åè¿å 0 |
| | | */ |
| | | Integer calculateDuration(Long workstationId, BigDecimal quantity); |
| | | |
| | | /** |
| | | * ç´¯å ä»»å¡çå·²ç产ãåæ ¼ãä¸åæ ¼æ°é |
| | | * |
| | | * @param id ä»»å¡ç¼å· |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskAutoGenerateReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.dv.machinery.MesDvMachineryDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationMachineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProTaskStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.dv.machinery.MesDvMachineryService; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| | | import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; |
| | | import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationMachineService; |
| | | import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_ALREADY_FINISHED; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_HAS_FEEDBACK; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.PRO_TASK_NOT_EXISTS; |
| | |
| | | private MesProWorkOrderProcessService workOrderProcessService; |
| | | @Resource |
| | | private MesMdAutoCodeRecordService autoCodeRecordService; |
| | | @Resource |
| | | private MesMdWorkstationMachineService workstationMachineService; |
| | | @Resource |
| | | @Lazy |
| | | private MesDvMachineryService machineryService; |
| | | |
| | | @Override |
| | | public Long createTask(MesProTaskSaveReqVO createReqVO) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public Integer calculateDuration(Long workstationId, BigDecimal quantity) { |
| | | if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return 0; |
| | | } |
| | | // 1. æ¥è¯¢å·¥ä½ç«ç»å®çè®¾å¤ |
| | | List<MesMdWorkstationMachineDO> machines = workstationMachineService |
| | | .getWorkstationMachineListByWorkstationId(workstationId); |
| | | if (CollUtil.isEmpty(machines)) { |
| | | return 0; |
| | | } |
| | | // 2. è·å设å¤è¯¦æ
ï¼è®¡ç®æ»æç |
| | | Set<Long> machineryIds = convertSet(machines, MesMdWorkstationMachineDO::getMachineryId); |
| | | List<MesDvMachineryDO> machineryList = machineryService.getMachineryList(machineryIds); |
| | | BigDecimal totalEfficiency = BigDecimal.ZERO; |
| | | for (MesDvMachineryDO m : machineryList) { |
| | | BigDecimal efficiency = m.getProductionEfficiency() != null ? m.getProductionEfficiency() : BigDecimal.ZERO; |
| | | Integer belt = m.getConveyorBelt() != null && m.getConveyorBelt() > 0 ? m.getConveyorBelt() : 1; |
| | | totalEfficiency = totalEfficiency.add(efficiency.multiply(BigDecimal.valueOf(belt))); |
| | | } |
| | | if (totalEfficiency.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return 0; |
| | | } |
| | | // 3. ç产æ¶é¿ï¼å°æ¶ï¼ = ceil(æäº§æ°é / æ»æç)ï¼æçåä½ä¸ºæ¯å°æ¶äº§é |
| | | return quantity.divide(totalEfficiency, 0, java.math.RoundingMode.CEILING).intValue(); |
| | | } |
| | | |
| | | @Override |
| | | public MesProTaskAutoGeneratePreviewRespVO previewAutoGenerate(MesProTaskAutoGenerateReqVO reqVO) { |
| | | // 1. æ ¡éªå·¥å已确认 |
| | | MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId()); |
| | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.*; |
| | | import cn.iocoder.yudao.module.srm.dal.dataobject.SrmBidAwardDO; |
| | | import cn.iocoder.yudao.module.srm.service.tender.SrmBidAwardService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | |
| | | @Operation(summary = "æ ¹æ®ææ 项ç®IDè·å宿 详æ
") |
| | | @PreAuthorize("@ss.hasPermission('srm:bid-award:query')") |
| | | public CommonResult<SrmBidAwardRespVO> getAwardByProject(@RequestParam("tenderProjectId") Long tenderProjectId) { |
| | | return success(BeanUtils.toBean(bidAwardService.getAwardByProjectId(tenderProjectId), SrmBidAwardRespVO.class)); |
| | | SrmBidAwardDO award = bidAwardService.getAwardByProjectId(tenderProjectId); |
| | | if (award == null) { |
| | | return success((SrmBidAwardRespVO) null); |
| | | } |
| | | return success(BeanUtils.toBean(award, SrmBidAwardRespVO.class)); |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤å®æ ") |
| | | @Parameter(name = "id", description = "宿 ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('srm:bid-award:update')") |
| | | public CommonResult<Boolean> deleteAward(@RequestParam("id") Long id) { |
| | | bidAwardService.deleteAward(id); |
| | | return success(true); |
| | | } |
| | | |
| | | @PutMapping("/approve") |
| | |
| | | return success(bidEvaluationService.createEvaluation(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°è¯æ è®°å½") |
| | | @PreAuthorize("@ss.hasPermission('srm:bid-evaluation:update')") |
| | | public CommonResult<Boolean> updateEvaluation(@Valid @RequestBody SrmBidEvaluationSaveReqVO updateReqVO) { |
| | | bidEvaluationService.updateEvaluation(updateReqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/list-by-project") |
| | | @Operation(summary = "æææ 项ç®è·åè¯æ å表") |
| | | @PreAuthorize("@ss.hasPermission('srm:bid-evaluation:query')") |
| | |
| | | if (material != null) { |
| | | vo.setTenderMaterialCode(material.getProductCode()); |
| | | vo.setTenderMaterialName(material.getProductName()); |
| | | vo.setMaterialName(material.getProductName()); |
| | | vo.setTenderMaterialSpec(material.getProductSpec()); |
| | | vo.setTenderMaterialUnit(material.getUnit()); |
| | | } |
| | |
| | | @Schema(description = "ç©æåç§°") |
| | | private String tenderMaterialName; |
| | | |
| | | @Schema(description = "ç©æåç§°ï¼ä¸å端 materialName 对åºï¼") |
| | | private String materialName; |
| | | |
| | | @Schema(description = "ç©æè§æ ¼") |
| | | private String tenderMaterialSpec; |
| | | |
| | |
| | | .eq(SrmTenderBidDO::getSupplierId, supplierId)); |
| | | } |
| | | |
| | | default boolean existsByBidNo(String bidNo) { |
| | | return exists(new LambdaQueryWrapperX<SrmTenderBidDO>() |
| | | .eq(SrmTenderBidDO::getBidNo, bidNo)); |
| | | } |
| | | |
| | | } |
| | |
| | | ErrorCode TENDER_STATUS_ALREADY_CLOSED = new ErrorCode(1_040_500_010, "å·²å
³éç项ç®ä¸å
许æä½"); |
| | | ErrorCode BID_NOT_EXISTS = new ErrorCode(1_040_500_003, "ææ è®°å½ä¸åå¨"); |
| | | ErrorCode BID_SUPPLIER_EXISTS = new ErrorCode(1_040_500_004, "ä¾åºåå·²å䏿æ "); |
| | | ErrorCode BID_NO_EXISTS = new ErrorCode(1_040_500_016, "ææ ç¼å·å·²åå¨"); |
| | | ErrorCode BID_PAST_END_TIME = new ErrorCode(1_040_500_005, "ææ å·²æªæ¢"); |
| | | ErrorCode BID_SUPPLIER_NOT_APPROVED = new ErrorCode(1_040_500_011, "ä¾åºåæªéè¿åå
¥å®¡æ¹ï¼æ æ³å䏿æ "); |
| | | ErrorCode BID_WITHDRAWN_CANNOT_QUOTE = new ErrorCode(1_040_500_012, "ææ å·²æ¤æ ï¼ä¸å
许æ¥ä»·"); |
| | |
| | | |
| | | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | |
| | | SrmBidAwardDO getAwardByProjectId(Long tenderProjectId); |
| | | |
| | | /** |
| | | * å é¤å®æ |
| | | */ |
| | | void deleteAward(Long id); |
| | | |
| | | /** |
| | | * 审æ¹å®æ |
| | | */ |
| | | void approveAward(Long id); |
| | |
| | | import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants; |
| | | import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class SrmBidAwardServiceImpl implements SrmBidAwardService { |
| | | |
| | | @Resource |
| | |
| | | @Override |
| | | public SrmBidAwardDO getAwardByProjectId(Long tenderProjectId) { |
| | | return bidAwardMapper.selectByTenderProjectId(tenderProjectId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void deleteAward(Long id) { |
| | | SrmBidAwardDO award = validateAwardExists(id); |
| | | bidAwardMapper.deleteById(id); |
| | | } |
| | | |
| | | @Override |
| | |
| | | ErpPurchaseOrderCreateReqDTO createReq = new ErpPurchaseOrderCreateReqDTO(); |
| | | createReq.setSupplierId(srmSupplier.getId()); |
| | | createReq.setOrderTime(LocalDateTime.now()); |
| | | createReq.setDepositPrice(BigDecimal.ZERO); |
| | | createReq.setItems(orderItems); |
| | | createReq.setRemark("SRM 宿 èªå¨çæ, 宿 ç¼å·: " + award.getAwardNo()); |
| | | |
| | | Long purchaseOrderId = erpPurchaseOrderApi.createPurchaseOrder(createReq).getCheckedData(); |
| | | |
| | | // è·åéè´è®¢åå· |
| | | String purchaseOrderNo = null; |
| | | try { |
| | | purchaseOrderNo = erpPurchaseOrderApi.getPurchaseOrder(purchaseOrderId) |
| | | .getCheckedData().getNo(); |
| | | } catch (Exception e) { |
| | | log.warn("[generatePurchaseOrder] è·åéè´è®¢åå·å¤±è´¥ï¼purchaseOrderId={}", purchaseOrderId, e); |
| | | } |
| | | |
| | | // 8. æ´æ°å®æ è®°å½ |
| | | award.setPurchaseOrderId(purchaseOrderId); |
| | | award.setPurchaseOrderNo(purchaseOrderNo); |
| | | award.setAwardStatus(AwardStatusEnum.ORDER_GENERATED.getCode()); |
| | | bidAwardMapper.updateById(award); |
| | | |
| | | // 9. æ´æ°ææ 项ç®ç¶æ |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId()); |
| | | if (project != null) { |
| | | project.setTenderStatus(TenderStatusEnum.CLOSED.getCode()); |
| | | tenderProjectMapper.updateById(project); |
| | | } |
| | | } |
| | | |
| | | private SrmBidAwardDO validateAwardExists(Long id) { |
| | |
| | | Long createEvaluation(@Valid SrmBidEvaluationSaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * æ´æ°è¯æ è®°å½ |
| | | */ |
| | | void updateEvaluation(@Valid SrmBidEvaluationSaveReqVO updateReqVO); |
| | | |
| | | /** |
| | | * è·åè¯æ åè¡¨ï¼æææ é¡¹ç®ï¼ |
| | | */ |
| | | List<SrmBidEvaluationDO> getEvaluationList(Long tenderProjectId); |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createEvaluation(SrmBidEvaluationSaveReqVO createReqVO) { |
| | | SrmBidEvaluationDO evaluation = BeanUtils.toBean(createReqVO, SrmBidEvaluationDO.class); |
| | | // 强å¶ç½®ç©º idï¼é¿å
åç«¯ä¼ å
¥å·²æ id 导è´ä¸»é®å²çªï¼ç±æ°æ®åºåºåèªå¨çæ |
| | | evaluation.setId(null); |
| | | // 计ç®ç»¼åè¯å: ä»·æ ¼*0.4 + ææ¯*0.3 + 交ä»*0.2 + æå¡*0.1 |
| | | BigDecimal price = nvl(evaluation.getPriceScore()); |
| | | BigDecimal tech = nvl(evaluation.getTechScore()); |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateEvaluation(SrmBidEvaluationSaveReqVO updateReqVO) { |
| | | SrmBidEvaluationDO existing = bidEvaluationMapper.selectById(updateReqVO.getId()); |
| | | if (existing == null) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.EVALUATION_NOT_EXISTS_TENDER); |
| | | } |
| | | SrmBidEvaluationDO evaluation = BeanUtils.toBean(updateReqVO, SrmBidEvaluationDO.class); |
| | | BigDecimal price = nvl(evaluation.getPriceScore()); |
| | | BigDecimal tech = nvl(evaluation.getTechScore()); |
| | | BigDecimal delivery = nvl(evaluation.getDeliveryScore()); |
| | | BigDecimal service = nvl(evaluation.getServiceScore()); |
| | | BigDecimal composite = price.multiply(new BigDecimal("0.4")) |
| | | .add(tech.multiply(new BigDecimal("0.3"))) |
| | | .add(delivery.multiply(new BigDecimal("0.2"))) |
| | | .add(service.multiply(new BigDecimal("0.1"))) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | evaluation.setCompositeScore(composite); |
| | | evaluation.setEvaluationTime(LocalDateTime.now()); |
| | | bidEvaluationMapper.updateById(evaluation); |
| | | } |
| | | |
| | | @Override |
| | | public List<SrmBidEvaluationDO> getEvaluationList(Long tenderProjectId) { |
| | | return bidEvaluationMapper.selectListByTenderProjectId(tenderProjectId); |
| | | } |
| | |
| | | if (!supplierApplyMapper.existsApprovedBySupplierId(createReqVO.getSupplierId())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.BID_SUPPLIER_NOT_APPROVED); |
| | | } |
| | | // æ ¡éªææ ç¼å·æ¯å¦éå¤ |
| | | if (tenderBidMapper.existsByBidNo(createReqVO.getBidNo())) { |
| | | throw ServiceExceptionUtil.exception(ErrorCodeConstants.BID_NO_EXISTS); |
| | | } |
| | | // æ ¡éªä¾åºåæ¯å¦å·²å䏿æ |
| | | SrmTenderBidDO existing = tenderBidMapper.selectByTenderAndSupplier(createReqVO.getTenderProjectId(), createReqVO.getSupplierId()); |
| | | if (existing != null) { |
| | |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmBidAwardMapper; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderMaterialMapper; |
| | | import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderProjectMapper; |
| | | import cn.iocoder.yudao.module.srm.enums.AwardStatusEnum; |
| | | import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants; |
| | | import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; |
| | |
| | | |
| | | @Override |
| | | public SrmTenderProjectDO getTenderProject(Long id) { |
| | | return tenderProjectMapper.selectById(id); |
| | | SrmTenderProjectDO project = tenderProjectMapper.selectById(id); |
| | | if (project != null) { |
| | | SrmBidAwardDO award = bidAwardMapper.selectByTenderProjectId(id); |
| | | if (award != null) { |
| | | project.setAwardId(award.getId()); |
| | | project.setPurchaseOrderNo(award.getPurchaseOrderNo()); |
| | | } |
| | | } |
| | | return project; |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (award != null) { |
| | | project.setAwardId(award.getId()); |
| | | project.setPurchaseOrderNo(award.getPurchaseOrderNo()); |
| | | // é²å¾¡ï¼å¦æå®æ å·²çæè®¢åä½é¡¹ç®ç¶ææªæ´æ°ï¼åæ¥ç¶æ |
| | | if (AwardStatusEnum.ORDER_GENERATED.getCode().equals(award.getAwardStatus())) { |
| | | project.setTenderStatus(TenderStatusEnum.CLOSED.getCode()); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | |
| | | HRM_RESIGNATION_APPLICATION("hrm_resignation_application", "HRM 离èç³è¯·"), |
| | | HRM_ATTENDANCE_EXCEPTION("hrm_attendance_exception", "HRM èå¤å¼å¸¸"), |
| | | |
| | | // ===== å®å ===== |
| | | AFTER_SALE_TICKET("aftersales_ticket", "å®åå·¥å"), |
| | | AFTER_SALE_RETURN("aftersales_return", "å®åéè´§ç³è¯·"), |
| | | |
| | | // ===== MES ===== |
| | | MES_PD_DOCUMENT("mes_pd_document", "MES è®¾è®¡èµæ"); |
| | | |
| | |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- å®åå·¥åç®¡çæ¨¡å --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-aftersales</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- spring boot é
ç½®æéä¾èµ --> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |