feat(finance): 对接课题经费拨付与财务报销模块
- 新增 yudao-module-finance-api 接口供课题管理调用
- 实现经费拨付时自动生成 1:1 财务报销单并提交审批
- 新增 ResearchFundStatusListener 监听器处理审批结果回写
- 更新 BPM 审批监听器数量统计为 15 个
- 修改课题经费拨付记录与财务报销单软关联关系
- 完善经费拨付必填凭证附件验证逻辑
- 更新文档说明课题与财务模块数据流向关系
| | |
| | | - **ä¸å¡å®ä½**ï¼ç¦»æ£å¶é å·¥å产ä¾é人财ç©ä¸ä½åï¼è¦çãé宿¥å â éè´/ç产 â è´¨æ£ â ä»å¨ â åè´§ â 忬¾ â å®åãå
¨é¾è·¯éç¯ |
| | | - **ææ¯åºåº§**ï¼yudaoï¼ruoyi-vue-proï¼äºå¼ï¼Spring Boot + MyBatis + Flowable + Redis + MySQL 8.4 + Milvus + éä¹åé®ï¼å端 mom-pro2-beforeï¼Vue3ï¼ |
| | | - **æ ¸å¿ä¸»çº¿**ï¼CRM åå â ERP éå®è®¢å â MES 主计å/å·¥å/æ¥å·¥ â è´¨æ£ä¸ä»å¨ â éå®åºåº â å¼ç¥¨å款 â å®åéç¯ |
| | | - **ç¬ç«æ¨¡å**ï¼è´¢å¡æ¥éï¼`yudao-module-finance`ï¼æ¥éå/æç»/å票éä»¶/审æ¹/彿¡£ï¼ä¸ä¼å管çï¼`yudao-module-ums`ï¼å
¥ä¼ç³è¯·/ç§ä¹¦å¤ä¸çäºä¼ä¸¤çº§å®¡æ¹/ä¼å/é讯å½ï¼åèªæä¸æ¡é¾è·¯ï¼åä¸ä¸å
¶ä»ä¸å¡æ¨¡å产çåæ®å
³èï¼UMS ä¾å¤ï¼å®¡æ¹éè¿ä¼ç» AdminUserApi å建系ç»ç»å½è´¦å·ï¼ï¼è¯¾é¢ç®¡çï¼`yudao-module-research`ï¼è¯¾é¢æå/å¨çº¿ç³æ¥/ä¸å®¶è¯å®¡/ä¸çº§ç«é¡¹å®¡æ¹/ç«é¡¹éç¥/ç»è´¹æ¨ä»ï¼ä¸ºå¦ä¸æ¡ç¬ç«ç§ç 主线ï¼ä»
åå¤å `ums_member` ä½ä¸ºç³æ¥äººãåå
å `system_notice` ç«é¡¹å
Œ |
| | | - **ç¬ç«æ¨¡å**ï¼è´¢å¡æ¥éï¼`yudao-module-finance`ï¼æ¥éå/æç»/å票éä»¶/审æ¹/彿¡£ï¼å¯¹å¤æä¾ `yudao-module-finance-api` ä¾ä»æ¨¡å建åï¼ä¸ä¼å管çï¼`yudao-module-ums`ï¼å
¥ä¼ç³è¯·/ç§ä¹¦å¤ä¸çäºä¼ä¸¤çº§å®¡æ¹/ä¼å/é讯å½ï¼åèªæä¸æ¡é¾è·¯ï¼UMS ä¾å¤ï¼å®¡æ¹éè¿ä¼ç» AdminUserApi å建系ç»ç»å½è´¦å·ï¼ï¼è¯¾é¢ç®¡çï¼`yudao-module-research`ï¼è¯¾é¢æå/å¨çº¿ç³æ¥/ä¸å®¶è¯å®¡/ä¸çº§ç«é¡¹å®¡æ¹/ç«é¡¹éç¥/ç»è´¹æ¨ä»ï¼ä¸ºå¦ä¸æ¡ç¬ç«ç§ç 主线ï¼åå¤å `ums_member` ä½ä¸ºç³æ¥äººãå `system_notice` ç«é¡¹å
¬åï¼**并已对æ¥è´¢å¡**ï¼ç»è´¹æ¨ä» 1:1 èªå¨çæè´¢å¡æ¥éåå¹¶æäº¤å®¡æ¹ï¼å®¡æ¹ç»æç» BPM çå¬å¨åå课é¢ä¾§æ¨æ¬¾å°è´¦ |
| | | |
| | | ## 2. ç®å½ç»æ |
| | | |
| | |
| | | | 09-data-flow | è·¨æ¨¡åæ°æ®æµï¼åæ®çæãåæ®µå¸¦å
¥ãæ°éååãäºä»¶ï¼ | |
| | | | 10-business-object | æ ¸å¿ä¸å¡å¯¹è±¡ ERï¼åªå«ä¸å¡å¯¹è±¡ï¼éå
¨åºè¡¨ï¼ | |
| | | | 11-ai-business-flow | AI ä¸å¡é¾è·¯ï¼OCR/è´¨æ£å¤å®/åç±»é¢æµ/RAGï¼å« API ä¾èµï¼ | |
| | | | 12-finance-flow | è´¢å¡æ¥éï¼ç¬ç«æ¨¡åï¼ï¼æ¥éå+æç»+å票éä»¶ â æäº¤ BPM å®¡æ¹ â éè¿/驳å â 彿¡£ç»æ | |
| | | | 12-finance-flow | è´¢å¡æ¥éï¼ç¬ç«æ¨¡åï¼ï¼æ¥éå+æç»+å票éä»¶ â æäº¤ BPM å®¡æ¹ â éè¿/驳å â 彿¡£ç»æï¼åæ®æ¥æºå«æå·¥æ°å»ºä¸ã课é¢ç»è´¹æ¨ä»èªå¨çæã两类 | |
| | | | 13-ums-membership-flow | ä¼åå
¥ä¼ï¼ç¬ç«æ¨¡åï¼ï¼å
¥ä¼ç³è¯· + ææéä»¶ â æäº¤ BPM 两级审æ¹ï¼ç§ä¹¦å¤å审âçäºä¼å®¡è®®ï¼â éè¿èªå¨å»ºä¼åä¸ç»å½è´¦å· â ä¼åå表/éè®¯å½æ£ç´¢ | |
| | | | 14-research-flow | 课é¢ç®¡çï¼ç¬ç«æ¨¡åï¼ï¼æååå¸(éç¹/ä¸è¬)âå¨çº¿ç³æ¥(éä¼å带åºç³æ¥äºº)âä¸å®¶è¯åæç»å ææåâBPM ä¸çº§å®¡æ¹(ç§ä¹¦å¤å½¢å¼å®¡æ¥âä¸å®¶è¯å®¡âå¦ä¼ç«é¡¹å®¡æ¹)âç«é¡¹ç¼å·ä¸å
¬åâç»è´¹æ¨ä»è®°å½ | |
| | | | 14-research-flow | 课é¢ç®¡çï¼ç¬ç«æ¨¡åï¼ï¼æååå¸(éç¹/ä¸è¬)âå¨çº¿ç³æ¥(éä¼å带åºç³æ¥äºº)âä¸å®¶è¯åæç»å ææåâBPM ä¸çº§å®¡æ¹(ç§ä¹¦å¤å½¢å¼å®¡æ¥âä¸å®¶è¯å®¡âå¦ä¼ç«é¡¹å®¡æ¹)âç«é¡¹ç¼å·ä¸å
¬åâç»è´¹æ¨ä»ï¼åè¯å¿
å¡«â1:1 èªå¨çæå¹¶æäº¤è´¢å¡æ¥éåâè´¢å¡å®¡æ ¸/è´¢å¡ä¸»ç®¡ä¸¤çº§å®¡æ¹âç»æç»çå¬å¨ååå°è´¦ï¼éè¿å·²æ¨ä»/驳å已驳åå¯éå/æ¤ååå¾
æ¨ä»ï¼| |
| | | |
| | | å¾ä¸ç¶ææ°åå为æºç æä¸¾çå®å¼ï¼å¦å·¥å 0è稿/1已确认/2宿/3åæ¶ï¼ERP å®¡æ¹ 15审æ¹ä¸/20å·²å®¡æ ¸ï¼ã |
| | | |
| | |
| | | - æ¬ç®å½ç±é¡¹ç®æè½ **project-business-analysis** 管çï¼`.claude/skills/project-business-analysis/`ï¼ï¼å¹¶æè§å `.claude/rules/business-visualization-maintenance.md` 强å¶ï¼ä¸å¡æ¨¡å/æµç¨/ç¶æ/对象/è§è²/AI åæ´åéåæ¥ç»´æ¤æ¬ç®å½ã |
| | | - å¢éç»´æ¤ï¼æ¹å¯¹åºç `mermaid/*.mmd` + `data/*.json` â è¿è¡ä¸é¢ç sync èæ¬ â æµè§å¨éªè¯åå½±åå¾ã |
| | | - å
¨ééåï¼åå·®è¿å¤§æ¶ï¼ï¼å¯¹ Claude 说ãéæ°çæä¸å¡å
¨æ¯ãï¼æè½ä¼éæ°èµ°è¯»æºç å¹¶æçææ¨¡å¼é建ã |
| | | - çæåºçº¿ï¼dev_business @ 87bf4a99ï¼2026-09-10ï¼2026-09-28 å¢éè¡¥å
è´¢å¡æ¥é模åï¼`yudao-module-finance`ï¼ãä¼åç®¡çæ¨¡åï¼`yudao-module-ums`ï¼ä¸è¯¾é¢ç®¡ç模åï¼`yudao-module-research`ï¼ä¸æé¡¹ 1~5ï¼äºæç»é¡¹éªæ¶ä¸ææå½æ¡£å°æªåï¼å¾ä¸å·²æ 注æªè¦çèå´ï¼ã |
| | | - çæåºçº¿ï¼dev_business @ 87bf4a99ï¼2026-09-10ï¼2026-09-28 å¢éè¡¥å
è´¢å¡æ¥é模åï¼`yudao-module-finance`ï¼ãä¼åç®¡çæ¨¡åï¼`yudao-module-ums`ï¼ä¸è¯¾é¢ç®¡ç模åï¼`yudao-module-research`ï¼ä¸æé¡¹ 1~5ï¼äºæç»é¡¹éªæ¶ä¸ææå½æ¡£å°æªåï¼å¾ä¸å·²æ 注æªè¦çèå´ï¼ï¼**2026-09-29 å¢é**ï¼è¯¾é¢ç»è´¹æ¨ä»å¯¹æ¥è´¢å¡æ¥éââæ°å»º `yudao-module-finance-api`ï¼`FinanceReimbursementApi` æ¬å° Bean è°ç¨ï¼å»ºå+æäº¤/æ¹å+éæ/å é¤/æ¥è¯¢ï¼ï¼ç»è®°æ¨æ¬¾æ¶ 1:1 èªå¨çæ `finance_reimbursement`ï¼ç³»ç»çæ 1 è¡æç»ï¼å¹¶èªå¨æäº¤ `finance_reimbursement_approve` 两级审æ¹ï¼æ°å¢ç¬¬ 15 个ä¸å¡çå¬å¨ `ResearchFundStatusListener` æå®¡æ¹ç»æååè¯¾é¢æ¨æ¬¾å°è´¦ï¼éè¿ 20 / 驳å 30 / æ¤å 0ï¼ï¼å½±åå¾ 08 / 09 / 10 / 14 ä¸ data å
¨é¨å份 jsonã |
| | | |
| | | ## 7. å·²ç¥å¾
确认ä¸å¡ |
| | | |
| | | è§ `data/business.json` ç `pendingConfirm`ï¼é¡µé¢ãå¾
确认äºé¡¹ãæ ï¼ï¼è¦ç¹ï¼ä»åºç±»å/åæ ¼ä»æ¹é æªè½å°ãHRM äº¤æ¥ expandUserIds å°æªè¢«ä¸å¡æ¥è¯¢æ¥å
¥ã忬¾ä¸æ¶æ¬¾åæªèµ° BPMãè´¢å¡å¾ç¨½ååæ¹æ³ä¸ºç©ºãNCR å¤ç½®ä¸ååæºåãè´¢å¡æ¥éç BPM æµç¨å®ä¹æªåå¸ä¸æ®éè§è²æªæèåãä¼å管çç BPM æµç¨æªåå¸ä¸ç¼ºå®¡æ¹èªå®ä¹è¡¨å页ãèªå¨å»ºè´¦å·ç¨ææºå·ä½åå§å¯ç åå¨å¼±å£ä»¤é£é©ã课é¢ç®¡ççè¯åæéä¸éè¿éå¼ä¸ºå ä½è§åå¾
å¦ä¼ç¡®è®¤ã䏿ç»è´¹æ¨ä»ä¸è´¢å¡æ¨¡åæ æ°æ®åæ¥ãç³æ¥åä¸ä¼å为软å
³èå¯è½æ¬ç©ºçã |
| | | è§ `data/business.json` ç `pendingConfirm`ï¼é¡µé¢ãå¾
确认äºé¡¹ãæ ï¼ï¼è¦ç¹ï¼ä»åºç±»å/åæ ¼ä»æ¹é æªè½å°ãHRM äº¤æ¥ expandUserIds å°æªè¢«ä¸å¡æ¥è¯¢æ¥å
¥ã忬¾ä¸æ¶æ¬¾åæªèµ° BPMãè´¢å¡å¾ç¨½ååæ¹æ³ä¸ºç©ºãNCR å¤ç½®ä¸ååæºåãè´¢å¡æ¥éç BPM æµç¨å®ä¹æªåå¸ä¸æ®éè§è²æªæèåãä¼å管çç BPM æµç¨æªåå¸ä¸ç¼ºå®¡æ¹èªå®ä¹è¡¨å页ãèªå¨å»ºè´¦å·ç¨ææºå·ä½åå§å¯ç åå¨å¼±å£ä»¤é£é©ã课é¢ç®¡ççè¯åæéä¸éè¿éå¼ä¸ºå ä½è§åå¾
å¦ä¼ç¡®è®¤ã课é¢ç»è´¹æ¨ä»è½å·²å¯¹æ¥è´¢å¡æ¥éä½å°è´¦ä¸æ¥éå为软å
³èï¼è´¢å¡ä¾§å åä¼çæ¬ç©º `reimbursement_id`ï¼ãæ°å»ºçè´¢å¡æ¥éå®¡æ¹æµç¨èç¹å®¡æ¹äººéä¸çº¿åå¨ BPM è®¾è®¡å¨æå®é
ç»ç»è°æ´ãç³æ¥åä¸ä¼å为软å
³èå¯è½æ¬ç©ºçã |
| | |
| | | "businessModules": 16, |
| | | "coreObjects": 56, |
| | | "documentFlows": 9, |
| | | "approvalListeners": 14, |
| | | "approvalListeners": 15, |
| | | "aiCapabilities": 8, |
| | | "wmBillTypes": 15 |
| | | }, |
| | |
| | | "转æ£ç³è¯·(hrm_regularize_application)ãå¹è®è¯ä¹¦çä»
æ SQL ä¸èååå§åï¼Java ä¾§ Service/Controller æªå®ç°", |
| | | "NCR å¤ç½®ç»æï¼è¿å·¥/éè´§ï¼æªååè§¦åæºåæ®ï¼ä»
å°è´¦è®°å½", |
| | | "MPS ç¶ææä¸¾ç¬ç«ç¼å·(0/1/2/3)ï¼ä¸éç¨åæ®å¸¸é(0/1/4/5)ä¸ä¸è´", |
| | | "è´¢å¡æ¥éï¼BPM åç±» finance_reimbursement_approve ä¸å°æ å·²åå¸çæµç¨å®ä¹ï¼act_re_cprocdef 为空ï¼ï¼ä¸æµç¨éæãèªå®ä¹è¡¨åè·¯å¾ãé
为 /finance/reimbursement/detail/approve/index.vueï¼å¦åå端ãæäº¤å®¡æ¹ã被ç¦ç¨ã审æ¹ä¸å¿çä¸å°æ¥éåå
容ãé BPM 设计å¨ä¾§é
ç½®ã", |
| | | "è´¢å¡æ¥éï¼BPM åç±» finance_reimbursement_approve ä¸å°æ å·²åå¸çæµç¨å®ä¹ï¼act_re_procdef 为空ï¼ââ该æµç¨ç°å·²æ¯ã课é¢ç»è´¹æ¨ä»èªå¨å»ºåå¹¶æäº¤ãç硬åç½®ï¼æ¬æ¹æ¡å·²æå 2 èç¹ BPMNï¼docs/sql/finance_reimbursement_approve.bpmnï¼è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹ï¼å¾
é¨ç½²ï¼é¨ç½²åè¿éæãèªå®ä¹è¡¨åè·¯å¾ãé
为 /finance/reimbursement/detail/approve/index.vueï¼form_type=20ï¼ï¼å¦åå端ãæäº¤å®¡æ¹ã被ç¦ç¨ã审æ¹ä¸å¿çä¸å°æ¥éåå
容ãé BPM 设计å¨ä¾§é
ç½®ã", |
| | | "è´¢å¡æ¥éï¼èåä»
æäº super_adminï¼è¶
管ç±ä»£ç ç´è¿å
¨é¨èåï¼ï¼æ®éè§è²æªé
system_role_menuï¼éè¶
管ç»å½çä¸å°ãæ¥éåãèåãå¾
确认æ¯å¦è¡¥ææã", |
| | | "ä¼å管çï¼ä¼å管çèå(1075490~1075503)ä»
super_admin å¯è§ï¼æ®éè§è²æªé
system_role_menuï¼éè¶
管ç»å½çä¸å°ä¼å管çç®å½ãå¾
确认æ¯å¦è¡¥ææã", |
| | | "ä¼å管çï¼å®¡æ¹éè¿èªå¨å»ºç³»ç»è´¦å·ç¨ãèç³»çµè¯ãåæ¶ä½ç¨æ·åä¸åå§å¯ç ï¼è¥èç³»çµè¯ä¸ºç©ºä¼ç¨åé¢é unknown å
åºï¼åå¨å¼±å£ä»¤ä¸éåé£é©ãå¾
确认æ¯å¦æ¹é ã", |
| | | "ä¼å管çï¼èªå¨å»ºæ¡£ä¸æ¬è¿ contactUser/unitIntro/expireDateï¼ums_application æ 对åºå段ï¼ï¼åä½ä¼åçãè系人/åä½ç®ä»/æææãåªè½å¨ä¼åå表æå·¥è¡¥å½ãå¾
确认æ¯å¦éè¦ç³è¯·åå¢å段ã", |
| | | "ä¼å管çï¼åä½ä¼åçç级åå
¸ ums_unit_grade ä»
å°ãä¼é¿åä½ã(4)ï¼ä½æ ¡éªé»è¾é¢å¤ç¡¬ç¼ç ç¦æ¢åä½éãçäºé¿ã(grade=5)ââè¯¥å¼æ¬ä¸å¨åä½åå
¸å
ï¼å±é²å¾¡æ§å使 ¡éªãå¾
确认æ¯å¦ç²¾ç®ã", |
| | | "课é¢ç®¡çï¼ä¸å®¶è¯åæéï¼éé¢0.3/æ¹æ¡0.3/å¢é0.2/ææ0.2ï¼ä¸ãå æååâ¥60 ä¸ å¤æ°ç»è®ºä¸ºæ¨èç«é¡¹ãçéè¿é弿¯å ä½è§åï¼éå¦ä¼æç»ç¡®è®¤ï¼å·²éä¸ä¸ºå¸¸é便äºè°æ´ãå¾
ç¡®è®¤ï¼æ¹å¨åªéæ¹å¸¸éã", |
| | | "课é¢ç®¡çï¼ä¸æç»è´¹æ¨ä»åªå¨æ¬æ¨¡åè½æ¨æ¬¾è®°å½ï¼ä¸è´¢å¡æ¨¡åæ 任使°æ®åæ¥ï¼åä¸ç¬é±å¨ä¸¤å¤è®°å½åå¨ä¸ä¸è´é£é©ï¼äºæå¯¹æ¥æ¶éæç¡®ä»¥åªä¾§ä¸ºåãå¾
确认ã", |
| | | "课é¢ç®¡çï¼ç»è´¹æ¨ä»å·²å¯¹æ¥è´¢å¡æ¥éï¼1:1 çæ finance_reimbursement å¹¶èªå¨æäº¤å®¡æ¹ï¼ï¼ä½å°è´¦ä¸æ¥éåæ¯è½¯å
³èï¼æ å¤é®ï¼ä»
é reimbursement_idï¼ï¼è´¢å¡ä¾§ç´æ¥å 餿¥éåä¼çä¸å°è´¦çæ¬ç©º reimbursement_idï¼å·²ç¨ FUND_REIMBURSEMENT_NOT_EXISTS 精确æç¤ºå
åºï¼ä¸åæ°æ®åºçº§çº¦æãå·²æ¥åçé£é©ã", |
| | | "课é¢ç®¡çï¼æ°å»ºçè´¢å¡æ¥éå®¡æ¹æµç¨ finance_reimbursement_approve 为 2 èç¹ï¼è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹ï¼ï¼èç¹é»è®¤å®¡æ¹äººçç¥ä¸ºãè§è² = è¶
级管çå(1)ã便¬¡å®¡æ¹ãï¼ä¸çº¿åéå¨ BPM 设计å¨ä¸æå¦ä¼/è´¢å¡å®é
审æ¹äººè°æ´ï¼å¦å该è§è²ä¸å¤ç¨æ·ä¼åæé人ä¼ç¾ãç¯å¢é
置项ï¼é代ç 缺é·ã", |
| | | "课é¢ç®¡çï¼ç»è´¹æ¨ä»å°è´¦çãå·²æ¨ä»(20)ãçä»·äºæ¥éåãå·²éè¿(20)ãï¼ä¸å«åºçº³å®é
仿¬¾å¨ä½ï¼è¥æ¥åéè¦ç¬ç«çã已仿¬¾ãç¶æï¼éå¦å¢ç¶æä¸å®¡æ¹èç¹ãäºæå¯æ©å±ã", |
| | | "课é¢ç®¡çï¼ç³æ¥åä¸ ums_member æ¯è½¯å
³èï¼æ å¤é®ï¼ï¼ä¼å被å é¤åç³æ¥åä¼ç䏿¬ç©º memberIdï¼æåå表é容éå±ç¤ºãä¼åå·²å é¤ããå¾
确认æ¯å¦å å¤é®æå é¤ä¿æ¤ã", |
| | | "课é¢ç®¡çï¼BPM æµç¨ research_topic_approve ä¸èç¹é»è®¤å®¡æ¹äººä¸ºãè§è²=è¶
级管çå(1) + 便¬¡å®¡æ¹ãï¼è¯¥ dev åºè¶
级管çåè§è²ä¸æ 4 ä¸ªç¨æ·ï¼admin/å¼ å¨/马è³/马è´ï¼ï¼æ¯ä¸ªèç¹é 4 人ä¼ç¾ææ¨è¿ï¼å
¨æ°å®è£
åºè¯¥è§è²ä»
admin ä¸äººãæµç¨å¯å¼ç®±å³ç¨ãdev åºéåå°è¶
级管çåç¨æ·ææ¹å¨ BPM 设计å¨ä¸ä¸ºæ¯èç¹æå®å®¡æ¹äººãç¯å¢é
置项ï¼é代ç 缺é·ã", |
| | | "课é¢ç®¡çï¼ç«é¡¹éç¥å¤ç¨ system_notice ç³»ç»å
¬åï¼ä¸æ°å¢ system_notify_templateãä¸åç«å
ä¿¡ï¼å¦éçä¿¡/ç«å
ä¿¡å®åéç¥éå¦è¡é
ç½®ãå¾
确认éç¥æ¸ éã" |
| | | ], |
| | | "generatedAt": "2026-09-28", |
| | | "analysisBasis": "åºäº dev_business 忝 87bf4a99 æºç ï¼6 ç»å¹¶è¡æºç 走读ï¼MES ç产质é / MES ä»å¨ / ERP / CRM+SRM / å®å+HRM / AI+BI+MDM+BPM+åºåº§ï¼ï¼2026-09-28 å¢éè¡¥å
yudao-module-finance ç¬ç«è´¢å¡æ¥é模åï¼æ¥éå + æç» + å票éä»¶ + BPM å®¡æ¹ + 彿¡£ï¼ä¸ yudao-module-ums ç¬ç«ä¼åç®¡çæ¨¡åï¼å
¥ä¼ç³è¯· + BPM ä¸¤çº§å®¡æ¹ + 审æ¹éè¿èªå¨å»ºä¼åä¸ç»å½è´¦å· + ä¼åå表/é讯å½ï¼ï¼2026-09-28 å¢éï¼BPM æµç¨å®ä¹ ums_membership_approveï¼å
¥ä¼å®¡æ¹ï¼å·²å¨ mom-jssm é¨ç½²å¹¶å¹¶å
¥ config_export_all é¶æ®µä¸ï¼åç±» ums_membership_approveï¼ç§ä¹¦å¤å审 â çäºä¼å®¡è®®ï¼ä¸¤èç¹å®¡æ¹äººå为ãè§è²ãçç¥ãè§è²=è¶
级管çå(1) å
åºï¼è¡¨åç±»å=èªå®ä¹è¡¨åï¼æ¥çè·¯å¾ /ums/application/detail/approve/index.vueï¼ï¼åæ¶ä¿®å¤ mom-jssm ç± CREATE TABLE ... LIKE å
é导è´ç 47 个æå ruoyi-vue-pro ç act_*/flw_* è·¨åºå¤é®ï¼é建为æå mom-jssm èªèº«ï¼å¤å¿è¡é¢æ£ä¸º 0ï¼ï¼2026-09-28 å¢éï¼æ°å¢ yudao-module-research ç¬ç«ç§ç è¯¾é¢æ¨¡å䏿ï¼è¯¾é¢æååå¸ + å¨çº¿ç³æ¥ + ä¸å®¶è¯å®¡æç» + BPM ä¸çº§ç«é¡¹å®¡æ¹ + ç«é¡¹éç¥å
¬å + ç»è´¹æ¨ä»è®°å½ï¼4 å¼ research_* 表 / 5 个åå
¸ / bpm_category id=8002 / æµç¨ research_topic_approve / èå 1075510~1075553ï¼ï¼å¹¶å¹¶å
¥ config_export_all_20260928 é¶æ®µä¸ï¼ç³æ¥äººå ums_memberï¼è½¯å
³èï¼ãç«é¡¹éç¥å¤ç¨ system_notice å
¬åãæ¨æ¬¾åè¯èµ° system éä»¶ä¸å¿ recordType=research_fund_record" |
| | | "generatedAt": "2026-09-29", |
| | | "analysisBasis": "åºäº dev_business 忝 87bf4a99 æºç ï¼6 ç»å¹¶è¡æºç 走读ï¼MES ç产质é / MES ä»å¨ / ERP / CRM+SRM / å®å+HRM / AI+BI+MDM+BPM+åºåº§ï¼ï¼2026-09-28 å¢éè¡¥å
yudao-module-finance ç¬ç«è´¢å¡æ¥é模åï¼æ¥éå + æç» + å票éä»¶ + BPM å®¡æ¹ + 彿¡£ï¼ä¸ yudao-module-ums ç¬ç«ä¼åç®¡çæ¨¡åï¼å
¥ä¼ç³è¯· + BPM ä¸¤çº§å®¡æ¹ + 审æ¹éè¿èªå¨å»ºä¼åä¸ç»å½è´¦å· + ä¼åå表/é讯å½ï¼ï¼2026-09-28 å¢éï¼BPM æµç¨å®ä¹ ums_membership_approveï¼å
¥ä¼å®¡æ¹ï¼å·²å¨ mom-jssm é¨ç½²å¹¶å¹¶å
¥ config_export_all é¶æ®µä¸ï¼åç±» ums_membership_approveï¼ç§ä¹¦å¤å审 â çäºä¼å®¡è®®ï¼ä¸¤èç¹å®¡æ¹äººå为ãè§è²ãçç¥ãè§è²=è¶
级管çå(1) å
åºï¼è¡¨åç±»å=èªå®ä¹è¡¨åï¼æ¥çè·¯å¾ /ums/application/detail/approve/index.vueï¼ï¼åæ¶ä¿®å¤ mom-jssm ç± CREATE TABLE ... LIKE å
é导è´ç 47 个æå ruoyi-vue-pro ç act_*/flw_* è·¨åºå¤é®ï¼é建为æå mom-jssm èªèº«ï¼å¤å¿è¡é¢æ£ä¸º 0ï¼ï¼2026-09-28 å¢éï¼æ°å¢ yudao-module-research ç¬ç«ç§ç è¯¾é¢æ¨¡å䏿ï¼è¯¾é¢æååå¸ + å¨çº¿ç³æ¥ + ä¸å®¶è¯å®¡æç» + BPM ä¸çº§ç«é¡¹å®¡æ¹ + ç«é¡¹éç¥å
¬å + ç»è´¹æ¨ä»è®°å½ï¼4 å¼ research_* 表 / 5 个åå
¸ / bpm_category id=8002 / æµç¨ research_topic_approve / èå 1075510~1075553ï¼ï¼å¹¶å¹¶å
¥ config_export_all_20260928 é¶æ®µä¸ï¼ç³æ¥äººå ums_memberï¼è½¯å
³èï¼ãç«é¡¹éç¥å¤ç¨ system_notice å
¬åãæ¨æ¬¾åè¯èµ° system éä»¶ä¸å¿ recordType=research_fund_recordï¼2026-09-29 å¢éï¼è¯¾é¢ç»è´¹æ¨ä»å¯¹æ¥è´¢å¡æ¥éââæ°å»º yudao-module-finance-apiï¼FinanceReimbursementApiï¼å»ºå+æäº¤/æ¹å+éæ/å é¤/æ¥è¯¢åæ¹æ³ï¼æ¬å° Spring Bean è°ç¨ï¼æ é Feignï¼ï¼è¯¾é¢ä¾§ç»è®°æ¨æ¬¾æ¶ 1:1 èªå¨çæ finance_reimbursementï¼ç³»ç»çæ 1 è¡æç»ï¼è´¹ç¨ç±»å=å
¶ä» 5ãå票éé¢=æ¨ä»éé¢ãåç¥¨æ¥æ=æ¨ä»æ¥æã说æ=ã课é¢ãåã第 N ææ¨æ¬¾ãï¼å¹¶ç«å³æäº¤ BPMï¼åå reimbursement_id/reimbursement_noãå°è´¦ç½®ãæ¥é审æ¹ä¸(15)ãï¼åè¯æ¹ä¸ºç»è®°æ¶å¿
å¡«å¹¶åç»ï¼research_fund_record + finance_reimbursementï¼ï¼æ°å¢ ResearchFundStatusListenerï¼ç¬¬ 15 个ä¸å¡çå¬å¨ï¼ä¸ finance èªå·±ç FinanceReimbursementStatusListener 订é
å䏿µç¨ key å¹¶è¡è§¦åï¼æå®¡æ¹ç»æååå°è´¦ï¼éè¿âå·²æ¨ä»(20)ã驳åâ已驳å(30)+驳ååå /æ¶é´ãæ¤åæåæ¶âéåå¾
æ¨ä»(0)坿¹åå¯éæ°åèµ·ï¼æ°é 2 èç¹ BPMN docs/sql/finance_reimbursement_approve.bpmnï¼è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹ï¼category id=216 å·²åå¨ä½æµç¨å®ä¹å¾
é¨ç½²ï¼" |
| | | } |
| | |
| | | {"stage": "建档", "action": "审æ¹éè¿é©åèªå¨å»ºä¼åï¼â çæä¼åç¼å· HY+yyyyMMdd+6使µæ°´ â¡AdminUserApi.createUser 建系ç»è´¦å·ï¼ç¨æ·åä¸åå§å¯ç =èç³»çµè¯ãæµç§°=ç³è¯·äººå§åãé¨é¨=å¦ä¼ä¼åï¼â¢ä¼åè½åºï¼å
¥ä¼æ¥æ=å½å¤©ãç¶æ 1 æ£å¸¸ãapplicationId åå¡«æ¥æºç³è¯·åï¼ï¼ææºå·éå¤ä¼æç¡®æ¥é", "roles": ["ç³»ç»èªå¨"]}, |
| | | {"stage": "管ç䏿£ç´¢", "action": "ä¼ååè¡¨æ¯ææå·¥æ°å¢/ç¼è¾/å é¤ï¼ç级ä¸ç±»åæ ¡éªï¼åä½ä¼åä¸å¯éãçäºé¿ãï¼ï¼ä¼åé讯å½ä¸ºåªè¯»é¡µï¼æå°åºç¼ç ä¸è¡ä¸æ£ç´¢", "roles": ["ä¼å管çå", "å
¨ä½å¯æ¥é讯å½"]}]}, |
| | | {"id": "research", "name": "课é¢ç®¡çæµç¨", "mermaid": "mermaid/14-research-flow.mmd", "color": "#e070a8", |
| | | "summary": "ç¬ç«ç§ç 模åï¼yudao-module-researchï¼ï¼å¦ä¼åå¸è¯¾é¢æåï¼éç¹/ä¸è¬åç±»ï¼â ä¼åå¨çº¿æäº¤è¯¾é¢ç³æ¥ä¹¦ â æäº¤ BPM ä¸çº§å®¡æ¹ï¼ç§ä¹¦å¤å½¢å¼å®¡æ¥ â ä¸å®¶è¯å®¡ â å¦ä¼ç«é¡¹å®¡æ¹ï¼ï¼ä¸å®¶è¯åä»¥ç»æåæç»å表记å½å¹¶ç±å端èªå¨æ±æ»å æååãæå䏿¨èç»è®º â 审æ¹éè¿çæç«é¡¹ç¼å·å¹¶åå¸ç³»ç»å
¬å â ææ¹æ¬¡ç»è®°ç»è´¹æ¨ä»è®°å½ï¼å«åè¯éä»¶ï¼ãé¢çº§äºæåè¡¥ç»é¡¹éªæ¶ä¸ææå½æ¡£ã", |
| | | "summary": "ç¬ç«ç§ç 模åï¼yudao-module-researchï¼ï¼å¦ä¼åå¸è¯¾é¢æåï¼éç¹/ä¸è¬åç±»ï¼â ä¼åå¨çº¿æäº¤è¯¾é¢ç³æ¥ä¹¦ â æäº¤ BPM ä¸çº§å®¡æ¹ï¼ç§ä¹¦å¤å½¢å¼å®¡æ¥ â ä¸å®¶è¯å®¡ â å¦ä¼ç«é¡¹å®¡æ¹ï¼ï¼ä¸å®¶è¯åä»¥ç»æåæç»å表记å½å¹¶ç±å端èªå¨æ±æ»å æååãæå䏿¨èç»è®º â 审æ¹éè¿çæç«é¡¹ç¼å·å¹¶åå¸ç³»ç»å
¬å â ææ¹æ¬¡ç»è®°ç»è´¹æ¨ä»ï¼åè¯å¿
å¡«ï¼ï¼æ¯æ¡æ¨æ¬¾è®°å½èªå¨çæå¹¶æäº¤ä¸å¼ 1:1 çè´¢å¡æ¥éåï¼finance_reimbursementï¼ï¼èµ° BPM 两级审æ¹åç±çå¬å¨æç»æååå°è´¦ãé¢çº§äºæåè¡¥ç»é¡¹éªæ¶ä¸ææå½æ¡£ã", |
| | | "steps": [ |
| | | {"stage": "å叿å", "action": "æ°å»ºæåéç±»å« 1éç¹è¯¾é¢ / 2ä¸è¬è¯¾é¢ï¼å¡«ç³æ¥èµ·æ¢æ¶é´ä¸æåæ£æï¼ç¼å· GL+yyyyMMdd+6使µæ°´ï¼Redis æ¯æ¥éç½®ï¼ï¼status: 0è稿/20å·²åå¸/30å·²æªæ¢ãä»
èç¨¿å¯æ¹å¯å ï¼åå¸åå³å»ç»ï¼å·²äº§çç³æ¥åçæåç¦æ¢å é¤ï¼æç¤ºè¯¥æåä¸å·²æ N å¼ ç³æ¥åï¼", "roles": ["å¦ä¼ç§ä¹¦å¤", "课é¢ç®¡çå"]}, |
| | | {"stage": "å¨çº¿ç³æ¥", "action": "ä»å·²åå¸ä¸å¨ç³æ¥æå
çæåæ°å»ºç³æ¥ä¹¦ï¼éä¼åï¼ums_memberï¼èªå¨å¸¦åºå§å/å·¥ä½åä½/èç§°/èç³»çµè¯/é®ç®±ï¼å¯æ¹ï¼å¡«è¯¾é¢åç§°ã课é¢ç»æåãç³è¯·ç»è´¹ãç³æ¥ä¹¦æ£æï¼ç¼å· SB+yyyyMMdd+6使µæ°´ï¼ç±»å«åä½èªæåï¼ä¸ä¿¡ä»»åç«¯ä¼ å¼ï¼status: 0è稿", "roles": ["课é¢ç³æ¥äººï¼ä¼åï¼", "课é¢ç®¡çå"]}, |
| | |
| | | {"stage": "ä¸å®¶è¯å®¡", "action": "ç³æ¥åå¤äºå®¡æ¹ä¸(15)æ¶å½å
¥ä¸å®¶è¯åæç»ï¼ä¸ä½ä¸å®¶ä¸è¡ï¼å§å/åä½/èç§° + éé¢ä»·å¼0.3/ç ç©¶æ¹æ¡0.3/å¢éåºç¡0.2/颿ææ0.2 å项åå¼ + ç»è®º + æè§ï¼ï¼åç«¯æ¯æ¬¡å¢å æ¹åéç® compositeScore å æå计ãæå æåéåºéæ rankingï¼å¹¶åå主å reviewAvgScoreï¼å
¨é¨ä¸å®¶ååï¼ä¸ reviewPassï¼ååè¾¾æ ä¸å¤æ°ç»è®ºä¸ºæ¨èç«é¡¹ï¼ï¼æç»å
¨é¨å 餿¶æ±æ»å¼æ¸
ç©ºä¸ºæªæ±æ»ï¼å项åå¼åå¨ 0~100 ä¹å¤æ¶æç¤ºæåºå
·ä½ç»´åº¦ä¸å®é
å¼", "roles": ["è¯å®¡ä¸å®¶", "å¦ä¼ç§ä¹¦å¤", "课é¢ç®¡çå"]}, |
| | | {"stage": "ç«é¡¹å®¡æ¹", "action": "BPM æµç¨ research_topic_approve 顺åºèµ°ä¸èç¹ï¼ç§ä¹¦å¤å½¢å¼å®¡æ¥ â ä¸å®¶è¯å®¡ â å¦ä¼ç«é¡¹å®¡æ¹ãå®¡æ¹æ¹æ³ä¸å®¡æ¹äººå¨æµç¨å®ä¹å
é
ç½®ï¼é¨ç½²åç±ç®¡çåå¨ BPM æµç¨è®¾è®¡å¨æå¦ä¼å®é
ç»ç»è°æ´ï¼å®¡æ¹ä¸å¿å
çèªå®ä¹è¡¨ååªè¯»åæ¾ç³æ¥å + è¯å®¡æç» + æ¨ä»è®°å½ãéè¿â20 å·²ç«é¡¹ã驳åâ35 已驳åãåæ¶âéå 0 è稿", "roles": ["å¦ä¼ç§ä¹¦å¤ï¼å½¢å¼å®¡æ¥ï¼", "è¯å®¡ä¸å®¶ï¼è¯å®¡èç¹ï¼", "å¦ä¼çäºä¼ï¼ç«é¡¹å®¡æ¹ï¼"]}, |
| | | {"stage": "ç«é¡¹ä¸éç¥", "action": "çå¬å¨ ResearchApplicationStatusListener å
åå审æ¹ç¶æï¼å®¡æ¹éè¿ååè° approveApplicationï¼çæç«é¡¹ç¼å· LX+yyyyMMdd+6使µæ°´ ä¸ approveTimeï¼å·²æç¼å·åå¹çè·³è¿ï¼ãç¹ãåå¸ç«é¡¹éç¥ãçæ system_notice å
¬åï¼æ é¢ãå
³äºå
¬å¸ç«é¡¹è¯¾é¢çéç¥ãï¼æ£æå«è¯¾é¢å/ç«é¡¹ç¼å·/ç±»å«/ç³æ¥äºº/åä½/èµå©éé¢ï¼ï¼åå noticeId é²éå¤ââéå¤ç¹å»æå·²å叿¦æªå¹¶åç¥ä¸æ¬¡å叿¶é´", "roles": ["课é¢ç®¡çå", "å¦ä¼ç§ä¹¦å¤"]}, |
| | | {"stage": "ç»è´¹æ¨ä»", "action": "ä»
ãå·²ç«é¡¹(20)ãçç³æ¥åå¯ç»è®°æ¨æ¬¾è®°å½ï¼æ¹æ¬¡åç§°/æ¨ä»éé¢/æ¨ä»æ¥æ/æ¶æ¬¾åä½/ç¶æ/夿³¨/åè¯éä»¶ï¼ï¼é颿 ¡éªï¼å·²ç»è®°éé¢ + æ¬æ¬¡éé¢ ä¸å¾è¶
åºè¯¥åç³è¯·ç»è´¹ï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ï¼status: 0å¾
æ¨ä»/20å·²æ¨ä»ï¼åè¯æç»èµ° system éä»¶ä¸å¿ recordType=research_fund_recordï¼ç¶ææ¹ä¸ºå·²æ¨ä»æ¶åè¯å¿
å¡«ï¼ä»
å¾
æ¨ä»ç¶æå¯æ¹å¯å ï¼ç¼è¾æ¶ä¼ææ¬è¡éé¢å åä½é¢æ¾ç¤º", "roles": ["å¦ä¼è´¢å¡", "课é¢ç®¡çå"]}]}, |
| | | {"stage": "ç»è´¹æ¨ä»", "action": "ä»
ãå·²ç«é¡¹(20)ãçç³æ¥åå¯ç»è®°æ¨æ¬¾è®°å½ï¼æ¹æ¬¡åç§°/æ¨ä»éé¢/æ¨ä»æ¥æ/æ¶æ¬¾åä½/夿³¨/åè¯éä»¶ï¼ï¼åè¯å¿
å¡«ãç»è®°æ¶ä¸æ¡é¾å®æï¼â 课é¢ä¾§è½ research_fund_record å°è´¦ï¼å
ç½®å¾
æ¨ä»ï¼â¡ å䏿¹ blob åç»å°è¯¾é¢å°è´¦ä¸è´¢å¡æ¥éå â¢ ç» yudao-module-finance-api èªå¨çæ 1:1 ç finance_reimbursement æ¥éåï¼1 è¡æç»ï¼è´¹ç¨ç±»å=å
¶ä»ãå票éé¢=æ¨ä»éé¢ãåç¥¨æ¥æ=æ¨ä»æ¥æãè´¹ç¨è¯´æ=ã课é¢ã课é¢åã第Næ/第N次ç»è´¹æ¨æ¬¾ãï¼â£ ç«å³æäº¤ BPM æ¥éå®¡æ¹ â¤ å°è´¦å忥éåå·å¹¶ç½®ãæ¥é审æ¹ä¸(15)ããé颿 ¡éªï¼å·²ç»è®°éé¢ + æ¬æ¬¡éé¢ ä¸å¾è¶
åºè¯¥åç³è¯·ç»è´¹ï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ãç¶æç±ç³»ç»é©±å¨ï¼0å¾
æ¨ä»/15æ¥é审æ¹ä¸/20å·²æ¨ä»/30已驳åï¼åªæãå¾
æ¨ä»ãå¯å ï¼å é¤è卿¸
çè´¢å¡ä¾§è稿æ¥éåï¼ï¼ãå¾
æ¨ä»ãã已驳åã坿¹å¹¶éæ°åèµ·æ¥éï¼å·²é©³åæ¹åæ¸
空驳ååå 䏿¶é´ï¼ï¼è´¢å¡ç«¯æ¤åæåæ¶åéåãå¾
æ¨ä»(0)ããè´¢å¡å®¡æ¹åç±»ä¸æ²¡æå·²å叿µç¨æ¶ç´æ¥æ¥éä¸ä¸å»ºåï¼ä¸çå¤å¿è稿æ¥éå", "roles": ["å¦ä¼è´¢å¡", "课é¢ç®¡çå", "è´¢å¡å®¡æ ¸äºº", "è´¢å¡ä¸»ç®¡"]}]}, |
| | | {"id": "ai", "name": "AI ä¸å¡æµç¨", "mermaid": "mermaid/11-ai-business-flow.mmd", "color": "#56c8d8", |
| | | "summary": "ç»ä¸æ¨¡å¼ï¼ä¸å¡ä¾§æ¶éä¸ä¸æ(å¿
è¦æ¶è° MDM/SRM/CRM API ååç§°)âç»è£
Promptâchat/chatWithImageâè§£æ JSONâå端é¢å¡«æå»ºè®®ï¼æ Function Callingï¼RAG ç¥è¯åºå·²å»ºæä½ææ ä¸å¡æ¶è´¹ã", |
| | | "steps": [ |
| | |
| | | {"key": "fin", "name": "è´¢å¡æ¥éï¼ç¬ç«ï¼", "color": "#3ec9a7", "tag": "FIN", "flow": "finance", |
| | | "positioning": "ç¬ç«çå票æ¥éåæ®ä¸å½æ¡£", |
| | | "problem": "纸质å票é¾å½éãæ¥éå®¡æ¹æ ççã彿¡£åæ æ³è¿½æº¯", |
| | | "features": ["æ¥éå(主表 + 1..n æç»è¡)", "å票é件夿件ä¸ä¼ (éä»¶ä¸å¿å¤æå
³è storage_attachment)", "åå· Redis çæ BX+yyyyMMdd+6使µæ°´Â·æ¯æ¥éç½®", "æç»éä¸»è¡¨ä¸æ¬¡æ§æäº¤(å
å åå¢å
¨éè¦ç)", "BPM 审æ¹(éè¿20/驳å35/åæ¶éåè稿0)", "已驳å坿¹å票åéæ°æäº¤", "彿¡£ç»æ 40 å¹¶è®°å½å½æ¡£æ¶é´", "è´¹ç¨ç±»å/æ¥éç¶æååå
¸ + Excel 导åº"], |
| | | "features": ["æ¥éå(主表 + 1..n æç»è¡)", "å票é件夿件ä¸ä¼ (éä»¶ä¸å¿å¤æå
³è storage_attachment)", "åå· Redis çæ BX+yyyyMMdd+6使µæ°´Â·æ¯æ¥éç½®", "æç»éä¸»è¡¨ä¸æ¬¡æ§æäº¤(å
å åå¢å
¨éè¦ç)", "BPM 审æ¹(éè¿20/驳å35/åæ¶éåè稿0)", "已驳å坿¹å票åéæ°æäº¤", "彿¡£ç»æ 40 å¹¶è®°å½å½æ¡£æ¶é´", "è´¹ç¨ç±»å/æ¥éç¶æååå
¸ + Excel 导åº", "å¯¹å¤æä¾ FinanceReimbursementApi(yudao-module-finance-api)ä¾è¯¾é¢ç®¡çç»è´¹æ¨ä»èªå¨å»ºåå¹¶æäº¤(1 è¡æç»Â·è´¹ç¨ç±»å=å
¶ä»Â·éé¢ä¸è´)"], |
| | | "objects": ["æ¥éå", "æ¥éæç»"], |
| | | "roles": ["æ¥é人", "è´¢å¡", "审æ¹äºº"], |
| | | "upstream": [], "downstream": [], |
| | | "upstream": ["课é¢ç®¡ç(ç»è´¹æ¨ä» 1:1 èªå¨çææ¥éå·走 yudao-module-finance-api·æ¬å° Bean è°ç¨)"], "downstream": [], |
| | | "coreTables": ["finance_reimbursement", "finance_reimbursement_item"]}, |
| | | {"key": "pro", "name": "ç产管ç", "color": "#e0b34f", "tag": "MES-PRO", "flow": "production", |
| | | "positioning": "ç产æ§è¡æ ¸å¿ï¼è®¡å-å·¥å-ä»»å¡-æ¥å·¥", |
| | |
| | | {"key": "res", "name": "课é¢ç®¡çï¼ç¬ç«ï¼", "color": "#e070a8", "tag": "RES", "flow": "research", |
| | | "positioning": "å¦ä¼/åä¼åç§ç 课é¢å
¨çå½å¨æï¼æååå¸ â å¨çº¿ç³æ¥ â ä¸å®¶è¯å®¡ â ç«é¡¹å®¡æ¹ â ç»è´¹æ¨ä»ï¼ç«é¡¹éç¥èµ°ç³»ç»å
¬åï¼", |
| | | "problem": "è¯¾é¢æåé 线ä¸åå¸ãç³æ¥ä¹¦é 纸质æé®ä»¶æ¶éãä¸å®¶è¯åæ£è½å¨è¡¨æ ¼éæ æ³èªå¨æ±æ»æåãç«é¡¹ä¸æ¨æ¬¾æ çç", |
| | | "features": ["è¯¾é¢æå(éç¹1/ä¸è¬2 åç±»æ æ³¨)", "æåç¶æ 0è稿/20å·²åå¸/30å·²æªæ¢Â·åå¸/æªæ¢ä¸¤ä¸ªå¨ä½", "æåç¼å· GL+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)", "å¨çº¿ç³æ¥ä¹¦(éæå+éä¼å带åºç³æ¥äººä¿¡æ¯+课é¢ç»æå+ç³è¯·ç»è´¹+ç³æ¥ä¹¦æ£æ)", "ç³æ¥ç¼å· SB+åæ¥æµæ°´Â·ç±»å«åä½èªæåä¸ä¿¡ä»»å端", "ç³æ¥ç¶æ 0è稿/15审æ¹ä¸/20å·²ç«é¡¹/35已驳å", "æäº¤åæ ¡éªæåå·²åå¸ä¸å¨ç³æ¥æå
(éæ¡æ¥å
·ä½ç»´åº¦ä¸æ¶é´)", "ä¸å®¶è¯å®¡æç»å表(ä¸ä½ä¸å®¶ä¸è¡Â·åé¡¹å æ 0.3/0.3/0.2/0.2)", "å端èªå¨éç®å æåè®¡ä¸æå·åå主ååå䏿¨èç»è®º", "BPM ä¸çº§å®¡æ¹ research_topic_approve(ç§ä¹¦å¤å½¢å¼å®¡æ¥âä¸å®¶è¯å®¡âå¦ä¼ç«é¡¹å®¡æ¹)", "审æ¹éè¿çæç«é¡¹ç¼å· LX+åæ¥æµæ°´ ä¸ç«é¡¹æ¶é´(å¹ç)", "åå¸ç«é¡¹éç¥(çæ system_notice å
¬å·åå noticeId é²éå¤)", "ç»è´¹æ¨ä»è®°å½(æ¹æ¬¡/éé¢/æ¥æ/æ¶æ¬¾åä½/ç¶æ/åè¯éä»¶)·éé¢ä¸å¾è¶
ç³è¯·ç»è´¹", "éä»¶èµ° system éä»¶ä¸å¿(recordType=research_guideline / research_application / research_fund_record)"], |
| | | "features": ["è¯¾é¢æå(éç¹1/ä¸è¬2 åç±»æ æ³¨)", "æåç¶æ 0è稿/20å·²åå¸/30å·²æªæ¢Â·åå¸/æªæ¢ä¸¤ä¸ªå¨ä½", "æåç¼å· GL+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)", "å¨çº¿ç³æ¥ä¹¦(éæå+éä¼å带åºç³æ¥äººä¿¡æ¯+课é¢ç»æå+ç³è¯·ç»è´¹+ç³æ¥ä¹¦æ£æ)", "ç³æ¥ç¼å· SB+åæ¥æµæ°´Â·ç±»å«åä½èªæåä¸ä¿¡ä»»å端", "ç³æ¥ç¶æ 0è稿/15审æ¹ä¸/20å·²ç«é¡¹/35已驳å", "æäº¤åæ ¡éªæåå·²åå¸ä¸å¨ç³æ¥æå
(éæ¡æ¥å
·ä½ç»´åº¦ä¸æ¶é´)", "ä¸å®¶è¯å®¡æç»å表(ä¸ä½ä¸å®¶ä¸è¡Â·åé¡¹å æ 0.3/0.3/0.2/0.2)", "å端èªå¨éç®å æåè®¡ä¸æå·åå主ååå䏿¨èç»è®º", "BPM ä¸çº§å®¡æ¹ research_topic_approve(ç§ä¹¦å¤å½¢å¼å®¡æ¥âä¸å®¶è¯å®¡âå¦ä¼ç«é¡¹å®¡æ¹)", "审æ¹éè¿çæç«é¡¹ç¼å· LX+åæ¥æµæ°´ ä¸ç«é¡¹æ¶é´(å¹ç)", "åå¸ç«é¡¹éç¥(çæ system_notice å
¬å·åå noticeId é²éå¤)", "ç»è´¹æ¨ä»è®°å½(æ¹æ¬¡/éé¢/æ¥æ/æ¶æ¬¾åä½/夿³¨/åè¯éä»¶)·åè¯å¿
填·éé¢ä¸å¾è¶
ç³è¯·ç»è´¹", "ç»è´¹æ¨ä» 1:1 èªå¨çæå¹¶æäº¤è´¢å¡æ¥éå(FinanceReimbursementApi·1 è¡æç»Â·è´¹ç¨ç±»å=å
¶ä»)", "æ¨ä»ç¶æ 0å¾
æ¨ä»/15æ¥é审æ¹ä¸/20å·²æ¨ä»/30已驳åÂ·ç± BPM çå¬å¨åå(å«é©³ååå 䏿¶é´)", "已驳å坿¹éé¢/åè¯åéæ°åèµ·æ¥é·å¾
æ¨ä»å¯å å¹¶è卿¸
çè´¢å¡ä¾§è稿æ¥éå", "éä»¶èµ° system éä»¶ä¸å¿(recordType=research_guideline / research_application / research_fund_record)"], |
| | | "objects": ["è¯¾é¢æå", "课é¢ç³æ¥ä¹¦", "ä¸å®¶è¯å®¡æç»", "ç»è´¹æ¨ä»è®°å½"], |
| | | "roles": ["课é¢ç³æ¥äºº(ä¼å)", "课é¢ç®¡çå", "è¯å®¡ä¸å®¶", "å¦ä¼ç§ä¹¦å¤", "å¦ä¼çäºä¼"], |
| | | "upstream": ["ä¼å管ç(ums_member åç³æ¥äººå§å/åä½/èç§°/çµè¯)", "BPM(æµç¨å®ä¹ research_topic_approve)"], |
| | | "downstream": ["system(system_notice ç«é¡¹éç¥å
¬å)", "system(éä»¶ä¸å¿)", "è´¢å¡(äºæé¢æå¾
对æ¥Â·ä¸æä¸æ¥)"], |
| | | "roles": ["课é¢ç³æ¥äºº(ä¼å)", "课é¢ç®¡çå", "è¯å®¡ä¸å®¶", "å¦ä¼ç§ä¹¦å¤", "å¦ä¼çäºä¼", "å¦ä¼è´¢å¡"], |
| | | "upstream": ["ä¼å管ç(ums_member åç³æ¥äººå§å/åä½/èç§°/çµè¯)", "BPM(æµç¨å®ä¹ research_topic_approve / finance_reimbursement_approve)"], |
| | | "downstream": ["system(system_notice ç«é¡¹éç¥å
¬å)", "system(éä»¶ä¸å¿)", "è´¢å¡(ç»è´¹æ¨ä»çæ finance_reimbursement æ¥éå·已对æ¥)"], |
| | | "coreTables": ["research_guideline", "research_application", "research_topic_review", "research_fund_record"]}, |
| | | {"key": "bpm", "name": "åå审æ¹", "color": "#e6a23c", "tag": "BPM", "flow": null, |
| | | "positioning": "å
¨ç³»ç»åæ®å®¡æ¹ä¸æ¢ï¼Flowableï¼", |
| | | "problem": "夿¨¡ååæ®éè¦çµæ´»å¯é
çå¤çº§å®¡æ¹", |
| | | "features": ["BPMN+éé飿 ¼å设计å¨", "æµç¨å®ä¹é¨ç½²", "审æ¹äºä»¶ç»ä¸åè°(BpmProcessInstanceStatusEvent)", "14个ä¸å¡çå¬å¨", "表åÂ·ç¨æ·ç»Â·æé·å ç¾"], |
| | | "features": ["BPMN+éé飿 ¼å设计å¨", "æµç¨å®ä¹é¨ç½²", "审æ¹äºä»¶ç»ä¸åè°(BpmProcessInstanceStatusEvent)", "15个ä¸å¡çå¬å¨(å䏿µç¨ key å
许å¤ä¸ªçå¬å¨å¹¶è¡Â·åèªæ key è¿æ»¤)", "表åÂ·ç¨æ·ç»Â·æé·å ç¾"], |
| | | "objects": ["æµç¨æ¨¡å", "æµç¨å®ä¾", "审æ¹ä»»å¡"], |
| | | "roles": ["审æ¹äºº(ææµç¨é
ç½®)", "æµç¨ç®¡çå"], |
| | | "upstream": ["åä¸å¡æäº¤å®¡æ¹"], "downstream": ["åè°æ´æ°åä¸å¡åæ®ç¶æ"], |
| | |
| | | {"name": "æç计å", "module": "设å¤", "table": "mes_cal_plan", "doc": "çç»Ãçæ¬¡Ãæ¥ææçï¼ä¾ç产ä¸èå¤å¼ç¨", "upstream": [], "downstream": ["ç产任å¡", "èå¤"], "keywords": "æç çç» çæ¬¡ æ¥å"}, |
| | | {"name": "æ¥å模æ¿", "module": "è´¨æ£æ¥å", "table": "qc_report_template", "doc": "æºè½è´¨æ£æ¥å模æ¿ï¼å¯ç¨0/åç¨1ï¼ç»å¸å
容åå¨ qc_report_template_versionï¼è稿0/å·²åå¸1/å·²åç¨2ï¼å·²åå¸ä¸å¯è¦çï¼ï¼currentVersion æåå½åå·²åå¸çæ¬ï¼æºæä»¶ç» AI 导å
¥è¯å«æè稿åç±äººå·¥ç¡®è®¤ææä¸ºçæ¬ï¼å䏿¨¡æ¿éå¤å¯¼å
¥æãæ¿æ¢ãå¤çââå
å æ§éä»¶ï¼è¿å¸¦ blob è¡ä¸ç£çæä»¶ï¼åç»æ°çï¼ä¸çå¤å¿æä»¶ï¼å 餿¨¡æ¿ä¼è¿å¸¦æ¸
éä»¶", "upstream": ["人工设计(GrapesJS 设计å¨)", "AI 导å
¥è稿(qc-report/ai-import/draft)"], "downstream": ["模æ¿çæ¬", "æ¥åå®ä¾"], "keywords": "æ¥åæ¨¡æ¿ è´¨æ£æ¥å template è®¾è®¡å¨ çæ¬ AI导å
¥ è¯å« è稿 æºæä»¶æ¿æ¢"}, |
| | | {"name": "æ¥åå®ä¾", "module": "è´¨æ£æ¥å", "table": "qc_report_instance", "doc": "åºä»¶äº§ç©ï¼ç¼å· QR+yyyyMMdd+4使µæ°´æå¤©ç¬ç«ä¸ä¸å¡å¯ä¸ï¼å¯æ¾å¼æå®è¦çï¼æ³¨æ uk_report_no ä¸åºå软å é¤ï¼å æçå·ä¸åæ¶ï¼ï¼ä¸¤æ¡åºä»¶å
¥å£ï¼éç¨ generateï¼è°ç¨æ¹èªå¸¦ contextï¼ä¸ generate-from-qcï¼æ°æ®ä» MES è´¨æ£ååï¼æéç qc-report:instance:generate å·²å
¥ system_menu id=1075416ï¼äºéæ ¡éªæä¸å¡ä¼å
çº§åªæ¥ç¬¬ä¸å¤ï¼105_000 ç±»åéæ³ / 105_001 åæ®ä¸åå¨ / 105_002 æªå®æ / 105_003 æªå¤å® / 105_005 模æ¿ç±»åä¸ç¬¦ / 105_006 æ å¯ç¨æ£éªé¡¹ï¼åå¼ è´¨æ£åå表çè¡æä½ãåºæ¥åãä»
å¨ status=已宿æ¶å¯è§ï¼å¼¹çªåªå reportType ä¸è´ã模æ¿å¯ç¨ãä¸ currentVersion æåççæ¬å·²åå¸ç模æ¿ï¼å端 /qc-report/template/selectable å¤å®ââåç¨çæ¬ä¸æ¸
空 currentVersionï¼å端æ¿åé¡µç»æèªå·±æ¨å¯¼ä¼æ¼ï¼ï¼ç»æå°±å°å±ç¤ºå¹¶è·³æ¬é¡µå表ï¼ï¼å»ç» data_snapshotï¼å¤å®åæ°æ®ï¼å«å端ç®å¥½ç PASS/FAIL ä¸åæ ¼çï¼ä¸ render_htmlï¼regenerate åªé渲æçãæ°æ®ä¸ç¼å·ä¸åï¼business_id/business_type å MES 表åï¼mes_qc_iqc çï¼ä¸åæ® IDï¼å¯åæ¥ãä¸åå¯åºå¤ä»½ï¼æ¥å头å¦å¸¦åæ®åå¤å® qcResult(æ°)/qcResultText(䏿ï¼åæ ¼/ç¹é/ä¸åæ ¼éè´§/ä¸åæ ¼æ¥åº)ï¼ä¸å¼æä¸æå¤å®å¹¶åäºä¸è¦çï¼ååºå¸¦ undecidableCount=å¿«ç
§ä¸ result 为空串ç项æ°ä¸ warningsï¼åç»æ é¢è·³è¿/ææ å·²å /æªå½å®æµå¼/æ ·åè¶
3ï¼ï¼ä¸¤è
é½ä¸è½åºãäºåçä¸å°", "upstream": ["æ¥å模æ¿çæ¬", "è´¨æ£åä¸ä¸æ(éç¨ generate ç±è°ç¨æ¹ä¼ å
¥)", "MES è´¨æ£å IQC/IPQC/OQC/RQC(generate-from-qc ç» MesQcReportApi åæ°)"], "downstream": ["å端å®ä¾é¡µ /qc/report-instance(å表·iframeé¢è§Â·å¿«ç
§é¡µç¾Â·å¯¼åºPDF)", "PDF彿¡£(system_storage_attachment recordType=qc_report_instance)"], "keywords": "æ¥åå®ä¾ åºä»¶ QRç¼å· å¿«ç
§ å¤ç° regenerate PDF彿¡£ æ¥åå®ä¾é¡µ 导åºPDF generate-from-qc è´¨æ£ååºæ¥å åºæ¥åå¼¹çª qcResult undecidableCount warnings å¾
å¤å® 忥 ä¸å¡åæ®çé"}, |
| | | {"name": "æ¥éå", "module": "è´¢å¡æ¥é", "table": "finance_reimbursement", "doc": "åå·å¯èªå®ä¹(ä¸é´ä¸å
è®¸ç©ºæ ¼ï¼ä¸å·²æåå·éå¤åæ¥é)ï¼æ°å¢æ¶ç空æçº¯ç©ºæ ¼ç±ç³»ç»çæ BX+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼ä¿®æ¹æ¶çç©ºè¡¨ç¤ºä¿æä¸åãstatus: 0è稿/15审æ¹ä¸/20å·²éè¿/35已驳å/40已彿¡£ï¼ä»
è稿å¯å ãè稿ä¸å·²é©³å坿¹ãä»
å·²éè¿å¯å½æ¡£ï¼æäº¤åç± BPM çå¬å¨æç»æååç¶æ(åæ¶éåè稿)ï¼å®¡æ¹ä¸ processInstanceId 被ååï¼ç¬ç«æ¨¡åï¼ä¸ä¸å
¶å®ä¸å¡æ¨¡å产çåæ®å
³è", "upstream": [], "downstream": ["æ¥éæç»", "å票éä»¶(storage_attachment·recordType=finance_reimbursement)"], "keywords": "æ¥éå æ¥é å票 reimbursement BX 彿¡£ è´¢å¡ è´¹ç¨ èªå®ä¹åå·"}, |
| | | {"name": "æ¥éå", "module": "è´¢å¡æ¥é", "table": "finance_reimbursement", "doc": "åå·å¯èªå®ä¹(ä¸é´ä¸å
è®¸ç©ºæ ¼ï¼ä¸å·²æåå·éå¤åæ¥é)ï¼æ°å¢æ¶ç空æçº¯ç©ºæ ¼ç±ç³»ç»çæ BX+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼ä¿®æ¹æ¶çç©ºè¡¨ç¤ºä¿æä¸åãstatus: 0è稿/15审æ¹ä¸/20å·²éè¿/35已驳å/40已彿¡£ï¼ä»
è稿å¯å ãè稿ä¸å·²é©³å坿¹ãä»
å·²éè¿å¯å½æ¡£ï¼æäº¤åç± BPM çå¬å¨æç»æååç¶æ(åæ¶éåè稿)ï¼å®¡æ¹ä¸ processInstanceId 被ååãæ¥æºä¸¤æ¡ï¼â è´¢å¡æ¨¡å页é¢äººå·¥å¡«æ¥ â¡è¯¾é¢ç®¡çãç»è´¹æ¨ä»ãç» FinanceReimbursementApi(yudao-module-finance-api)èªå¨å»ºåå¹¶ç«å³æäº¤(1:1ãéé¢ä¸è´ãç³»ç»åºå® 1 è¡æç»Â·è´¹ç¨ç±»å=å
¶ä»)ââåè
ç审æ¹ç»æç±è¯¾é¢ä¾§ ResearchFundStatusListener 订é
å䏿µç¨ååæ¨æ¬¾å°è´¦ï¼æ¥éåæ¬èº«ä¸ååä»»ä½å¤é¨åæ®", "upstream": ["课é¢ç®¡ç(ç»è´¹æ¨ä»Â·ç» FinanceReimbursementApi èªå¨å»ºå)", "人工填æ¥"], "downstream": ["æ¥éæç»", "å票éä»¶(storage_attachment·recordType=finance_reimbursement)", "è¯¾é¢æ¨æ¬¾å°è´¦(ä»
ç» BPM äºä»¶ååç¶æ)"], "keywords": "æ¥éå æ¥é å票 reimbursement BX 彿¡£ è´¢å¡ è´¹ç¨ èªå®ä¹åå· è¯¾é¢ç»è´¹æ¨ä» èªå¨å»ºå FinanceReimbursementApi"}, |
| | | {"name": "æ¥éæç»", "module": "è´¢å¡æ¥é", "table": "finance_reimbursement_item", "doc": "æ¥éåçè´¹ç¨è¡ï¼è´¹ç¨ç±»å(1å·®æ
/2åå
¬/3æå¾
/4交é/5å
¶ä»)ãå票å·ç ãå票éé¢ãåç¥¨æ¥æãå¼ç¥¨æ¹ãè´¹ç¨è¯´æï¼éä¸»è¡¨ä¸æ¬¡æ§æäº¤(å
å åå¢å
¨éè¦ç)ï¼æäº¤æ¶å¿
é¡»å¥æè¡ id ä¸ reimbursementId ââ æç»å 餿¯è½¯å ï¼åä¼ å id ä¼ä¸å·²è½¯å è¡ä¸»é®å²çª", "upstream": ["æ¥éå"], "downstream": [], "keywords": "æ¥éæç» è´¹ç¨æç» è´¹ç¨ç±»å å票éé¢ item æç»è¡ å·®æ
"}, |
| | | {"name": "å
¥ä¼ç³è¯·å", "module": "ä¼å管ç", "table": "ums_application", "doc": "åå· SQ+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼å端çæä¸å¯èªå®ä¹ï¼memberType 1个人/2åä½å³å®å段åå(ä¸ªäººç¨ workUnit/titleï¼åä½ç¨ legalPerson/organizationCode)ï¼memberGrade æç±»ååä¸ååå
¸ï¼status: 0è稿/15审æ¹ä¸/20å·²éè¿/35已驳åãä»
è稿å¯å (è¿å¸¦æ¸
éä»¶)ãè稿ä¸å·²é©³å坿¹å¯éæï¼æäº¤åç± BPM çå¬å¨æç»æåå(åæ¶éåè稿)ï¼å®¡æ¹ä¸åå processInstanceIdï¼å®¡æ¹éè¿è§¦åèªå¨å»ºä¼åä¸ç³»ç»è´¦å·ãç¬ç«æ¨¡åï¼ä¸ä¸å
¶å®ä¸å¡æ¨¡å产çåæ®å
³è", "upstream": ["人工填æ¥(ç³è¯·äºº)", "è¯æææéä»¶(storage_attachment·recordType=ums_application)"], "downstream": ["ä¼å(审æ¹éè¿èªå¨å建)", "BPM æµç¨å®ä¾(ums_membership_approve åç±»)"], "keywords": "å
¥ä¼ç³è¯· å
¥ä¼ ä¼åç³è¯· application SQ ç§ä¹¦å¤ çäºä¼ å®¡æ¹ ä¼åç±»å 个人 åä½ æ³å®ä»£è¡¨äºº ç ç©¶æ¹å ç³è¯·ç级"}, |
| | | {"name": "ä¼å", "module": "ä¼å管ç", "table": "ums_member", "doc": "åå· HY+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼ä¸¤ä¸ªæ¥æºï¼â å
¥ä¼ç³è¯·å®¡æ¹éè¿èªå¨å建(åå¡« applicationId ä¸ userName/ç³»ç»è´¦å·) â¡ä¼åå表æå·¥æ°å¢ãstatus: 1æ£å¸¸/0æåï¼memberGrade æ memberType å对åºåå
¸ï¼æ ¡éªè§åæ¯åä½ä¼å(type=2)ä¸å¯éãçäºé¿ã(grade=5)ãèªå¨å»ºæ¡£æ¶å
¥ä¼æ¥æ=å½å¤©ã䏿¬è¿ contactUser/unitIntro/expireDate(ç³è¯·åæ 对åºå段)ï¼èªå¨å»ºçç³»ç»è´¦å·ç¨æ·å为èç³»çµè¯ä¸åå§å¯ç å为èç³»çµè¯ï¼é¨é¨åºå®ä¸ºãå¦ä¼ä¼åãï¼ææºå·éå¤ä¼æç¡®æ¥é䏿´åäºå¡åæ»", "upstream": ["å
¥ä¼ç³è¯·å(审æ¹éè¿)", "人工æ°å¢", "éä»¶(storage_attachment·recordType=ums_member)"], "downstream": ["ä¼åé讯å½(æ regionCode/industry æ£ç´¢)", "system_users(ç»å½è´¦å·)"], "keywords": "ä¼å member HY ä¼åç¼å· ä¼åç级 ä¼åç±»å éè®¯å½ å°åº è¡ä¸ å
¥ä¼æ¥æ æææ"}, |
| | | {"name": "è¯¾é¢æå", "module": "课é¢ç®¡ç", "table": "research_guideline", "doc": "æåç¼å· GL+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼category 1éç¹è¯¾é¢/2ä¸è¬è¯¾é¢ï¼publishStatus 0è稿/20å·²åå¸/30å·²æªæ¢ï¼ä»
èç¨¿å¯æ¹å¯å ï¼publish åå¸åå publishTimeï¼close æªæ¢ç½® 30ï¼å·²äº§çç³æ¥å(applicationMapper.selectCountByGuidelineId å¤§äº 0)çæåç¦æ¢å é¤å¹¶å¨æç¤ºä¸æ¥åºè¯¥æåä¸å·²æå¤å°å¼ ç³æ¥åï¼æ£æ content ä¸ºé¿ææ¬ï¼éä»¶ recordType=research_guideline", "upstream": ["人工维æ¤(å¦ä¼ç§ä¹¦å¤)", "æåéä»¶(storage_attachment·recordType=research_guideline)"], "downstream": ["课é¢ç³æ¥ä¹¦(ç³æ¥æ¶å¼ç¨ä¸å¿
须已åå¸å¹¶å¨ç³æ¥æå
)"], "keywords": "è¯¾é¢æå æå åå¸ æªæ¢ éç¹è¯¾é¢ ä¸è¬è¯¾é¢ GL æåç¼å· ç³æ¥æ ç³æ¥èµ·æ¢"}, |
| | | {"name": "课é¢ç³æ¥ä¹¦", "module": "课é¢ç®¡ç", "table": "research_application", "doc": "ç³æ¥ç¼å· SB+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼guidelineId å
³èæåãmemberId å
³è ums_member(软å
³èæ å¤é®ï¼ä¼åå é¤åä¼ç䏿¬ç©º memberId éå®¹éæ¾ç¤º)ï¼applicantName/workUnit/jobTitle/contactPhone/contactEmail ç±éä¼åèªå¨å¸¦åºå¯ææ¹ï¼category åä½èªæåä¸ä¸ä¿¡ä»»åç«¯ä¼ å¼ï¼budgetAmount ç³è¯·ç»è´¹ä¸ºæ¨ä»ä¸éï¼status: 0è稿/15审æ¹ä¸/20å·²ç«é¡¹/35已驳åãä»
è稿å¯å (è¿å¸¦æ¸
éä»¶)ãè稿ä¸å·²é©³å坿¹å¯éæï¼submit åéæ¡æ ¡éªãæåå·²åå¸ãä¸ãç°å¨å¨ç³æ¥æå
ãï¼ä»»ä¸ä¸æ»¡è¶³å³æç»å¹¶æç»´åº¦ç»åºæååä¸å®é
å¼ï¼å®¡æ¹éè¿ç±çå¬å¨çæç«é¡¹ç¼å· researchNo(LX+åæ¥æµæ°´)ä¸ approveTime(å·²æç¼å·å¹çè·³è¿)ï¼reviewAvgScore/reviewPass 为è¯å®¡æ±æ»ååå¼ï¼æç»å ç©ºæ¶æ¸
ææªæ±æ»ï¼noticeId è®°å½å·²åå¸çç«é¡¹éç¥å
¬åï¼éå¤åå¸è¢«æ¦æª", "upstream": ["è¯¾é¢æå(å¿
须已åå¸ä¸å¨ç³æ¥æå
)", "ä¼å(ums_member·带åºç³æ¥äººä¿¡æ¯)", "ç³æ¥éä»¶(storage_attachment·recordType=research_application)"], "downstream": ["ä¸å®¶è¯å®¡æç»", "ç»è´¹æ¨ä»è®°å½", "ç«é¡¹éç¥(system_notice å
¬å)", "BPM æµç¨å®ä¾(research_topic_approve åç±»)", "éä»¶ä¸å¿"], "keywords": "课é¢ç³æ¥ ç³æ¥ä¹¦ ç³æ¥å SB ç³æ¥ç¼å· ç«é¡¹ ç«é¡¹ç¼å· LX ç³è¯·ç»è´¹ ç³æ¥ä¹¦æ£æ 课é¢ç»æå ä¸å®¶è¯å®¡ è¯å®¡æ±æ» ç«é¡¹éç¥ åå¸éç¥ æäº¤å®¡æ¹ 驳å éæ"}, |
| | | {"name": "ä¸å®¶è¯å®¡æç»", "module": "课é¢ç®¡ç", "table": "research_topic_review", "doc": "ä¸ä½ä¸å®¶ä¸è¡çä¸ä¸»å¤è¡å表ï¼evaluatorName/evaluatorUnit/evaluatorTitle + topicScore éé¢ä»·å¼ä¸æä¹(æé0.3) + planScore ç ç©¶æ¹æ¡å¯è¡æ§(0.3) + teamScore å¢éä¸ç ç©¶åºç¡(0.2) + resultScore 颿ææä¸æç(0.2) + conclusion 1æ¨èç«é¡¹/2䏿¨èç«é¡¹ + opinion è¯å®¡æè§ + reviewTimeãcompositeScore ç±å端 weightedScore 计ç®ãranking ç±å端æå æåéåºéæï¼å䏿¥ååç«¯ä¼ å¼ï¼æ¯æ¬¡å¢å æ¹åè° recalculate åå主å reviewAvgScore(å
¨é¨ä¸å®¶å æååå¼Â·ä¿ç2ä½)ä¸ reviewPass(ååè¾¾æ ä¸ å¤æ°ç»è®ºä¸ºæ¨èç«é¡¹æ¶ä¸º 1)ï¼å项åå¼è¶
åº 0~100 æ¶æç¤ºæåºå
·ä½ç»´åº¦ä¸å®é
å¼ï¼ä»
å¨ç³æ¥å status=15 审æ¹ä¸å¯å¢å æ¹", "upstream": ["课é¢ç³æ¥ä¹¦(ä»
审æ¹ä¸å¯å)"], "downstream": ["课é¢ç³æ¥ä¹¦(åå reviewAvgScore/reviewPass)"], "keywords": "ä¸å®¶è¯å®¡ è¯å®¡æç» è¯å å æ æé æå ranking compositeScore æ¨èç«é¡¹ è¯å®¡æè§ åå"}, |
| | | {"name": "ç»è´¹æ¨ä»è®°å½", "module": "课é¢ç®¡ç", "table": "research_fund_record", "doc": "ä¸ä¸»å¤è¡çæ¨æ¬¾è®°å½ï¼batchName æ¹æ¬¡åç§°/amount æ¨ä»éé¢/payDate æ¨ä»æ¥æ/payee æ¶æ¬¾åä½/status 0å¾
æ¨ä» 20å·²æ¨ä»/remarkï¼åè¯éä»¶èµ° system éä»¶ä¸å¿ recordType=research_fund_record(表å
ä¸åæä»¶å°å)ãä»
ç³æ¥å status=20 å·²ç«é¡¹å¯ç»è®°ï¼é颿 ¡éªï¼å·²ç»è®°éé¢(该åå
¨é¨è®°å½æ±å) + æ¬æ¬¡éé¢ ä¸å¾è¶
åºç³æ¥å budgetAmountï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ï¼status=20 å·²æ¨ä» æ¶åè¯éä»¶å¿
å¡«(å端å
è¡æ¦æªï¼å端 validateVoucherRequired å
åº)ï¼ä»
å¾
æ¨ä»ç¶æå¯æ¹å¯å ï¼ç¼è¾æ¶ææ¬è¡éé¢å åå¯ç¨ä½é¢å±ç¤ºé¿å
误解", "upstream": ["课é¢ç³æ¥ä¹¦(å¿
须已ç«é¡¹)"], "downstream": ["æ¨ä»åè¯(storage_attachment·recordType=research_fund_record)", "è´¢å¡(äºæé¢æå¾
对æ¥Â·ä¸æä¸æ¥)"], "keywords": "ç»è´¹æ¨ä» æ¨æ¬¾ æ¨ä»è®°å½ æ¹æ¬¡ æ¨ä»éé¢ åè¯ å¾
æ¨ä» å·²æ¨ä» æ¶æ¬¾åä½ èµå©éé¢ é¢ç® è¶
é¢"} |
| | | {"name": "ç»è´¹æ¨ä»è®°å½", "module": "课é¢ç®¡ç", "table": "research_fund_record", "doc": "ä¸ä¸»å¤è¡çæ¨æ¬¾å°è´¦ï¼batchName æ¹æ¬¡åç§°/amount æ¨ä»éé¢/payDate æ¨ä»æ¥æ/payee æ¶æ¬¾åä½/remarkï¼åè¯éä»¶èµ° system éä»¶ä¸å¿ recordType=research_fund_record(表å
ä¸åæä»¶å°å)ãstatus: 0å¾
æ¨ä»/15æ¥é审æ¹ä¸/20å·²æ¨ä»/30已驳åï¼ç±ç³»ç»ä¸ BPM 驱å¨ï¼æ°å¢/ä¿®æ¹æ¥å£å·²ç§»é¤ status å
¥å(é²ä¼ªé ãå·²æ¨ä»ã)ãç»è®°å³ä¸æ¡é¾ï¼è½å°è´¦ â å䏿¹ blob åç» â ç» FinanceReimbursementApi èªå¨çæ 1:1 ç finance_reimbursement å¹¶ç«å³æäº¤ BPM â åå reimbursement_id/reimbursement_no å¹¶ç½® 15ï¼å®¡æ¹ç»æç±çå¬å¨ååï¼éè¿â20ã驳åâ30(+reject_reason/reject_time)ãæ¤åæåæ¶âéå 0ãä»
ç³æ¥å status=20 å·²ç«é¡¹å¯ç»è®°ï¼åè¯å¿
å¡«ï¼é颿 ¡éªï¼å·²ç»è®°éé¢(该åå
¨é¨è®°å½æ±å) + æ¬æ¬¡éé¢ ä¸å¾è¶
åºç³æ¥å budgetAmountï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ï¼ä»
ãå¾
æ¨ä»ãå¯å (èå¨å é¤è´¢å¡ä¾§è稿æ¥éåï¼éè稿åæç»)ï¼ãå¾
æ¨ä»ãã已驳åã坿¹å¹¶éæ°åèµ·æ¥é(已驳忹忏
空 reject_reason/reject_time)ï¼ç¼è¾æ¶ææ¬è¡éé¢å åå¯ç¨ä½é¢å±ç¤ºé¿å
误解ã䏿¥éå为软å
³è(æ å¤é®)ï¼è´¢å¡ä¾§ç´æ¥å åä¼ç䏿¬ç©º reimbursement_idï¼æ¤æ¶ä¿®æ¹æ¥ãæ¥éåå·²ä¸åå¨ï¼è¯·å 餿¬æ¡è®°å½åéæ°ç»è®°ã", "upstream": ["课é¢ç³æ¥ä¹¦(å¿
须已ç«é¡¹)", "è´¢å¡æ¥éå(1:1 èªå¨çæÂ·è½¯å
³è reimbursement_id)"], "downstream": ["æ¨ä»åè¯(storage_attachment·recordType=research_fund_record)", "è´¢å¡æ¥éå(çæå¹¶æäº¤åºè´¦Â·å®¡æ¹ç»æå忬å°è´¦)"], "keywords": "ç»è´¹æ¨ä» æ¨æ¬¾ æ¨ä»è®°å½ æ¹æ¬¡ æ¨ä»éé¢ åè¯ å¾
æ¨ä» æ¥é审æ¹ä¸ å·²æ¨ä» 已驳å 驳ååå è´¢å¡æ¥éåå· reimbursement_id æ¶æ¬¾åä½ èµå©éé¢ é¢ç® è¶
é¢ éæ°åèµ·æ¥é"} |
| | | ] |
| | | } |
| | |
| | | "businessModules": 16, |
| | | "coreObjects": 56, |
| | | "documentFlows": 9, |
| | | "approvalListeners": 14, |
| | | "approvalListeners": 15, |
| | | "aiCapabilities": 8, |
| | | "wmBillTypes": 15 |
| | | }, |
| | |
| | | "转æ£ç³è¯·(hrm_regularize_application)ãå¹è®è¯ä¹¦çä»
æ SQL ä¸èååå§åï¼Java ä¾§ Service/Controller æªå®ç°", |
| | | "NCR å¤ç½®ç»æï¼è¿å·¥/éè´§ï¼æªååè§¦åæºåæ®ï¼ä»
å°è´¦è®°å½", |
| | | "MPS ç¶ææä¸¾ç¬ç«ç¼å·(0/1/2/3)ï¼ä¸éç¨åæ®å¸¸é(0/1/4/5)ä¸ä¸è´", |
| | | "è´¢å¡æ¥éï¼BPM åç±» finance_reimbursement_approve ä¸å°æ å·²åå¸çæµç¨å®ä¹ï¼act_re_cprocdef 为空ï¼ï¼ä¸æµç¨éæãèªå®ä¹è¡¨åè·¯å¾ãé
为 /finance/reimbursement/detail/approve/index.vueï¼å¦åå端ãæäº¤å®¡æ¹ã被ç¦ç¨ã审æ¹ä¸å¿çä¸å°æ¥éåå
容ãé BPM 设计å¨ä¾§é
ç½®ã", |
| | | "è´¢å¡æ¥éï¼BPM åç±» finance_reimbursement_approve ä¸å°æ å·²åå¸çæµç¨å®ä¹ï¼act_re_procdef 为空ï¼ââ该æµç¨ç°å·²æ¯ã课é¢ç»è´¹æ¨ä»èªå¨å»ºåå¹¶æäº¤ãç硬åç½®ï¼æ¬æ¹æ¡å·²æå 2 èç¹ BPMNï¼docs/sql/finance_reimbursement_approve.bpmnï¼è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹ï¼å¾
é¨ç½²ï¼é¨ç½²åè¿éæãèªå®ä¹è¡¨åè·¯å¾ãé
为 /finance/reimbursement/detail/approve/index.vueï¼form_type=20ï¼ï¼å¦åå端ãæäº¤å®¡æ¹ã被ç¦ç¨ã审æ¹ä¸å¿çä¸å°æ¥éåå
容ãé BPM 设计å¨ä¾§é
ç½®ã", |
| | | "è´¢å¡æ¥éï¼èåä»
æäº super_adminï¼è¶
管ç±ä»£ç ç´è¿å
¨é¨èåï¼ï¼æ®éè§è²æªé
system_role_menuï¼éè¶
管ç»å½çä¸å°ãæ¥éåãèåãå¾
确认æ¯å¦è¡¥ææã", |
| | | "ä¼å管çï¼ä¼å管çèå(1075490~1075503)ä»
super_admin å¯è§ï¼æ®éè§è²æªé
system_role_menuï¼éè¶
管ç»å½çä¸å°ä¼å管çç®å½ãå¾
确认æ¯å¦è¡¥ææã", |
| | | "ä¼å管çï¼å®¡æ¹éè¿èªå¨å»ºç³»ç»è´¦å·ç¨ãèç³»çµè¯ãåæ¶ä½ç¨æ·åä¸åå§å¯ç ï¼è¥èç³»çµè¯ä¸ºç©ºä¼ç¨åé¢é unknown å
åºï¼åå¨å¼±å£ä»¤ä¸éåé£é©ãå¾
确认æ¯å¦æ¹é ã", |
| | | "ä¼å管çï¼èªå¨å»ºæ¡£ä¸æ¬è¿ contactUser/unitIntro/expireDateï¼ums_application æ 对åºå段ï¼ï¼åä½ä¼åçãè系人/åä½ç®ä»/æææãåªè½å¨ä¼åå表æå·¥è¡¥å½ãå¾
确认æ¯å¦éè¦ç³è¯·åå¢å段ã", |
| | | "ä¼å管çï¼åä½ä¼åçç级åå
¸ ums_unit_grade ä»
å°ãä¼é¿åä½ã(4)ï¼ä½æ ¡éªé»è¾é¢å¤ç¡¬ç¼ç ç¦æ¢åä½éãçäºé¿ã(grade=5)ââè¯¥å¼æ¬ä¸å¨åä½åå
¸å
ï¼å±é²å¾¡æ§å使 ¡éªãå¾
确认æ¯å¦ç²¾ç®ã", |
| | | "课é¢ç®¡çï¼ä¸å®¶è¯åæéï¼éé¢0.3/æ¹æ¡0.3/å¢é0.2/ææ0.2ï¼ä¸ãå æååâ¥60 ä¸ å¤æ°ç»è®ºä¸ºæ¨èç«é¡¹ãçéè¿é弿¯å ä½è§åï¼éå¦ä¼æç»ç¡®è®¤ï¼å·²éä¸ä¸ºå¸¸é便äºè°æ´ãå¾
ç¡®è®¤ï¼æ¹å¨åªéæ¹å¸¸éã", |
| | | "课é¢ç®¡çï¼ä¸æç»è´¹æ¨ä»åªå¨æ¬æ¨¡åè½æ¨æ¬¾è®°å½ï¼ä¸è´¢å¡æ¨¡åæ 任使°æ®åæ¥ï¼åä¸ç¬é±å¨ä¸¤å¤è®°å½åå¨ä¸ä¸è´é£é©ï¼äºæå¯¹æ¥æ¶éæç¡®ä»¥åªä¾§ä¸ºåãå¾
确认ã", |
| | | "课é¢ç®¡çï¼ç»è´¹æ¨ä»å·²å¯¹æ¥è´¢å¡æ¥éï¼1:1 çæ finance_reimbursement å¹¶èªå¨æäº¤å®¡æ¹ï¼ï¼ä½å°è´¦ä¸æ¥éåæ¯è½¯å
³èï¼æ å¤é®ï¼ä»
é reimbursement_idï¼ï¼è´¢å¡ä¾§ç´æ¥å 餿¥éåä¼çä¸å°è´¦çæ¬ç©º reimbursement_idï¼å·²ç¨ FUND_REIMBURSEMENT_NOT_EXISTS 精确æç¤ºå
åºï¼ä¸åæ°æ®åºçº§çº¦æãå·²æ¥åçé£é©ã", |
| | | "课é¢ç®¡çï¼æ°å»ºçè´¢å¡æ¥éå®¡æ¹æµç¨ finance_reimbursement_approve 为 2 èç¹ï¼è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹ï¼ï¼èç¹é»è®¤å®¡æ¹äººçç¥ä¸ºãè§è² = è¶
级管çå(1)ã便¬¡å®¡æ¹ãï¼ä¸çº¿åéå¨ BPM 设计å¨ä¸æå¦ä¼/è´¢å¡å®é
审æ¹äººè°æ´ï¼å¦å该è§è²ä¸å¤ç¨æ·ä¼åæé人ä¼ç¾ãç¯å¢é
置项ï¼é代ç 缺é·ã", |
| | | "课é¢ç®¡çï¼ç»è´¹æ¨ä»å°è´¦çãå·²æ¨ä»(20)ãçä»·äºæ¥éåãå·²éè¿(20)ãï¼ä¸å«åºçº³å®é
仿¬¾å¨ä½ï¼è¥æ¥åéè¦ç¬ç«çã已仿¬¾ãç¶æï¼éå¦å¢ç¶æä¸å®¡æ¹èç¹ãäºæå¯æ©å±ã", |
| | | "课é¢ç®¡çï¼ç³æ¥åä¸ ums_member æ¯è½¯å
³èï¼æ å¤é®ï¼ï¼ä¼å被å é¤åç³æ¥åä¼ç䏿¬ç©º memberIdï¼æåå表é容éå±ç¤ºãä¼åå·²å é¤ããå¾
确认æ¯å¦å å¤é®æå é¤ä¿æ¤ã", |
| | | "课é¢ç®¡çï¼BPM æµç¨ research_topic_approve ä¸èç¹é»è®¤å®¡æ¹äººä¸ºãè§è²=è¶
级管çå(1) + 便¬¡å®¡æ¹ãï¼è¯¥ dev åºè¶
级管çåè§è²ä¸æ 4 ä¸ªç¨æ·ï¼admin/å¼ å¨/马è³/马è´ï¼ï¼æ¯ä¸ªèç¹é 4 人ä¼ç¾ææ¨è¿ï¼å
¨æ°å®è£
åºè¯¥è§è²ä»
admin ä¸äººãæµç¨å¯å¼ç®±å³ç¨ãdev åºéåå°è¶
级管çåç¨æ·ææ¹å¨ BPM 设计å¨ä¸ä¸ºæ¯èç¹æå®å®¡æ¹äººãç¯å¢é
置项ï¼é代ç 缺é·ã", |
| | | "课é¢ç®¡çï¼ç«é¡¹éç¥å¤ç¨ system_notice ç³»ç»å
¬åï¼ä¸æ°å¢ system_notify_templateãä¸åç«å
ä¿¡ï¼å¦éçä¿¡/ç«å
ä¿¡å®åéç¥éå¦è¡é
ç½®ãå¾
确认éç¥æ¸ éã" |
| | | ], |
| | | "generatedAt": "2026-09-28", |
| | | "analysisBasis": "åºäº dev_business 忝 87bf4a99 æºç ï¼6 ç»å¹¶è¡æºç 走读ï¼MES ç产质é / MES ä»å¨ / ERP / CRM+SRM / å®å+HRM / AI+BI+MDM+BPM+åºåº§ï¼ï¼2026-09-28 å¢éè¡¥å
yudao-module-finance ç¬ç«è´¢å¡æ¥é模åï¼æ¥éå + æç» + å票éä»¶ + BPM å®¡æ¹ + 彿¡£ï¼ä¸ yudao-module-ums ç¬ç«ä¼åç®¡çæ¨¡åï¼å
¥ä¼ç³è¯· + BPM ä¸¤çº§å®¡æ¹ + 审æ¹éè¿èªå¨å»ºä¼åä¸ç»å½è´¦å· + ä¼åå表/é讯å½ï¼ï¼2026-09-28 å¢éï¼BPM æµç¨å®ä¹ ums_membership_approveï¼å
¥ä¼å®¡æ¹ï¼å·²å¨ mom-jssm é¨ç½²å¹¶å¹¶å
¥ config_export_all é¶æ®µä¸ï¼åç±» ums_membership_approveï¼ç§ä¹¦å¤å审 â çäºä¼å®¡è®®ï¼ä¸¤èç¹å®¡æ¹äººå为ãè§è²ãçç¥ãè§è²=è¶
级管çå(1) å
åºï¼è¡¨åç±»å=èªå®ä¹è¡¨åï¼æ¥çè·¯å¾ /ums/application/detail/approve/index.vueï¼ï¼åæ¶ä¿®å¤ mom-jssm ç± CREATE TABLE ... LIKE å
é导è´ç 47 个æå ruoyi-vue-pro ç act_*/flw_* è·¨åºå¤é®ï¼é建为æå mom-jssm èªèº«ï¼å¤å¿è¡é¢æ£ä¸º 0ï¼ï¼2026-09-28 å¢éï¼æ°å¢ yudao-module-research ç¬ç«ç§ç è¯¾é¢æ¨¡å䏿ï¼è¯¾é¢æååå¸ + å¨çº¿ç³æ¥ + ä¸å®¶è¯å®¡æç» + BPM ä¸çº§ç«é¡¹å®¡æ¹ + ç«é¡¹éç¥å
¬å + ç»è´¹æ¨ä»è®°å½ï¼4 å¼ research_* 表 / 5 个åå
¸ / bpm_category id=8002 / æµç¨ research_topic_approve / èå 1075510~1075553ï¼ï¼å¹¶å¹¶å
¥ config_export_all_20260928 é¶æ®µä¸ï¼ç³æ¥äººå ums_memberï¼è½¯å
³èï¼ãç«é¡¹éç¥å¤ç¨ system_notice å
¬åãæ¨æ¬¾åè¯èµ° system éä»¶ä¸å¿ recordType=research_fund_record" |
| | | "generatedAt": "2026-09-29", |
| | | "analysisBasis": "åºäº dev_business 忝 87bf4a99 æºç ï¼6 ç»å¹¶è¡æºç 走读ï¼MES ç产质é / MES ä»å¨ / ERP / CRM+SRM / å®å+HRM / AI+BI+MDM+BPM+åºåº§ï¼ï¼2026-09-28 å¢éè¡¥å
yudao-module-finance ç¬ç«è´¢å¡æ¥é模åï¼æ¥éå + æç» + å票éä»¶ + BPM å®¡æ¹ + 彿¡£ï¼ä¸ yudao-module-ums ç¬ç«ä¼åç®¡çæ¨¡åï¼å
¥ä¼ç³è¯· + BPM ä¸¤çº§å®¡æ¹ + 审æ¹éè¿èªå¨å»ºä¼åä¸ç»å½è´¦å· + ä¼åå表/é讯å½ï¼ï¼2026-09-28 å¢éï¼BPM æµç¨å®ä¹ ums_membership_approveï¼å
¥ä¼å®¡æ¹ï¼å·²å¨ mom-jssm é¨ç½²å¹¶å¹¶å
¥ config_export_all é¶æ®µä¸ï¼åç±» ums_membership_approveï¼ç§ä¹¦å¤å审 â çäºä¼å®¡è®®ï¼ä¸¤èç¹å®¡æ¹äººå为ãè§è²ãçç¥ãè§è²=è¶
级管çå(1) å
åºï¼è¡¨åç±»å=èªå®ä¹è¡¨åï¼æ¥çè·¯å¾ /ums/application/detail/approve/index.vueï¼ï¼åæ¶ä¿®å¤ mom-jssm ç± CREATE TABLE ... LIKE å
é导è´ç 47 个æå ruoyi-vue-pro ç act_*/flw_* è·¨åºå¤é®ï¼é建为æå mom-jssm èªèº«ï¼å¤å¿è¡é¢æ£ä¸º 0ï¼ï¼2026-09-28 å¢éï¼æ°å¢ yudao-module-research ç¬ç«ç§ç è¯¾é¢æ¨¡å䏿ï¼è¯¾é¢æååå¸ + å¨çº¿ç³æ¥ + ä¸å®¶è¯å®¡æç» + BPM ä¸çº§ç«é¡¹å®¡æ¹ + ç«é¡¹éç¥å
¬å + ç»è´¹æ¨ä»è®°å½ï¼4 å¼ research_* 表 / 5 个åå
¸ / bpm_category id=8002 / æµç¨ research_topic_approve / èå 1075510~1075553ï¼ï¼å¹¶å¹¶å
¥ config_export_all_20260928 é¶æ®µä¸ï¼ç³æ¥äººå ums_memberï¼è½¯å
³èï¼ãç«é¡¹éç¥å¤ç¨ system_notice å
¬åãæ¨æ¬¾åè¯èµ° system éä»¶ä¸å¿ recordType=research_fund_recordï¼2026-09-29 å¢éï¼è¯¾é¢ç»è´¹æ¨ä»å¯¹æ¥è´¢å¡æ¥éââæ°å»º yudao-module-finance-apiï¼FinanceReimbursementApiï¼å»ºå+æäº¤/æ¹å+éæ/å é¤/æ¥è¯¢åæ¹æ³ï¼æ¬å° Spring Bean è°ç¨ï¼æ é Feignï¼ï¼è¯¾é¢ä¾§ç»è®°æ¨æ¬¾æ¶ 1:1 èªå¨çæ finance_reimbursementï¼ç³»ç»çæ 1 è¡æç»ï¼è´¹ç¨ç±»å=å
¶ä» 5ãå票éé¢=æ¨ä»éé¢ãåç¥¨æ¥æ=æ¨ä»æ¥æã说æ=ã课é¢ãåã第 N ææ¨æ¬¾ãï¼å¹¶ç«å³æäº¤ BPMï¼åå reimbursement_id/reimbursement_noãå°è´¦ç½®ãæ¥é审æ¹ä¸(15)ãï¼åè¯æ¹ä¸ºç»è®°æ¶å¿
å¡«å¹¶åç»ï¼research_fund_record + finance_reimbursementï¼ï¼æ°å¢ ResearchFundStatusListenerï¼ç¬¬ 15 个ä¸å¡çå¬å¨ï¼ä¸ finance èªå·±ç FinanceReimbursementStatusListener 订é
å䏿µç¨ key å¹¶è¡è§¦åï¼æå®¡æ¹ç»æååå°è´¦ï¼éè¿âå·²æ¨ä»(20)ã驳åâ已驳å(30)+驳ååå /æ¶é´ãæ¤åæåæ¶âéåå¾
æ¨ä»(0)坿¹åå¯éæ°åèµ·ï¼æ°é 2 èç¹ BPMN docs/sql/finance_reimbursement_approve.bpmnï¼è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹ï¼category id=216 å·²åå¨ä½æµç¨å®ä¹å¾
é¨ç½²ï¼" |
| | | }</script> |
| | | <script type="application/json" id="data-modules">{ |
| | | "modules": [ |
| | |
| | | {"key": "fin", "name": "è´¢å¡æ¥éï¼ç¬ç«ï¼", "color": "#3ec9a7", "tag": "FIN", "flow": "finance", |
| | | "positioning": "ç¬ç«çå票æ¥éåæ®ä¸å½æ¡£", |
| | | "problem": "纸质å票é¾å½éãæ¥éå®¡æ¹æ ççã彿¡£åæ æ³è¿½æº¯", |
| | | "features": ["æ¥éå(主表 + 1..n æç»è¡)", "å票é件夿件ä¸ä¼ (éä»¶ä¸å¿å¤æå
³è storage_attachment)", "åå· Redis çæ BX+yyyyMMdd+6使µæ°´Â·æ¯æ¥éç½®", "æç»éä¸»è¡¨ä¸æ¬¡æ§æäº¤(å
å åå¢å
¨éè¦ç)", "BPM 审æ¹(éè¿20/驳å35/åæ¶éåè稿0)", "已驳å坿¹å票åéæ°æäº¤", "彿¡£ç»æ 40 å¹¶è®°å½å½æ¡£æ¶é´", "è´¹ç¨ç±»å/æ¥éç¶æååå
¸ + Excel 导åº"], |
| | | "features": ["æ¥éå(主表 + 1..n æç»è¡)", "å票é件夿件ä¸ä¼ (éä»¶ä¸å¿å¤æå
³è storage_attachment)", "åå· Redis çæ BX+yyyyMMdd+6使µæ°´Â·æ¯æ¥éç½®", "æç»éä¸»è¡¨ä¸æ¬¡æ§æäº¤(å
å åå¢å
¨éè¦ç)", "BPM 审æ¹(éè¿20/驳å35/åæ¶éåè稿0)", "已驳å坿¹å票åéæ°æäº¤", "彿¡£ç»æ 40 å¹¶è®°å½å½æ¡£æ¶é´", "è´¹ç¨ç±»å/æ¥éç¶æååå
¸ + Excel 导åº", "å¯¹å¤æä¾ FinanceReimbursementApi(yudao-module-finance-api)ä¾è¯¾é¢ç®¡çç»è´¹æ¨ä»èªå¨å»ºåå¹¶æäº¤(1 è¡æç»Â·è´¹ç¨ç±»å=å
¶ä»Â·éé¢ä¸è´)"], |
| | | "objects": ["æ¥éå", "æ¥éæç»"], |
| | | "roles": ["æ¥é人", "è´¢å¡", "审æ¹äºº"], |
| | | "upstream": [], "downstream": [], |
| | | "upstream": ["课é¢ç®¡ç(ç»è´¹æ¨ä» 1:1 èªå¨çææ¥éå·走 yudao-module-finance-api·æ¬å° Bean è°ç¨)"], "downstream": [], |
| | | "coreTables": ["finance_reimbursement", "finance_reimbursement_item"]}, |
| | | {"key": "pro", "name": "ç产管ç", "color": "#e0b34f", "tag": "MES-PRO", "flow": "production", |
| | | "positioning": "ç产æ§è¡æ ¸å¿ï¼è®¡å-å·¥å-ä»»å¡-æ¥å·¥", |
| | |
| | | {"key": "res", "name": "课é¢ç®¡çï¼ç¬ç«ï¼", "color": "#e070a8", "tag": "RES", "flow": "research", |
| | | "positioning": "å¦ä¼/åä¼åç§ç 课é¢å
¨çå½å¨æï¼æååå¸ â å¨çº¿ç³æ¥ â ä¸å®¶è¯å®¡ â ç«é¡¹å®¡æ¹ â ç»è´¹æ¨ä»ï¼ç«é¡¹éç¥èµ°ç³»ç»å
¬åï¼", |
| | | "problem": "è¯¾é¢æåé 线ä¸åå¸ãç³æ¥ä¹¦é 纸质æé®ä»¶æ¶éãä¸å®¶è¯åæ£è½å¨è¡¨æ ¼éæ æ³èªå¨æ±æ»æåãç«é¡¹ä¸æ¨æ¬¾æ çç", |
| | | "features": ["è¯¾é¢æå(éç¹1/ä¸è¬2 åç±»æ æ³¨)", "æåç¶æ 0è稿/20å·²åå¸/30å·²æªæ¢Â·åå¸/æªæ¢ä¸¤ä¸ªå¨ä½", "æåç¼å· GL+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)", "å¨çº¿ç³æ¥ä¹¦(éæå+éä¼å带åºç³æ¥äººä¿¡æ¯+课é¢ç»æå+ç³è¯·ç»è´¹+ç³æ¥ä¹¦æ£æ)", "ç³æ¥ç¼å· SB+åæ¥æµæ°´Â·ç±»å«åä½èªæåä¸ä¿¡ä»»å端", "ç³æ¥ç¶æ 0è稿/15审æ¹ä¸/20å·²ç«é¡¹/35已驳å", "æäº¤åæ ¡éªæåå·²åå¸ä¸å¨ç³æ¥æå
(éæ¡æ¥å
·ä½ç»´åº¦ä¸æ¶é´)", "ä¸å®¶è¯å®¡æç»å表(ä¸ä½ä¸å®¶ä¸è¡Â·åé¡¹å æ 0.3/0.3/0.2/0.2)", "å端èªå¨éç®å æåè®¡ä¸æå·åå主ååå䏿¨èç»è®º", "BPM ä¸çº§å®¡æ¹ research_topic_approve(ç§ä¹¦å¤å½¢å¼å®¡æ¥âä¸å®¶è¯å®¡âå¦ä¼ç«é¡¹å®¡æ¹)", "审æ¹éè¿çæç«é¡¹ç¼å· LX+åæ¥æµæ°´ ä¸ç«é¡¹æ¶é´(å¹ç)", "åå¸ç«é¡¹éç¥(çæ system_notice å
¬å·åå noticeId é²éå¤)", "ç»è´¹æ¨ä»è®°å½(æ¹æ¬¡/éé¢/æ¥æ/æ¶æ¬¾åä½/ç¶æ/åè¯éä»¶)·éé¢ä¸å¾è¶
ç³è¯·ç»è´¹", "éä»¶èµ° system éä»¶ä¸å¿(recordType=research_guideline / research_application / research_fund_record)"], |
| | | "features": ["è¯¾é¢æå(éç¹1/ä¸è¬2 åç±»æ æ³¨)", "æåç¶æ 0è稿/20å·²åå¸/30å·²æªæ¢Â·åå¸/æªæ¢ä¸¤ä¸ªå¨ä½", "æåç¼å· GL+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)", "å¨çº¿ç³æ¥ä¹¦(éæå+éä¼å带åºç³æ¥äººä¿¡æ¯+课é¢ç»æå+ç³è¯·ç»è´¹+ç³æ¥ä¹¦æ£æ)", "ç³æ¥ç¼å· SB+åæ¥æµæ°´Â·ç±»å«åä½èªæåä¸ä¿¡ä»»å端", "ç³æ¥ç¶æ 0è稿/15审æ¹ä¸/20å·²ç«é¡¹/35已驳å", "æäº¤åæ ¡éªæåå·²åå¸ä¸å¨ç³æ¥æå
(éæ¡æ¥å
·ä½ç»´åº¦ä¸æ¶é´)", "ä¸å®¶è¯å®¡æç»å表(ä¸ä½ä¸å®¶ä¸è¡Â·åé¡¹å æ 0.3/0.3/0.2/0.2)", "å端èªå¨éç®å æåè®¡ä¸æå·åå主ååå䏿¨èç»è®º", "BPM ä¸çº§å®¡æ¹ research_topic_approve(ç§ä¹¦å¤å½¢å¼å®¡æ¥âä¸å®¶è¯å®¡âå¦ä¼ç«é¡¹å®¡æ¹)", "审æ¹éè¿çæç«é¡¹ç¼å· LX+åæ¥æµæ°´ ä¸ç«é¡¹æ¶é´(å¹ç)", "åå¸ç«é¡¹éç¥(çæ system_notice å
¬å·åå noticeId é²éå¤)", "ç»è´¹æ¨ä»è®°å½(æ¹æ¬¡/éé¢/æ¥æ/æ¶æ¬¾åä½/夿³¨/åè¯éä»¶)·åè¯å¿
填·éé¢ä¸å¾è¶
ç³è¯·ç»è´¹", "ç»è´¹æ¨ä» 1:1 èªå¨çæå¹¶æäº¤è´¢å¡æ¥éå(FinanceReimbursementApi·1 è¡æç»Â·è´¹ç¨ç±»å=å
¶ä»)", "æ¨ä»ç¶æ 0å¾
æ¨ä»/15æ¥é审æ¹ä¸/20å·²æ¨ä»/30已驳åÂ·ç± BPM çå¬å¨åå(å«é©³ååå 䏿¶é´)", "已驳å坿¹éé¢/åè¯åéæ°åèµ·æ¥é·å¾
æ¨ä»å¯å å¹¶è卿¸
çè´¢å¡ä¾§è稿æ¥éå", "éä»¶èµ° system éä»¶ä¸å¿(recordType=research_guideline / research_application / research_fund_record)"], |
| | | "objects": ["è¯¾é¢æå", "课é¢ç³æ¥ä¹¦", "ä¸å®¶è¯å®¡æç»", "ç»è´¹æ¨ä»è®°å½"], |
| | | "roles": ["课é¢ç³æ¥äºº(ä¼å)", "课é¢ç®¡çå", "è¯å®¡ä¸å®¶", "å¦ä¼ç§ä¹¦å¤", "å¦ä¼çäºä¼"], |
| | | "upstream": ["ä¼å管ç(ums_member åç³æ¥äººå§å/åä½/èç§°/çµè¯)", "BPM(æµç¨å®ä¹ research_topic_approve)"], |
| | | "downstream": ["system(system_notice ç«é¡¹éç¥å
¬å)", "system(éä»¶ä¸å¿)", "è´¢å¡(äºæé¢æå¾
对æ¥Â·ä¸æä¸æ¥)"], |
| | | "roles": ["课é¢ç³æ¥äºº(ä¼å)", "课é¢ç®¡çå", "è¯å®¡ä¸å®¶", "å¦ä¼ç§ä¹¦å¤", "å¦ä¼çäºä¼", "å¦ä¼è´¢å¡"], |
| | | "upstream": ["ä¼å管ç(ums_member åç³æ¥äººå§å/åä½/èç§°/çµè¯)", "BPM(æµç¨å®ä¹ research_topic_approve / finance_reimbursement_approve)"], |
| | | "downstream": ["system(system_notice ç«é¡¹éç¥å
¬å)", "system(éä»¶ä¸å¿)", "è´¢å¡(ç»è´¹æ¨ä»çæ finance_reimbursement æ¥éå·已对æ¥)"], |
| | | "coreTables": ["research_guideline", "research_application", "research_topic_review", "research_fund_record"]}, |
| | | {"key": "bpm", "name": "åå审æ¹", "color": "#e6a23c", "tag": "BPM", "flow": null, |
| | | "positioning": "å
¨ç³»ç»åæ®å®¡æ¹ä¸æ¢ï¼Flowableï¼", |
| | | "problem": "夿¨¡ååæ®éè¦çµæ´»å¯é
çå¤çº§å®¡æ¹", |
| | | "features": ["BPMN+éé飿 ¼å设计å¨", "æµç¨å®ä¹é¨ç½²", "审æ¹äºä»¶ç»ä¸åè°(BpmProcessInstanceStatusEvent)", "14个ä¸å¡çå¬å¨", "表åÂ·ç¨æ·ç»Â·æé·å ç¾"], |
| | | "features": ["BPMN+éé飿 ¼å设计å¨", "æµç¨å®ä¹é¨ç½²", "审æ¹äºä»¶ç»ä¸åè°(BpmProcessInstanceStatusEvent)", "15个ä¸å¡çå¬å¨(å䏿µç¨ key å
许å¤ä¸ªçå¬å¨å¹¶è¡Â·åèªæ key è¿æ»¤)", "表åÂ·ç¨æ·ç»Â·æé·å ç¾"], |
| | | "objects": ["æµç¨æ¨¡å", "æµç¨å®ä¾", "审æ¹ä»»å¡"], |
| | | "roles": ["审æ¹äºº(ææµç¨é
ç½®)", "æµç¨ç®¡çå"], |
| | | "upstream": ["åä¸å¡æäº¤å®¡æ¹"], "downstream": ["åè°æ´æ°åä¸å¡åæ®ç¶æ"], |
| | |
| | | {"name": "æç计å", "module": "设å¤", "table": "mes_cal_plan", "doc": "çç»Ãçæ¬¡Ãæ¥ææçï¼ä¾ç产ä¸èå¤å¼ç¨", "upstream": [], "downstream": ["ç产任å¡", "èå¤"], "keywords": "æç çç» çæ¬¡ æ¥å"}, |
| | | {"name": "æ¥å模æ¿", "module": "è´¨æ£æ¥å", "table": "qc_report_template", "doc": "æºè½è´¨æ£æ¥å模æ¿ï¼å¯ç¨0/åç¨1ï¼ç»å¸å
容åå¨ qc_report_template_versionï¼è稿0/å·²åå¸1/å·²åç¨2ï¼å·²åå¸ä¸å¯è¦çï¼ï¼currentVersion æåå½åå·²åå¸çæ¬ï¼æºæä»¶ç» AI 导å
¥è¯å«æè稿åç±äººå·¥ç¡®è®¤ææä¸ºçæ¬ï¼å䏿¨¡æ¿éå¤å¯¼å
¥æãæ¿æ¢ãå¤çââå
å æ§éä»¶ï¼è¿å¸¦ blob è¡ä¸ç£çæä»¶ï¼åç»æ°çï¼ä¸çå¤å¿æä»¶ï¼å 餿¨¡æ¿ä¼è¿å¸¦æ¸
éä»¶", "upstream": ["人工设计(GrapesJS 设计å¨)", "AI 导å
¥è稿(qc-report/ai-import/draft)"], "downstream": ["模æ¿çæ¬", "æ¥åå®ä¾"], "keywords": "æ¥åæ¨¡æ¿ è´¨æ£æ¥å template è®¾è®¡å¨ çæ¬ AI导å
¥ è¯å« è稿 æºæä»¶æ¿æ¢"}, |
| | | {"name": "æ¥åå®ä¾", "module": "è´¨æ£æ¥å", "table": "qc_report_instance", "doc": "åºä»¶äº§ç©ï¼ç¼å· QR+yyyyMMdd+4使µæ°´æå¤©ç¬ç«ä¸ä¸å¡å¯ä¸ï¼å¯æ¾å¼æå®è¦çï¼æ³¨æ uk_report_no ä¸åºå软å é¤ï¼å æçå·ä¸åæ¶ï¼ï¼ä¸¤æ¡åºä»¶å
¥å£ï¼éç¨ generateï¼è°ç¨æ¹èªå¸¦ contextï¼ä¸ generate-from-qcï¼æ°æ®ä» MES è´¨æ£ååï¼æéç qc-report:instance:generate å·²å
¥ system_menu id=1075416ï¼äºéæ ¡éªæä¸å¡ä¼å
çº§åªæ¥ç¬¬ä¸å¤ï¼105_000 ç±»åéæ³ / 105_001 åæ®ä¸åå¨ / 105_002 æªå®æ / 105_003 æªå¤å® / 105_005 模æ¿ç±»åä¸ç¬¦ / 105_006 æ å¯ç¨æ£éªé¡¹ï¼åå¼ è´¨æ£åå表çè¡æä½ãåºæ¥åãä»
å¨ status=已宿æ¶å¯è§ï¼å¼¹çªåªå reportType ä¸è´ã模æ¿å¯ç¨ãä¸ currentVersion æåççæ¬å·²åå¸ç模æ¿ï¼å端 /qc-report/template/selectable å¤å®ââåç¨çæ¬ä¸æ¸
空 currentVersionï¼å端æ¿åé¡µç»æèªå·±æ¨å¯¼ä¼æ¼ï¼ï¼ç»æå°±å°å±ç¤ºå¹¶è·³æ¬é¡µå表ï¼ï¼å»ç» data_snapshotï¼å¤å®åæ°æ®ï¼å«å端ç®å¥½ç PASS/FAIL ä¸åæ ¼çï¼ä¸ render_htmlï¼regenerate åªé渲æçãæ°æ®ä¸ç¼å·ä¸åï¼business_id/business_type å MES 表åï¼mes_qc_iqc çï¼ä¸åæ® IDï¼å¯åæ¥ãä¸åå¯åºå¤ä»½ï¼æ¥å头å¦å¸¦åæ®åå¤å® qcResult(æ°)/qcResultText(䏿ï¼åæ ¼/ç¹é/ä¸åæ ¼éè´§/ä¸åæ ¼æ¥åº)ï¼ä¸å¼æä¸æå¤å®å¹¶åäºä¸è¦çï¼ååºå¸¦ undecidableCount=å¿«ç
§ä¸ result 为空串ç项æ°ä¸ warningsï¼åç»æ é¢è·³è¿/ææ å·²å /æªå½å®æµå¼/æ ·åè¶
3ï¼ï¼ä¸¤è
é½ä¸è½åºãäºåçä¸å°", "upstream": ["æ¥å模æ¿çæ¬", "è´¨æ£åä¸ä¸æ(éç¨ generate ç±è°ç¨æ¹ä¼ å
¥)", "MES è´¨æ£å IQC/IPQC/OQC/RQC(generate-from-qc ç» MesQcReportApi åæ°)"], "downstream": ["å端å®ä¾é¡µ /qc/report-instance(å表·iframeé¢è§Â·å¿«ç
§é¡µç¾Â·å¯¼åºPDF)", "PDF彿¡£(system_storage_attachment recordType=qc_report_instance)"], "keywords": "æ¥åå®ä¾ åºä»¶ QRç¼å· å¿«ç
§ å¤ç° regenerate PDF彿¡£ æ¥åå®ä¾é¡µ 导åºPDF generate-from-qc è´¨æ£ååºæ¥å åºæ¥åå¼¹çª qcResult undecidableCount warnings å¾
å¤å® 忥 ä¸å¡åæ®çé"}, |
| | | {"name": "æ¥éå", "module": "è´¢å¡æ¥é", "table": "finance_reimbursement", "doc": "åå·å¯èªå®ä¹(ä¸é´ä¸å
è®¸ç©ºæ ¼ï¼ä¸å·²æåå·éå¤åæ¥é)ï¼æ°å¢æ¶ç空æçº¯ç©ºæ ¼ç±ç³»ç»çæ BX+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼ä¿®æ¹æ¶çç©ºè¡¨ç¤ºä¿æä¸åãstatus: 0è稿/15审æ¹ä¸/20å·²éè¿/35已驳å/40已彿¡£ï¼ä»
è稿å¯å ãè稿ä¸å·²é©³å坿¹ãä»
å·²éè¿å¯å½æ¡£ï¼æäº¤åç± BPM çå¬å¨æç»æååç¶æ(åæ¶éåè稿)ï¼å®¡æ¹ä¸ processInstanceId 被ååï¼ç¬ç«æ¨¡åï¼ä¸ä¸å
¶å®ä¸å¡æ¨¡å产çåæ®å
³è", "upstream": [], "downstream": ["æ¥éæç»", "å票éä»¶(storage_attachment·recordType=finance_reimbursement)"], "keywords": "æ¥éå æ¥é å票 reimbursement BX 彿¡£ è´¢å¡ è´¹ç¨ èªå®ä¹åå·"}, |
| | | {"name": "æ¥éå", "module": "è´¢å¡æ¥é", "table": "finance_reimbursement", "doc": "åå·å¯èªå®ä¹(ä¸é´ä¸å
è®¸ç©ºæ ¼ï¼ä¸å·²æåå·éå¤åæ¥é)ï¼æ°å¢æ¶ç空æçº¯ç©ºæ ¼ç±ç³»ç»çæ BX+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼ä¿®æ¹æ¶çç©ºè¡¨ç¤ºä¿æä¸åãstatus: 0è稿/15审æ¹ä¸/20å·²éè¿/35已驳å/40已彿¡£ï¼ä»
è稿å¯å ãè稿ä¸å·²é©³å坿¹ãä»
å·²éè¿å¯å½æ¡£ï¼æäº¤åç± BPM çå¬å¨æç»æååç¶æ(åæ¶éåè稿)ï¼å®¡æ¹ä¸ processInstanceId 被ååãæ¥æºä¸¤æ¡ï¼â è´¢å¡æ¨¡å页é¢äººå·¥å¡«æ¥ â¡è¯¾é¢ç®¡çãç»è´¹æ¨ä»ãç» FinanceReimbursementApi(yudao-module-finance-api)èªå¨å»ºåå¹¶ç«å³æäº¤(1:1ãéé¢ä¸è´ãç³»ç»åºå® 1 è¡æç»Â·è´¹ç¨ç±»å=å
¶ä»)ââåè
ç审æ¹ç»æç±è¯¾é¢ä¾§ ResearchFundStatusListener 订é
å䏿µç¨ååæ¨æ¬¾å°è´¦ï¼æ¥éåæ¬èº«ä¸ååä»»ä½å¤é¨åæ®", "upstream": ["课é¢ç®¡ç(ç»è´¹æ¨ä»Â·ç» FinanceReimbursementApi èªå¨å»ºå)", "人工填æ¥"], "downstream": ["æ¥éæç»", "å票éä»¶(storage_attachment·recordType=finance_reimbursement)", "è¯¾é¢æ¨æ¬¾å°è´¦(ä»
ç» BPM äºä»¶ååç¶æ)"], "keywords": "æ¥éå æ¥é å票 reimbursement BX 彿¡£ è´¢å¡ è´¹ç¨ èªå®ä¹åå· è¯¾é¢ç»è´¹æ¨ä» èªå¨å»ºå FinanceReimbursementApi"}, |
| | | {"name": "æ¥éæç»", "module": "è´¢å¡æ¥é", "table": "finance_reimbursement_item", "doc": "æ¥éåçè´¹ç¨è¡ï¼è´¹ç¨ç±»å(1å·®æ
/2åå
¬/3æå¾
/4交é/5å
¶ä»)ãå票å·ç ãå票éé¢ãåç¥¨æ¥æãå¼ç¥¨æ¹ãè´¹ç¨è¯´æï¼éä¸»è¡¨ä¸æ¬¡æ§æäº¤(å
å åå¢å
¨éè¦ç)ï¼æäº¤æ¶å¿
é¡»å¥æè¡ id ä¸ reimbursementId ââ æç»å 餿¯è½¯å ï¼åä¼ å id ä¼ä¸å·²è½¯å è¡ä¸»é®å²çª", "upstream": ["æ¥éå"], "downstream": [], "keywords": "æ¥éæç» è´¹ç¨æç» è´¹ç¨ç±»å å票éé¢ item æç»è¡ å·®æ
"}, |
| | | {"name": "å
¥ä¼ç³è¯·å", "module": "ä¼å管ç", "table": "ums_application", "doc": "åå· SQ+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼å端çæä¸å¯èªå®ä¹ï¼memberType 1个人/2åä½å³å®å段åå(ä¸ªäººç¨ workUnit/titleï¼åä½ç¨ legalPerson/organizationCode)ï¼memberGrade æç±»ååä¸ååå
¸ï¼status: 0è稿/15审æ¹ä¸/20å·²éè¿/35已驳åãä»
è稿å¯å (è¿å¸¦æ¸
éä»¶)ãè稿ä¸å·²é©³å坿¹å¯éæï¼æäº¤åç± BPM çå¬å¨æç»æåå(åæ¶éåè稿)ï¼å®¡æ¹ä¸åå processInstanceIdï¼å®¡æ¹éè¿è§¦åèªå¨å»ºä¼åä¸ç³»ç»è´¦å·ãç¬ç«æ¨¡åï¼ä¸ä¸å
¶å®ä¸å¡æ¨¡å产çåæ®å
³è", "upstream": ["人工填æ¥(ç³è¯·äºº)", "è¯æææéä»¶(storage_attachment·recordType=ums_application)"], "downstream": ["ä¼å(审æ¹éè¿èªå¨å建)", "BPM æµç¨å®ä¾(ums_membership_approve åç±»)"], "keywords": "å
¥ä¼ç³è¯· å
¥ä¼ ä¼åç³è¯· application SQ ç§ä¹¦å¤ çäºä¼ å®¡æ¹ ä¼åç±»å 个人 åä½ æ³å®ä»£è¡¨äºº ç ç©¶æ¹å ç³è¯·ç级"}, |
| | | {"name": "ä¼å", "module": "ä¼å管ç", "table": "ums_member", "doc": "åå· HY+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼ä¸¤ä¸ªæ¥æºï¼â å
¥ä¼ç³è¯·å®¡æ¹éè¿èªå¨å建(åå¡« applicationId ä¸ userName/ç³»ç»è´¦å·) â¡ä¼åå表æå·¥æ°å¢ãstatus: 1æ£å¸¸/0æåï¼memberGrade æ memberType å对åºåå
¸ï¼æ ¡éªè§åæ¯åä½ä¼å(type=2)ä¸å¯éãçäºé¿ã(grade=5)ãèªå¨å»ºæ¡£æ¶å
¥ä¼æ¥æ=å½å¤©ã䏿¬è¿ contactUser/unitIntro/expireDate(ç³è¯·åæ 对åºå段)ï¼èªå¨å»ºçç³»ç»è´¦å·ç¨æ·å为èç³»çµè¯ä¸åå§å¯ç å为èç³»çµè¯ï¼é¨é¨åºå®ä¸ºãå¦ä¼ä¼åãï¼ææºå·éå¤ä¼æç¡®æ¥é䏿´åäºå¡åæ»", "upstream": ["å
¥ä¼ç³è¯·å(审æ¹éè¿)", "人工æ°å¢", "éä»¶(storage_attachment·recordType=ums_member)"], "downstream": ["ä¼åé讯å½(æ regionCode/industry æ£ç´¢)", "system_users(ç»å½è´¦å·)"], "keywords": "ä¼å member HY ä¼åç¼å· ä¼åç级 ä¼åç±»å éè®¯å½ å°åº è¡ä¸ å
¥ä¼æ¥æ æææ"}, |
| | | {"name": "è¯¾é¢æå", "module": "课é¢ç®¡ç", "table": "research_guideline", "doc": "æåç¼å· GL+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼category 1éç¹è¯¾é¢/2ä¸è¬è¯¾é¢ï¼publishStatus 0è稿/20å·²åå¸/30å·²æªæ¢ï¼ä»
èç¨¿å¯æ¹å¯å ï¼publish åå¸åå publishTimeï¼close æªæ¢ç½® 30ï¼å·²äº§çç³æ¥å(applicationMapper.selectCountByGuidelineId å¤§äº 0)çæåç¦æ¢å é¤å¹¶å¨æç¤ºä¸æ¥åºè¯¥æåä¸å·²æå¤å°å¼ ç³æ¥åï¼æ£æ content ä¸ºé¿ææ¬ï¼éä»¶ recordType=research_guideline", "upstream": ["人工维æ¤(å¦ä¼ç§ä¹¦å¤)", "æåéä»¶(storage_attachment·recordType=research_guideline)"], "downstream": ["课é¢ç³æ¥ä¹¦(ç³æ¥æ¶å¼ç¨ä¸å¿
须已åå¸å¹¶å¨ç³æ¥æå
)"], "keywords": "è¯¾é¢æå æå åå¸ æªæ¢ éç¹è¯¾é¢ ä¸è¬è¯¾é¢ GL æåç¼å· ç³æ¥æ ç³æ¥èµ·æ¢"}, |
| | | {"name": "课é¢ç³æ¥ä¹¦", "module": "课é¢ç®¡ç", "table": "research_application", "doc": "ç³æ¥ç¼å· SB+yyyyMMdd+6使µæ°´(Redis æ¯æ¥éç½®)ï¼guidelineId å
³èæåãmemberId å
³è ums_member(软å
³èæ å¤é®ï¼ä¼åå é¤åä¼ç䏿¬ç©º memberId éå®¹éæ¾ç¤º)ï¼applicantName/workUnit/jobTitle/contactPhone/contactEmail ç±éä¼åèªå¨å¸¦åºå¯ææ¹ï¼category åä½èªæåä¸ä¸ä¿¡ä»»åç«¯ä¼ å¼ï¼budgetAmount ç³è¯·ç»è´¹ä¸ºæ¨ä»ä¸éï¼status: 0è稿/15审æ¹ä¸/20å·²ç«é¡¹/35已驳åãä»
è稿å¯å (è¿å¸¦æ¸
éä»¶)ãè稿ä¸å·²é©³å坿¹å¯éæï¼submit åéæ¡æ ¡éªãæåå·²åå¸ãä¸ãç°å¨å¨ç³æ¥æå
ãï¼ä»»ä¸ä¸æ»¡è¶³å³æç»å¹¶æç»´åº¦ç»åºæååä¸å®é
å¼ï¼å®¡æ¹éè¿ç±çå¬å¨çæç«é¡¹ç¼å· researchNo(LX+åæ¥æµæ°´)ä¸ approveTime(å·²æç¼å·å¹çè·³è¿)ï¼reviewAvgScore/reviewPass 为è¯å®¡æ±æ»ååå¼ï¼æç»å ç©ºæ¶æ¸
ææªæ±æ»ï¼noticeId è®°å½å·²åå¸çç«é¡¹éç¥å
¬åï¼éå¤åå¸è¢«æ¦æª", "upstream": ["è¯¾é¢æå(å¿
须已åå¸ä¸å¨ç³æ¥æå
)", "ä¼å(ums_member·带åºç³æ¥äººä¿¡æ¯)", "ç³æ¥éä»¶(storage_attachment·recordType=research_application)"], "downstream": ["ä¸å®¶è¯å®¡æç»", "ç»è´¹æ¨ä»è®°å½", "ç«é¡¹éç¥(system_notice å
¬å)", "BPM æµç¨å®ä¾(research_topic_approve åç±»)", "éä»¶ä¸å¿"], "keywords": "课é¢ç³æ¥ ç³æ¥ä¹¦ ç³æ¥å SB ç³æ¥ç¼å· ç«é¡¹ ç«é¡¹ç¼å· LX ç³è¯·ç»è´¹ ç³æ¥ä¹¦æ£æ 课é¢ç»æå ä¸å®¶è¯å®¡ è¯å®¡æ±æ» ç«é¡¹éç¥ åå¸éç¥ æäº¤å®¡æ¹ 驳å éæ"}, |
| | | {"name": "ä¸å®¶è¯å®¡æç»", "module": "课é¢ç®¡ç", "table": "research_topic_review", "doc": "ä¸ä½ä¸å®¶ä¸è¡çä¸ä¸»å¤è¡å表ï¼evaluatorName/evaluatorUnit/evaluatorTitle + topicScore éé¢ä»·å¼ä¸æä¹(æé0.3) + planScore ç ç©¶æ¹æ¡å¯è¡æ§(0.3) + teamScore å¢éä¸ç ç©¶åºç¡(0.2) + resultScore 颿ææä¸æç(0.2) + conclusion 1æ¨èç«é¡¹/2䏿¨èç«é¡¹ + opinion è¯å®¡æè§ + reviewTimeãcompositeScore ç±å端 weightedScore 计ç®ãranking ç±å端æå æåéåºéæï¼å䏿¥ååç«¯ä¼ å¼ï¼æ¯æ¬¡å¢å æ¹åè° recalculate åå主å reviewAvgScore(å
¨é¨ä¸å®¶å æååå¼Â·ä¿ç2ä½)ä¸ reviewPass(ååè¾¾æ ä¸ å¤æ°ç»è®ºä¸ºæ¨èç«é¡¹æ¶ä¸º 1)ï¼å项åå¼è¶
åº 0~100 æ¶æç¤ºæåºå
·ä½ç»´åº¦ä¸å®é
å¼ï¼ä»
å¨ç³æ¥å status=15 审æ¹ä¸å¯å¢å æ¹", "upstream": ["课é¢ç³æ¥ä¹¦(ä»
审æ¹ä¸å¯å)"], "downstream": ["课é¢ç³æ¥ä¹¦(åå reviewAvgScore/reviewPass)"], "keywords": "ä¸å®¶è¯å®¡ è¯å®¡æç» è¯å å æ æé æå ranking compositeScore æ¨èç«é¡¹ è¯å®¡æè§ åå"}, |
| | | {"name": "ç»è´¹æ¨ä»è®°å½", "module": "课é¢ç®¡ç", "table": "research_fund_record", "doc": "ä¸ä¸»å¤è¡çæ¨æ¬¾è®°å½ï¼batchName æ¹æ¬¡åç§°/amount æ¨ä»éé¢/payDate æ¨ä»æ¥æ/payee æ¶æ¬¾åä½/status 0å¾
æ¨ä» 20å·²æ¨ä»/remarkï¼åè¯éä»¶èµ° system éä»¶ä¸å¿ recordType=research_fund_record(表å
ä¸åæä»¶å°å)ãä»
ç³æ¥å status=20 å·²ç«é¡¹å¯ç»è®°ï¼é颿 ¡éªï¼å·²ç»è®°éé¢(该åå
¨é¨è®°å½æ±å) + æ¬æ¬¡éé¢ ä¸å¾è¶
åºç³æ¥å budgetAmountï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ï¼status=20 å·²æ¨ä» æ¶åè¯éä»¶å¿
å¡«(å端å
è¡æ¦æªï¼å端 validateVoucherRequired å
åº)ï¼ä»
å¾
æ¨ä»ç¶æå¯æ¹å¯å ï¼ç¼è¾æ¶ææ¬è¡éé¢å åå¯ç¨ä½é¢å±ç¤ºé¿å
误解", "upstream": ["课é¢ç³æ¥ä¹¦(å¿
须已ç«é¡¹)"], "downstream": ["æ¨ä»åè¯(storage_attachment·recordType=research_fund_record)", "è´¢å¡(äºæé¢æå¾
对æ¥Â·ä¸æä¸æ¥)"], "keywords": "ç»è´¹æ¨ä» æ¨æ¬¾ æ¨ä»è®°å½ æ¹æ¬¡ æ¨ä»éé¢ åè¯ å¾
æ¨ä» å·²æ¨ä» æ¶æ¬¾åä½ èµå©éé¢ é¢ç® è¶
é¢"} |
| | | {"name": "ç»è´¹æ¨ä»è®°å½", "module": "课é¢ç®¡ç", "table": "research_fund_record", "doc": "ä¸ä¸»å¤è¡çæ¨æ¬¾å°è´¦ï¼batchName æ¹æ¬¡åç§°/amount æ¨ä»éé¢/payDate æ¨ä»æ¥æ/payee æ¶æ¬¾åä½/remarkï¼åè¯éä»¶èµ° system éä»¶ä¸å¿ recordType=research_fund_record(表å
ä¸åæä»¶å°å)ãstatus: 0å¾
æ¨ä»/15æ¥é审æ¹ä¸/20å·²æ¨ä»/30已驳åï¼ç±ç³»ç»ä¸ BPM 驱å¨ï¼æ°å¢/ä¿®æ¹æ¥å£å·²ç§»é¤ status å
¥å(é²ä¼ªé ãå·²æ¨ä»ã)ãç»è®°å³ä¸æ¡é¾ï¼è½å°è´¦ â å䏿¹ blob åç» â ç» FinanceReimbursementApi èªå¨çæ 1:1 ç finance_reimbursement å¹¶ç«å³æäº¤ BPM â åå reimbursement_id/reimbursement_no å¹¶ç½® 15ï¼å®¡æ¹ç»æç±çå¬å¨ååï¼éè¿â20ã驳åâ30(+reject_reason/reject_time)ãæ¤åæåæ¶âéå 0ãä»
ç³æ¥å status=20 å·²ç«é¡¹å¯ç»è®°ï¼åè¯å¿
å¡«ï¼é颿 ¡éªï¼å·²ç»è®°éé¢(该åå
¨é¨è®°å½æ±å) + æ¬æ¬¡éé¢ ä¸å¾è¶
åºç³æ¥å budgetAmountï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ï¼ä»
ãå¾
æ¨ä»ãå¯å (èå¨å é¤è´¢å¡ä¾§è稿æ¥éåï¼éè稿åæç»)ï¼ãå¾
æ¨ä»ãã已驳åã坿¹å¹¶éæ°åèµ·æ¥é(已驳忹忏
空 reject_reason/reject_time)ï¼ç¼è¾æ¶ææ¬è¡éé¢å åå¯ç¨ä½é¢å±ç¤ºé¿å
误解ã䏿¥éå为软å
³è(æ å¤é®)ï¼è´¢å¡ä¾§ç´æ¥å åä¼ç䏿¬ç©º reimbursement_idï¼æ¤æ¶ä¿®æ¹æ¥ãæ¥éåå·²ä¸åå¨ï¼è¯·å 餿¬æ¡è®°å½åéæ°ç»è®°ã", "upstream": ["课é¢ç³æ¥ä¹¦(å¿
须已ç«é¡¹)", "è´¢å¡æ¥éå(1:1 èªå¨çæÂ·è½¯å
³è reimbursement_id)"], "downstream": ["æ¨ä»åè¯(storage_attachment·recordType=research_fund_record)", "è´¢å¡æ¥éå(çæå¹¶æäº¤åºè´¦Â·å®¡æ¹ç»æå忬å°è´¦)"], "keywords": "ç»è´¹æ¨ä» æ¨æ¬¾ æ¨ä»è®°å½ æ¹æ¬¡ æ¨ä»éé¢ åè¯ å¾
æ¨ä» æ¥é审æ¹ä¸ å·²æ¨ä» 已驳å 驳ååå è´¢å¡æ¥éåå· reimbursement_id æ¶æ¬¾åä½ èµå©éé¢ é¢ç® è¶
é¢ éæ°åèµ·æ¥é"} |
| | | ] |
| | | }</script> |
| | | <script type="application/json" id="data-flows">{ |
| | |
| | | {"stage": "建档", "action": "审æ¹éè¿é©åèªå¨å»ºä¼åï¼â çæä¼åç¼å· HY+yyyyMMdd+6使µæ°´ â¡AdminUserApi.createUser 建系ç»è´¦å·ï¼ç¨æ·åä¸åå§å¯ç =èç³»çµè¯ãæµç§°=ç³è¯·äººå§åãé¨é¨=å¦ä¼ä¼åï¼â¢ä¼åè½åºï¼å
¥ä¼æ¥æ=å½å¤©ãç¶æ 1 æ£å¸¸ãapplicationId åå¡«æ¥æºç³è¯·åï¼ï¼ææºå·éå¤ä¼æç¡®æ¥é", "roles": ["ç³»ç»èªå¨"]}, |
| | | {"stage": "管ç䏿£ç´¢", "action": "ä¼ååè¡¨æ¯ææå·¥æ°å¢/ç¼è¾/å é¤ï¼ç级ä¸ç±»åæ ¡éªï¼åä½ä¼åä¸å¯éãçäºé¿ãï¼ï¼ä¼åé讯å½ä¸ºåªè¯»é¡µï¼æå°åºç¼ç ä¸è¡ä¸æ£ç´¢", "roles": ["ä¼å管çå", "å
¨ä½å¯æ¥é讯å½"]}]}, |
| | | {"id": "research", "name": "课é¢ç®¡çæµç¨", "mermaid": "mermaid/14-research-flow.mmd", "color": "#e070a8", |
| | | "summary": "ç¬ç«ç§ç 模åï¼yudao-module-researchï¼ï¼å¦ä¼åå¸è¯¾é¢æåï¼éç¹/ä¸è¬åç±»ï¼â ä¼åå¨çº¿æäº¤è¯¾é¢ç³æ¥ä¹¦ â æäº¤ BPM ä¸çº§å®¡æ¹ï¼ç§ä¹¦å¤å½¢å¼å®¡æ¥ â ä¸å®¶è¯å®¡ â å¦ä¼ç«é¡¹å®¡æ¹ï¼ï¼ä¸å®¶è¯åä»¥ç»æåæç»å表记å½å¹¶ç±å端èªå¨æ±æ»å æååãæå䏿¨èç»è®º â 审æ¹éè¿çæç«é¡¹ç¼å·å¹¶åå¸ç³»ç»å
¬å â ææ¹æ¬¡ç»è®°ç»è´¹æ¨ä»è®°å½ï¼å«åè¯éä»¶ï¼ãé¢çº§äºæåè¡¥ç»é¡¹éªæ¶ä¸ææå½æ¡£ã", |
| | | "summary": "ç¬ç«ç§ç 模åï¼yudao-module-researchï¼ï¼å¦ä¼åå¸è¯¾é¢æåï¼éç¹/ä¸è¬åç±»ï¼â ä¼åå¨çº¿æäº¤è¯¾é¢ç³æ¥ä¹¦ â æäº¤ BPM ä¸çº§å®¡æ¹ï¼ç§ä¹¦å¤å½¢å¼å®¡æ¥ â ä¸å®¶è¯å®¡ â å¦ä¼ç«é¡¹å®¡æ¹ï¼ï¼ä¸å®¶è¯åä»¥ç»æåæç»å表记å½å¹¶ç±å端èªå¨æ±æ»å æååãæå䏿¨èç»è®º â 审æ¹éè¿çæç«é¡¹ç¼å·å¹¶åå¸ç³»ç»å
¬å â ææ¹æ¬¡ç»è®°ç»è´¹æ¨ä»ï¼åè¯å¿
å¡«ï¼ï¼æ¯æ¡æ¨æ¬¾è®°å½èªå¨çæå¹¶æäº¤ä¸å¼ 1:1 çè´¢å¡æ¥éåï¼finance_reimbursementï¼ï¼èµ° BPM 两级审æ¹åç±çå¬å¨æç»æååå°è´¦ãé¢çº§äºæåè¡¥ç»é¡¹éªæ¶ä¸ææå½æ¡£ã", |
| | | "steps": [ |
| | | {"stage": "å叿å", "action": "æ°å»ºæåéç±»å« 1éç¹è¯¾é¢ / 2ä¸è¬è¯¾é¢ï¼å¡«ç³æ¥èµ·æ¢æ¶é´ä¸æåæ£æï¼ç¼å· GL+yyyyMMdd+6使µæ°´ï¼Redis æ¯æ¥éç½®ï¼ï¼status: 0è稿/20å·²åå¸/30å·²æªæ¢ãä»
èç¨¿å¯æ¹å¯å ï¼åå¸åå³å»ç»ï¼å·²äº§çç³æ¥åçæåç¦æ¢å é¤ï¼æç¤ºè¯¥æåä¸å·²æ N å¼ ç³æ¥åï¼", "roles": ["å¦ä¼ç§ä¹¦å¤", "课é¢ç®¡çå"]}, |
| | | {"stage": "å¨çº¿ç³æ¥", "action": "ä»å·²åå¸ä¸å¨ç³æ¥æå
çæåæ°å»ºç³æ¥ä¹¦ï¼éä¼åï¼ums_memberï¼èªå¨å¸¦åºå§å/å·¥ä½åä½/èç§°/èç³»çµè¯/é®ç®±ï¼å¯æ¹ï¼å¡«è¯¾é¢åç§°ã课é¢ç»æåãç³è¯·ç»è´¹ãç³æ¥ä¹¦æ£æï¼ç¼å· SB+yyyyMMdd+6使µæ°´ï¼ç±»å«åä½èªæåï¼ä¸ä¿¡ä»»åç«¯ä¼ å¼ï¼status: 0è稿", "roles": ["课é¢ç³æ¥äººï¼ä¼åï¼", "课é¢ç®¡çå"]}, |
| | |
| | | {"stage": "ä¸å®¶è¯å®¡", "action": "ç³æ¥åå¤äºå®¡æ¹ä¸(15)æ¶å½å
¥ä¸å®¶è¯åæç»ï¼ä¸ä½ä¸å®¶ä¸è¡ï¼å§å/åä½/èç§° + éé¢ä»·å¼0.3/ç ç©¶æ¹æ¡0.3/å¢éåºç¡0.2/颿ææ0.2 å项åå¼ + ç»è®º + æè§ï¼ï¼åç«¯æ¯æ¬¡å¢å æ¹åéç® compositeScore å æå计ãæå æåéåºéæ rankingï¼å¹¶åå主å reviewAvgScoreï¼å
¨é¨ä¸å®¶ååï¼ä¸ reviewPassï¼ååè¾¾æ ä¸å¤æ°ç»è®ºä¸ºæ¨èç«é¡¹ï¼ï¼æç»å
¨é¨å 餿¶æ±æ»å¼æ¸
ç©ºä¸ºæªæ±æ»ï¼å项åå¼åå¨ 0~100 ä¹å¤æ¶æç¤ºæåºå
·ä½ç»´åº¦ä¸å®é
å¼", "roles": ["è¯å®¡ä¸å®¶", "å¦ä¼ç§ä¹¦å¤", "课é¢ç®¡çå"]}, |
| | | {"stage": "ç«é¡¹å®¡æ¹", "action": "BPM æµç¨ research_topic_approve 顺åºèµ°ä¸èç¹ï¼ç§ä¹¦å¤å½¢å¼å®¡æ¥ â ä¸å®¶è¯å®¡ â å¦ä¼ç«é¡¹å®¡æ¹ãå®¡æ¹æ¹æ³ä¸å®¡æ¹äººå¨æµç¨å®ä¹å
é
ç½®ï¼é¨ç½²åç±ç®¡çåå¨ BPM æµç¨è®¾è®¡å¨æå¦ä¼å®é
ç»ç»è°æ´ï¼å®¡æ¹ä¸å¿å
çèªå®ä¹è¡¨ååªè¯»åæ¾ç³æ¥å + è¯å®¡æç» + æ¨ä»è®°å½ãéè¿â20 å·²ç«é¡¹ã驳åâ35 已驳åãåæ¶âéå 0 è稿", "roles": ["å¦ä¼ç§ä¹¦å¤ï¼å½¢å¼å®¡æ¥ï¼", "è¯å®¡ä¸å®¶ï¼è¯å®¡èç¹ï¼", "å¦ä¼çäºä¼ï¼ç«é¡¹å®¡æ¹ï¼"]}, |
| | | {"stage": "ç«é¡¹ä¸éç¥", "action": "çå¬å¨ ResearchApplicationStatusListener å
åå审æ¹ç¶æï¼å®¡æ¹éè¿ååè° approveApplicationï¼çæç«é¡¹ç¼å· LX+yyyyMMdd+6使µæ°´ ä¸ approveTimeï¼å·²æç¼å·åå¹çè·³è¿ï¼ãç¹ãåå¸ç«é¡¹éç¥ãçæ system_notice å
¬åï¼æ é¢ãå
³äºå
¬å¸ç«é¡¹è¯¾é¢çéç¥ãï¼æ£æå«è¯¾é¢å/ç«é¡¹ç¼å·/ç±»å«/ç³æ¥äºº/åä½/èµå©éé¢ï¼ï¼åå noticeId é²éå¤ââéå¤ç¹å»æå·²å叿¦æªå¹¶åç¥ä¸æ¬¡å叿¶é´", "roles": ["课é¢ç®¡çå", "å¦ä¼ç§ä¹¦å¤"]}, |
| | | {"stage": "ç»è´¹æ¨ä»", "action": "ä»
ãå·²ç«é¡¹(20)ãçç³æ¥åå¯ç»è®°æ¨æ¬¾è®°å½ï¼æ¹æ¬¡åç§°/æ¨ä»éé¢/æ¨ä»æ¥æ/æ¶æ¬¾åä½/ç¶æ/夿³¨/åè¯éä»¶ï¼ï¼é颿 ¡éªï¼å·²ç»è®°éé¢ + æ¬æ¬¡éé¢ ä¸å¾è¶
åºè¯¥åç³è¯·ç»è´¹ï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ï¼status: 0å¾
æ¨ä»/20å·²æ¨ä»ï¼åè¯æç»èµ° system éä»¶ä¸å¿ recordType=research_fund_recordï¼ç¶ææ¹ä¸ºå·²æ¨ä»æ¶åè¯å¿
å¡«ï¼ä»
å¾
æ¨ä»ç¶æå¯æ¹å¯å ï¼ç¼è¾æ¶ä¼ææ¬è¡éé¢å åä½é¢æ¾ç¤º", "roles": ["å¦ä¼è´¢å¡", "课é¢ç®¡çå"]}]}, |
| | | {"stage": "ç»è´¹æ¨ä»", "action": "ä»
ãå·²ç«é¡¹(20)ãçç³æ¥åå¯ç»è®°æ¨æ¬¾è®°å½ï¼æ¹æ¬¡åç§°/æ¨ä»éé¢/æ¨ä»æ¥æ/æ¶æ¬¾åä½/夿³¨/åè¯éä»¶ï¼ï¼åè¯å¿
å¡«ãç»è®°æ¶ä¸æ¡é¾å®æï¼â 课é¢ä¾§è½ research_fund_record å°è´¦ï¼å
ç½®å¾
æ¨ä»ï¼â¡ å䏿¹ blob åç»å°è¯¾é¢å°è´¦ä¸è´¢å¡æ¥éå â¢ ç» yudao-module-finance-api èªå¨çæ 1:1 ç finance_reimbursement æ¥éåï¼1 è¡æç»ï¼è´¹ç¨ç±»å=å
¶ä»ãå票éé¢=æ¨ä»éé¢ãåç¥¨æ¥æ=æ¨ä»æ¥æãè´¹ç¨è¯´æ=ã课é¢ã课é¢åã第Næ/第N次ç»è´¹æ¨æ¬¾ãï¼â£ ç«å³æäº¤ BPM æ¥éå®¡æ¹ â¤ å°è´¦å忥éåå·å¹¶ç½®ãæ¥é审æ¹ä¸(15)ããé颿 ¡éªï¼å·²ç»è®°éé¢ + æ¬æ¬¡éé¢ ä¸å¾è¶
åºè¯¥åç³è¯·ç»è´¹ï¼è¶
åºæ¶æç¤ºæ¥åºæ¬æ¬¡ãå·²ç»è®°ãå计ãé¢ç®å项æ°å¼ãç¶æç±ç³»ç»é©±å¨ï¼0å¾
æ¨ä»/15æ¥é审æ¹ä¸/20å·²æ¨ä»/30已驳åï¼åªæãå¾
æ¨ä»ãå¯å ï¼å é¤è卿¸
çè´¢å¡ä¾§è稿æ¥éåï¼ï¼ãå¾
æ¨ä»ãã已驳åã坿¹å¹¶éæ°åèµ·æ¥éï¼å·²é©³åæ¹åæ¸
空驳ååå 䏿¶é´ï¼ï¼è´¢å¡ç«¯æ¤åæåæ¶åéåãå¾
æ¨ä»(0)ããè´¢å¡å®¡æ¹åç±»ä¸æ²¡æå·²å叿µç¨æ¶ç´æ¥æ¥éä¸ä¸å»ºåï¼ä¸çå¤å¿è稿æ¥éå", "roles": ["å¦ä¼è´¢å¡", "课é¢ç®¡çå", "è´¢å¡å®¡æ ¸äºº", "è´¢å¡ä¸»ç®¡"]}]}, |
| | | {"id": "ai", "name": "AI ä¸å¡æµç¨", "mermaid": "mermaid/11-ai-business-flow.mmd", "color": "#56c8d8", |
| | | "summary": "ç»ä¸æ¨¡å¼ï¼ä¸å¡ä¾§æ¶éä¸ä¸æ(å¿
è¦æ¶è° MDM/SRM/CRM API ååç§°)âç»è£
Promptâchat/chatWithImageâè§£æ JSONâå端é¢å¡«æå»ºè®®ï¼æ Function Callingï¼RAG ç¥è¯åºå·²å»ºæä½ææ ä¸å¡æ¶è´¹ã", |
| | | "steps": [ |
| | |
| | | MES -->|éè´§è´¨æ£å
¥åºåè°| AS[å®åå·¥åç»´ä¿®éè´§] |
| | | CRM -->|客æ·ä¸»æ°æ®| AS |
| | | HRM[HRM åå·¥å
¥è½¬è°ç¦»äº¤æ¥èå¤èªé
¬] -.->|expandUserIds æ°æ®å¯è§æ§æ©å±Â·æ¥å£å·²å°±ç»ªå¾
忍¡åæ¥å
¥| CRM |
| | | BPM[BPM Flowable 审æ¹å¼æ] -.->|ç¶æäºä»¶åè°Â·14个çå¬å¨| ERP |
| | | BPM[BPM Flowable 审æ¹å¼æ] -.->|ç¶æäºä»¶åè°Â·15个çå¬å¨| ERP |
| | | BPM -.-> CRM |
| | | BPM -.-> SRM |
| | | BPM -.-> MES |
| | |
| | | STG[éä»¶ä¸å¿ storage-blob+attachment å
¨æ¨¡åç»ä¸æéä»¶] --- ERP |
| | | FIN[è´¢å¡æ¥é ç¬ç«æ¨¡å yudao-module-finance æ¥éå æç» å票éä»¶] -.->|å¤ç¨ BPM 审æ¹ä¸ç¶æåè°| BPM |
| | | FIN -.->|å票走éä»¶ä¸å¿ recordType=finance_reimbursement| STG |
| | | FIN -.->|ç¬ç«æ¨¡å·ä¸ä¸å
¶å®ä¸å¡æ¨¡å产çåæ®ææ°æ®å
³è| ERP |
| | | FIN -.->|"对å¤ä»
æä¾ yudao-module-finance-api(FinanceReimbursementApi)ä¾ä»æ¨¡å建å"| ERP |
| | | UMS[ä¼å管ç ç¬ç«æ¨¡å yudao-module-ums å
¥ä¼ç³è¯· ä¼å é讯å½] -.->|å¤ç¨ BPM 两级审æ¹ä¸ç¶æåè°| BPM |
| | | UMS -.->|è¯æææèµ°éä»¶ä¸å¿ recordType=ums_application / ums_member| STG |
| | | UMS -.->|审æ¹éè¿ç» AdminUserApi.createUser 建系ç»ç»å½è´¦å·| SYS |
| | |
| | | RES -.->|éä»¶èµ°éä»¶ä¸å¿ recordType=research_guideline / research_application / research_fund_record| STG |
| | | RES -->|éä¼ååç³æ¥äººå§å å·¥ä½åä½ èç§° èç³»çµè¯| UMS |
| | | RES -->|ç«é¡¹éç¥å system_notice å
Œ| SYS |
| | | RES -->|ç»è´¹æ¨ä» 1:1 èªå¨çæ finance_reimbursement æ¥éåå¹¶æäº¤å®¡æ¹Â·èµ°æ°å»ºç yudao-module-finance-api| FIN |
| | | FIN -.->|æ¥é审æ¹ç»æç» BPM äºä»¶åè° ResearchFundStatusListener ååè¯¾é¢æ¨æ¬¾å°è´¦| RES |
| | | </pre> |
| | | <pre style="display:none" class="mmd-src" data-mmd="09-data-flow"> |
| | | flowchart LR |
| | |
| | | RBM -->|submit 带 id ä¸ processDefinitionKey èµ° query| RBS |
| | | RBS -.->|BPM çå¬å¨ç»æåå éè¿20 驳å35 åæ¶éå0| RBM |
| | | RBA -.->|ä¸ä¼ ä¸ä¿åå离·ç¦å¨ä¸å¡è¡¨åæä»¶å°å| PDFARCH |
| | | FINNOTE[ç¬ç«æ¨¡å·éå®éè´é¾æ¡ä»»æåæ®åä¸çææ¥éå·æ¥éå亦ä¸ååä»»ä½å¤é¨åæ®] -.-> RBM |
| | | FINNOTE[ç¬ç«æ¨¡å·éå®éè´é¾æ¡ä»»æåæ®åä¸çææ¥éå·æ¥éå亦ä¸ååä»»ä½å¤é¨åæ®Â·å¯ä¸ä¾å¤æ¯è¯¾é¢ç»è´¹æ¨ä»] -.-> RBM |
| | | subgraph S6 [ç¬ç«è¯¾é¢ç®¡ç research] |
| | | RGL[è¯¾é¢æå research_guideline] --> RAP[课é¢ç³æ¥ä¹¦ research_application] |
| | | RAP --> RRV[ä¸å®¶è¯å®¡æç» research_topic_review] |
| | |
| | | RRV -.->|"æç»å 空æ¶ä¸»åæ±æ»æ¸
为 null"| RAP |
| | | RAP -->|"publishNotice çæ system_notice å
¬åå¹¶åå noticeId·éå¤å叿¦æª"| SYS2[system_notice ç³»ç»å
Œ] |
| | | RFR -->|"é颿 ¡éª å·²ç»è®° + æ¬æ¬¡ ä¸å¾è¶
åº budgetAmount ç³è¯·ç»è´¹"| RAP |
| | | RFR -.->|"åè¯èµ°éä»¶ä¸å¿ recordType=research_fund_record·表å
ä¸åæä»¶å°å"| PDFARCH |
| | | RFR -.->|"åè¯èµ°éä»¶ä¸å¿ recordType=research_fund_record·å䏿¹ blob åç» finance_reimbursement·表å
ä¸åæä»¶å°å"| PDFARCH |
| | | RAP -.->|"ç³æ¥éä»¶ recordType=research_application"| PDFARCH |
| | | RGL -.->|"æåéä»¶ recordType=research_guideline"| PDFARCH |
| | | RESNOTE[ç¬ç«æ¨¡åÂ·ä¸æç»è´¹æ¨ä»åªå¨æ¬æ¨¡åè½è®°å½Â·ä¸è´¢å¡æ¨¡åæ æ°æ®åæ¥Â·äºæå对æ¥] -.-> RFR |
| | | RFR -->|"1:1 çææ¥éåÂ·ç» FinanceReimbursementApi æ¬å° Bean 建åå¹¶ç«å³ submit·åå reimbursement_id/reimbursement_no·å°è´¦ç½® 15 æ¥é审æ¹ä¸"| RBM |
| | | RBM -->|"æ¥éåè¿å
¥å䏿¡ BPM æµç¨ finance_reimbursement_approve(è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹)·businessKey=æ¥éå ID"| RBS |
| | | RBS -.->|"BPM çå¬å¨ ResearchFundStatusListener åå课é¢å°è´¦ éè¿20 驳å30(+驳ååå /æ¶é´) æ¤å0"| RFR |
| | | RESNOTE[䏿已坹æ¥è´¢å¡Â·è¯¾é¢å°è´¦ä¸ºæ¨æ¬¾å°è´¦Â·æ¥éå为财å¡åºè´¦åè¯Â·ä¸¤è¾¹ä»¥ reimbursement_id 软å
³èæ å¤é®Â·è´¢å¡ä¾§ç´æ¥å åä¼ç䏿¬ç©º ID ç±ä¸å¡æ¥éå
åº] -.-> RFR |
| | | </pre> |
| | | <pre style="display:none" class="mmd-src" data-mmd="10-business-object"> |
| | | erDiagram |
| | |
| | | research_guideline ||--o{ research_application : "è¢«ç³æ¥å¼ç¨" |
| | | research_application ||--o{ research_topic_review : "ä¸å®¶è¯åæç»" |
| | | research_application ||--o{ research_fund_record : "ç»è´¹æ¨ä»è®°å½" |
| | | research_fund_record ||--|| finance_reimbursement : "1:1 çæåºè´¦æ¥éå(软å
³è reimbursement_id)" |
| | | ums_member ||--o{ research_application : "ç³æ¥äºº(软å
³èæ å¤é®)" |
| | | </pre> |
| | | <pre style="display:none" class="mmd-src" data-mmd="11-ai-business-flow"> |
| | |
| | | </pre> |
| | | <pre style="display:none" class="mmd-src" data-mmd="12-finance-flow"> |
| | | flowchart TD |
| | | U1[æ¥éäººå¡«æ¥æ¥éå·主表: æ¥éåå·(éå¡«) æ¥éæ é¢ æ¥éæ»éé¢ ç³è¯·æ¥æ 夿³¨] --> U2[å½å
¥æ¥éæç» 1..n è¡: è´¹ç¨ç±»å å票å·ç å票éé¢ åç¥¨æ¥æ å¼ç¥¨æ¹ è´¹ç¨è¯´æ] |
| | | U1["æ¥éäººå¡«æ¥æ¥éå·主表: æ¥éåå·(éå¡«) æ¥éæ é¢ æ¥éæ»éé¢ ç³è¯·æ¥æ 夿³¨"] --> U2["å½å
¥æ¥éæç» 1..n è¡: è´¹ç¨ç±»å å票å·ç å票éé¢ åç¥¨æ¥æ å¼ç¥¨æ¹ è´¹ç¨è¯´æ"] |
| | | U2 --> U3[å票éä»¶: å¾çæ PDF å
ä¼ system storage-blob upload å blobId] |
| | | U3 --> S1[ä¿å createÂ·ä¸»è¡¨ä¸æç»ä¸å
¨é¨ blobIds 䏿¬¡æ§æäº¤] |
| | | S1 --> G1["æ¥éåå·ï¼å¯èªå®ä¹ï¼ç空(å«çº¯ç©ºæ ¼)åç±åç«¯çæ BX + yyyyMMdd + 6使µæ°´(RedisÂ·æ¯æ¥éç½®)"] |
| | |
| | | K3 -->|archive 彿¡£| K5[已彿¡£ 40Â·ç»æÂ·åå
¥ archiveTime] |
| | | D1["ä»
è稿 0 å¯ delete·è¿å¸¦æ¸
çæç»ä¸å票éä»¶"] -.-> K1 |
| | | E1["ä»
è稿 0 ä¸å·²é©³å 35 å¯ update·å
¶ä½ç¶æåªè¯»"] -.-> K4 |
| | | N1["ç¬ç«æ¨¡å·ä¸ä¸å
¶ä»ä¸å¡æ¨¡å产çåæ®æå段带å
¥"] --- K1 |
| | | N1["ç¬ç«æ¨¡å·ä¸éå®éè´é¾æ¡ä»»ä½åæ®åæ å
³èï¼å¯ä¸ä¾å¤æ¯è¢«è¯¾é¢ç»è´¹æ¨ä» 1:1 èªå¨çæ(ç» yudao-module-finance-api)"] --- K1 |
| | | </pre> |
| | | <pre style="display:none" class="mmd-src" data-mmd="13-ums-membership-flow"> |
| | | flowchart TD |
| | |
| | | KA -->|驳å| K5 |
| | | K5 -->|ä¿®æ¹åéæ° submit| K2 |
| | | K4 -->|publishNotice åå¸ç«é¡¹éç¥| N1["system_notice å
¬å·æ é¢ãå
³äºå
¬å¸ç«é¡¹è¯¾é¢çéç¥ãÂ·æ£æå«è¯¾é¢å ç«é¡¹ç¼å· ç±»å« ç³æ¥äºº åä½ èµå©éé¢Â·åå noticeId·éå¤åå¸è¢«æ¦æª"] |
| | | K4 -->|ç»è®°æ¨æ¬¾è®°å½ research_fund_record| F1[å¡«æ¹æ¬¡åç§° æ¨ä»éé¢ æ¨ä»æ¥æ æ¶æ¬¾åä½ æ¨ä»ç¶æ åè¯éä»¶] |
| | | F1 -->|"é颿 ¡éª: å·²ç»è®°éé¢ + æ¬æ¬¡éé¢ ä¸å¾è¶
åºç³æ¥åç³è¯·ç»è´¹Â·è¶
åºæ¶æ¥åºæ¬æ¬¡ å·²ç»è®° å计 é¢ç®å项æ°å¼"| F2[å¾
æ¨ä» 0] |
| | | F2 -->|"ä»
å¾
æ¨ä» 0 坿¹å¯å "| F2 |
| | | F2 -->|"ç¶ææ¹ä¸ºå·²æ¨ä»æ¶å¿
须已æåè¯éä»¶"| F3[å·²æ¨ä» 20] |
| | | K4 -->|ç»è®°æ¨æ¬¾è®°å½ research_fund_record| F1[å¡«æ¹æ¬¡åç§° æ¨ä»éé¢ æ¨ä»æ¥æ æ¶æ¬¾åä½ å¤æ³¨Â·åè¯éä»¶å¿
å¡«] |
| | | F1 -->|"é颿 ¡éª: å·²ç»è®°éé¢ + æ¬æ¬¡éé¢ ä¸å¾è¶
åºç³æ¥åç³è¯·ç»è´¹Â·è¶
åºæ¶æ¥åºæ¬æ¬¡ å·²ç»è®° å计 é¢ç®å项æ°å¼"| FGEN["èªå¨çæ 1:1 è´¢å¡æ¥éå finance_reimbursement(1 è¡æç»: è´¹ç¨ç±»å=å
¶ä» å票éé¢=æ¨ä»éé¢ åç¥¨æ¥æ=æ¨ä»æ¥æ è´¹ç¨è¯´æ=课é¢å+æ¹æ¬¡)·éå䏿¹åè¯Â·ç«å³æäº¤ BPM·å忥éåå·"] |
| | | FGEN -->|ååå°è´¦ç¶æ| F3[æ¥é审æ¹ä¸ 15] |
| | | F3 -->|"è´¢å¡å®¡æ ¸ Activity_finance_review"| FAPP[è´¢å¡ä¸»ç®¡å®¡æ¹ Activity_finance_approve] |
| | | FAPP -->|BPM 审æ¹éè¿| F4[å·²æ¨ä» 20] |
| | | FAPP -->|BPM 审æ¹é©³å| F5["已驳å 30·åå驳ååå ä¸é©³åæ¶é´"] |
| | | F5 -->|"ä¿®æ¹é颿åè¯åéæ°åèµ·æ¥é"| F3 |
| | | FAPP -->|"è´¢å¡ç«¯æ¤åæåæ¶"| F2["å¾
æ¨ä» 0·å¯ç¼è¾å¯å é¤"] |
| | | F2 -->|"ä»
å¾
æ¨ä» 0 坿¹å¯å ·å 餿¶è卿¸
çè´¢å¡ä¾§è稿æ¥éå"| F2 |
| | | F2 -->|"ä¿®æ¹åéæ°åèµ·æ¥é"| F3 |
| | | ATT1["éä»¶ recordType = research_guideline"] -.-> G3 |
| | | ATT2["éä»¶ recordType = research_application"] -.-> K1 |
| | | ATT3["éä»¶ recordType = research_fund_record"] -.-> F1 |
| | | ATT3["éä»¶ recordType = research_fund_record·å䏿¹ blob åç» finance_reimbursement(æ recordType+recordId é离äºä¸å½±å)"] -.-> F1 |
| | | ROL["审æ¹ä¸å¿çå: æµç¨å®ä¹è¡¨åç±»å=èªå®ä¹è¡¨å·åå»ºè·¯å¾ /research/application/index · æ¥çè·¯å¾ /research/application/detail/approve/index.vue·æ businessKey åæ¾ç³æ¥å"] -.-> K3 |
| | | ROL2["审æ¹äººåå¼: ä¸èç¹å¨æµç¨å®ä¹å
é
å¥½å®¡æ¹æ¹æ³(便¬¡å®¡æ¹)ä¸å®¡æ¹äººçç¥Â·é¨ç½²åç±ç®¡çåå¨ BPM æµç¨è®¾è®¡å¨æå¦ä¼å®é
ç»ç»è°æ´Â·æäº¤æ¶å端åªè®©éæµç¨ä¸é审æ¹äºº"] -.-> K3 |
| | | RES1["ä¸æè¾¹ç: ç»è´¹æ¨ä»åªå¨æ¬æ¨¡åè½æ¨æ¬¾è®°å½Â·ä¸è´¢å¡æ¨¡åæ æ°æ®åæ¥(ä¸å跨模å对æ¥)"] -.-> F1 |
| | | LIS2["çå¬å¨ ResearchFundStatusListener(æµç¨ key=finance_reimbursement_approve·businessKey=æ¥éå ID): éè¿âå°è´¦å·²æ¨ä» 20·驳åâ已驳å 30+åå 䏿¶é´Â·æ¤å/åæ¶âéåå¾
æ¨ä» 0Â·ä¸ finance èªå·±ççå¬å¨è®¢é
åä¸ key å¹¶è¡è§¦å"] -.-> F3 |
| | | FINAPI["跨模åèµ°æ°å»ºç yudao-module-finance-api(FinanceReimbursementApi·æ¬å° Bean é HTTP): æ å·²å叿¥éå®¡æ¹æµç¨æ¶å
è§£æå³æ¥é·ä¸å»ºå·é¿å
çä¸å¤å¿è稿æ¥éå"] -.-> FGEN |
| | | RES1["䏿已坹æ¥è´¢å¡: æ¨æ¬¾å¿
须走 finance_reimbursement æ¥éååºè´¦Â·è¯¾é¢ä¾§å°è´¦=æ¨æ¬¾å°è´¦Â·è´¢å¡æ¥éå=åºè´¦åè¯Â·ä¸¤è¾¹ä»¥ reimbursement_id 软å
³è(æ å¤é®)·财å¡å®¡æ¹ç»æèªå¨å忬å°è´¦"] -.-> F1 |
| | | RES2["äºæèå´(æ¬å¾æªè¦ç): ç»é¡¹éªæ¶ ç»é¡¹è¯ä¹¦ ææå½æ¡£ç¥è¯åº é纳æ
åµä¸ç¤¾ä¼æçæ æ³¨"] -.-> K4 |
| | | BOUND["ç¬ç«æ¨¡å yudao-module-research·对 ums_member 为软å
³è(æ å¤é®)·ä»
å¤ç¨ BPM 审æ¹ãsystem å
¬åä¸éä»¶ä¸å¿"] --- K1 |
| | | BOUND["ç¬ç«æ¨¡å yudao-module-research·对 ums_member 为软å
³è(æ å¤é®)Â·å¯¹è´¢å¡æ¨¡åèµ° -api 忍¡åæ¬å°è°ç¨Â·ä»
å¤ç¨ BPM 审æ¹ãsystem å
¬åä¸éä»¶ä¸å¿"] --- K1 |
| | | </pre> |
| | | |
| | | <script type="module"> |
| | |
| | | MES -->|éè´§è´¨æ£å
¥åºåè°| AS[å®åå·¥åç»´ä¿®éè´§] |
| | | CRM -->|客æ·ä¸»æ°æ®| AS |
| | | HRM[HRM åå·¥å
¥è½¬è°ç¦»äº¤æ¥èå¤èªé
¬] -.->|expandUserIds æ°æ®å¯è§æ§æ©å±Â·æ¥å£å·²å°±ç»ªå¾
忍¡åæ¥å
¥| CRM |
| | | BPM[BPM Flowable 审æ¹å¼æ] -.->|ç¶æäºä»¶åè°Â·14个çå¬å¨| ERP |
| | | BPM[BPM Flowable 审æ¹å¼æ] -.->|ç¶æäºä»¶åè°Â·15个çå¬å¨| ERP |
| | | BPM -.-> CRM |
| | | BPM -.-> SRM |
| | | BPM -.-> MES |
| | |
| | | STG[éä»¶ä¸å¿ storage-blob+attachment å
¨æ¨¡åç»ä¸æéä»¶] --- ERP |
| | | FIN[è´¢å¡æ¥é ç¬ç«æ¨¡å yudao-module-finance æ¥éå æç» å票éä»¶] -.->|å¤ç¨ BPM 审æ¹ä¸ç¶æåè°| BPM |
| | | FIN -.->|å票走éä»¶ä¸å¿ recordType=finance_reimbursement| STG |
| | | FIN -.->|ç¬ç«æ¨¡å·ä¸ä¸å
¶å®ä¸å¡æ¨¡å产çåæ®ææ°æ®å
³è| ERP |
| | | FIN -.->|"对å¤ä»
æä¾ yudao-module-finance-api(FinanceReimbursementApi)ä¾ä»æ¨¡å建å"| ERP |
| | | UMS[ä¼å管ç ç¬ç«æ¨¡å yudao-module-ums å
¥ä¼ç³è¯· ä¼å é讯å½] -.->|å¤ç¨ BPM 两级审æ¹ä¸ç¶æåè°| BPM |
| | | UMS -.->|è¯æææèµ°éä»¶ä¸å¿ recordType=ums_application / ums_member| STG |
| | | UMS -.->|审æ¹éè¿ç» AdminUserApi.createUser 建系ç»ç»å½è´¦å·| SYS |
| | |
| | | RES -.->|éä»¶èµ°éä»¶ä¸å¿ recordType=research_guideline / research_application / research_fund_record| STG |
| | | RES -->|éä¼ååç³æ¥äººå§å å·¥ä½åä½ èç§° èç³»çµè¯| UMS |
| | | RES -->|ç«é¡¹éç¥å system_notice å
Œ| SYS |
| | | RES -->|ç»è´¹æ¨ä» 1:1 èªå¨çæ finance_reimbursement æ¥éåå¹¶æäº¤å®¡æ¹Â·èµ°æ°å»ºç yudao-module-finance-api| FIN |
| | | FIN -.->|æ¥é审æ¹ç»æç» BPM äºä»¶åè° ResearchFundStatusListener ååè¯¾é¢æ¨æ¬¾å°è´¦| RES |
| | |
| | | RBM -->|submit 带 id ä¸ processDefinitionKey èµ° query| RBS |
| | | RBS -.->|BPM çå¬å¨ç»æåå éè¿20 驳å35 åæ¶éå0| RBM |
| | | RBA -.->|ä¸ä¼ ä¸ä¿åå离·ç¦å¨ä¸å¡è¡¨åæä»¶å°å| PDFARCH |
| | | FINNOTE[ç¬ç«æ¨¡å·éå®éè´é¾æ¡ä»»æåæ®åä¸çææ¥éå·æ¥éå亦ä¸ååä»»ä½å¤é¨åæ®] -.-> RBM |
| | | FINNOTE[ç¬ç«æ¨¡å·éå®éè´é¾æ¡ä»»æåæ®åä¸çææ¥éå·æ¥éå亦ä¸ååä»»ä½å¤é¨åæ®Â·å¯ä¸ä¾å¤æ¯è¯¾é¢ç»è´¹æ¨ä»] -.-> RBM |
| | | subgraph S6 [ç¬ç«è¯¾é¢ç®¡ç research] |
| | | RGL[è¯¾é¢æå research_guideline] --> RAP[课é¢ç³æ¥ä¹¦ research_application] |
| | | RAP --> RRV[ä¸å®¶è¯å®¡æç» research_topic_review] |
| | |
| | | RRV -.->|"æç»å 空æ¶ä¸»åæ±æ»æ¸
为 null"| RAP |
| | | RAP -->|"publishNotice çæ system_notice å
¬åå¹¶åå noticeId·éå¤å叿¦æª"| SYS2[system_notice ç³»ç»å
Œ] |
| | | RFR -->|"é颿 ¡éª å·²ç»è®° + æ¬æ¬¡ ä¸å¾è¶
åº budgetAmount ç³è¯·ç»è´¹"| RAP |
| | | RFR -.->|"åè¯èµ°éä»¶ä¸å¿ recordType=research_fund_record·表å
ä¸åæä»¶å°å"| PDFARCH |
| | | RFR -.->|"åè¯èµ°éä»¶ä¸å¿ recordType=research_fund_record·å䏿¹ blob åç» finance_reimbursement·表å
ä¸åæä»¶å°å"| PDFARCH |
| | | RAP -.->|"ç³æ¥éä»¶ recordType=research_application"| PDFARCH |
| | | RGL -.->|"æåéä»¶ recordType=research_guideline"| PDFARCH |
| | | RESNOTE[ç¬ç«æ¨¡åÂ·ä¸æç»è´¹æ¨ä»åªå¨æ¬æ¨¡åè½è®°å½Â·ä¸è´¢å¡æ¨¡åæ æ°æ®åæ¥Â·äºæå对æ¥] -.-> RFR |
| | | RFR -->|"1:1 çææ¥éåÂ·ç» FinanceReimbursementApi æ¬å° Bean 建åå¹¶ç«å³ submit·åå reimbursement_id/reimbursement_no·å°è´¦ç½® 15 æ¥é审æ¹ä¸"| RBM |
| | | RBM -->|"æ¥éåè¿å
¥å䏿¡ BPM æµç¨ finance_reimbursement_approve(è´¢å¡å®¡æ ¸ â è´¢å¡ä¸»ç®¡å®¡æ¹)·businessKey=æ¥éå ID"| RBS |
| | | RBS -.->|"BPM çå¬å¨ ResearchFundStatusListener åå课é¢å°è´¦ éè¿20 驳å30(+驳ååå /æ¶é´) æ¤å0"| RFR |
| | | RESNOTE[䏿已坹æ¥è´¢å¡Â·è¯¾é¢å°è´¦ä¸ºæ¨æ¬¾å°è´¦Â·æ¥éå为财å¡åºè´¦åè¯Â·ä¸¤è¾¹ä»¥ reimbursement_id 软å
³èæ å¤é®Â·è´¢å¡ä¾§ç´æ¥å åä¼ç䏿¬ç©º ID ç±ä¸å¡æ¥éå
åº] -.-> RFR |
| | |
| | | research_guideline ||--o{ research_application : "è¢«ç³æ¥å¼ç¨" |
| | | research_application ||--o{ research_topic_review : "ä¸å®¶è¯åæç»" |
| | | research_application ||--o{ research_fund_record : "ç»è´¹æ¨ä»è®°å½" |
| | | research_fund_record ||--|| finance_reimbursement : "1:1 çæåºè´¦æ¥éå(软å
³è reimbursement_id)" |
| | | ums_member ||--o{ research_application : "ç³æ¥äºº(软å
³èæ å¤é®)" |
| | |
| | | flowchart TD |
| | | U1[æ¥éäººå¡«æ¥æ¥éå·主表: æ¥éåå·(éå¡«) æ¥éæ é¢ æ¥éæ»éé¢ ç³è¯·æ¥æ 夿³¨] --> U2[å½å
¥æ¥éæç» 1..n è¡: è´¹ç¨ç±»å å票å·ç å票éé¢ åç¥¨æ¥æ å¼ç¥¨æ¹ è´¹ç¨è¯´æ] |
| | | U1["æ¥éäººå¡«æ¥æ¥éå·主表: æ¥éåå·(éå¡«) æ¥éæ é¢ æ¥éæ»éé¢ ç³è¯·æ¥æ 夿³¨"] --> U2["å½å
¥æ¥éæç» 1..n è¡: è´¹ç¨ç±»å å票å·ç å票éé¢ åç¥¨æ¥æ å¼ç¥¨æ¹ è´¹ç¨è¯´æ"] |
| | | U2 --> U3[å票éä»¶: å¾çæ PDF å
ä¼ system storage-blob upload å blobId] |
| | | U3 --> S1[ä¿å createÂ·ä¸»è¡¨ä¸æç»ä¸å
¨é¨ blobIds 䏿¬¡æ§æäº¤] |
| | | S1 --> G1["æ¥éåå·ï¼å¯èªå®ä¹ï¼ç空(å«çº¯ç©ºæ ¼)åç±åç«¯çæ BX + yyyyMMdd + 6使µæ°´(RedisÂ·æ¯æ¥éç½®)"] |
| | |
| | | K3 -->|archive 彿¡£| K5[已彿¡£ 40Â·ç»æÂ·åå
¥ archiveTime] |
| | | D1["ä»
è稿 0 å¯ delete·è¿å¸¦æ¸
çæç»ä¸å票éä»¶"] -.-> K1 |
| | | E1["ä»
è稿 0 ä¸å·²é©³å 35 å¯ update·å
¶ä½ç¶æåªè¯»"] -.-> K4 |
| | | N1["ç¬ç«æ¨¡å·ä¸ä¸å
¶ä»ä¸å¡æ¨¡å产çåæ®æå段带å
¥"] --- K1 |
| | | N1["ç¬ç«æ¨¡å·ä¸éå®éè´é¾æ¡ä»»ä½åæ®åæ å
³èï¼å¯ä¸ä¾å¤æ¯è¢«è¯¾é¢ç»è´¹æ¨ä» 1:1 èªå¨çæ(ç» yudao-module-finance-api)"] --- K1 |
| | |
| | | <module>yudao-module-qcreport</module> |
| | | <!-- è´¢å¡ç®¡ç模å --> |
| | | <module>yudao-module-finance</module> |
| | | <module>yudao-module-finance-api</module> |
| | | <!-- ä¼åç®¡çæ¨¡å --> |
| | | <module>yudao-module-ums</module> |
| | | <!-- 课é¢ç®¡ç模å --> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?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-finance-api</artifactId> |
| | | <packaging>jar</packaging> |
| | | |
| | | <name>${project.artifactId}</name> |
| | | <description> |
| | | finance 模åä¸ï¼è´¢å¡æ¥éç 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.finance.api.reimbursement; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementCreateReqDTO; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementRespDTO; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementUpdateReqDTO; |
| | | |
| | | /** |
| | | * è´¢å¡æ¥éå API æ¥å£ |
| | | * |
| | | * ä¾å
¶ä»æ¨¡åï¼å¦è¯¾é¢ç®¡çç»è´¹æ¨ä»ï¼å建并èªå¨æäº¤æ¥é审æ¹ï¼ä»¥åä¿®æ¹åéæ°åèµ·ãå é¤ãæ¥è¯¢æ¥éåã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface FinanceReimbursementApi { |
| | | |
| | | String PREFIX = "/rpc-api/finance/reimbursement"; |
| | | |
| | | /** |
| | | * å建æ¥éåå¹¶ç«å³æäº¤å®¡æ¹ï¼ç³»ç»èªå¨çæ 1 è¡æç»ï¼ |
| | | * |
| | | * @param reqDTO æ¥éåä¿¡æ¯ |
| | | * @return æ¥éåç¼å· |
| | | */ |
| | | CommonResult<Long> createReimbursementAndSubmit(FinanceReimbursementCreateReqDTO reqDTO); |
| | | |
| | | /** |
| | | * ä¿®æ¹æ¥éåå¹¶éæ°æäº¤å®¡æ¹ï¼ç¨äºæ¥é被驳ååéæ°åèµ·ï¼ |
| | | * |
| | | * @param reqDTO æ¥éåä¿¡æ¯ï¼å«æ¥éåç¼å·ï¼ |
| | | * @return æ¯å¦æå |
| | | */ |
| | | CommonResult<Boolean> updateReimbursementAndResubmit(FinanceReimbursementUpdateReqDTO reqDTO); |
| | | |
| | | /** |
| | | * å 餿¥éåï¼åªæè稿æå·²é©³åç¶ææè½å é¤ï¼ |
| | | * |
| | | * @param reimbursementId æ¥éåç¼å· |
| | | * @return æ¯å¦æå |
| | | */ |
| | | CommonResult<Boolean> deleteReimbursement(Long reimbursementId); |
| | | |
| | | /** |
| | | * è·åæ¥éå |
| | | * |
| | | * @param reimbursementId æ¥éåç¼å· |
| | | * @return æ¥éå |
| | | */ |
| | | CommonResult<FinanceReimbursementRespDTO> getReimbursement(Long reimbursementId); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.finance.api.reimbursement.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "RPC æå¡ - è´¢å¡æ¥éåå建 Request DTO") |
| | | @Data |
| | | public class FinanceReimbursementCreateReqDTO { |
| | | |
| | | @Schema(description = "æ¥éäºç±/æ é¢", requiredMode = Schema.RequiredMode.REQUIRED, example = "课é¢ãXXç ç©¶ãç¬¬ä¸æç»è´¹æ¨æ¬¾") |
| | | private String title; |
| | | |
| | | @Schema(description = "æ¥éæ»éé¢ï¼å
ï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "50000.00") |
| | | private BigDecimal totalAmount; |
| | | |
| | | @Schema(description = "ç³è¯·æ¥æ", example = "2026-12-01") |
| | | private LocalDate applyDate; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "åè¯éä»¶ BlobId å表") |
| | | private List<Long> blobIds; |
| | | |
| | | @Schema(description = "èªå¨çæçå¯ä¸ä¸è¡æç»çè´¹ç¨è¯´æ", example = "课é¢ãXXç ç©¶ãç¬¬ä¸æç»è´¹æ¨æ¬¾") |
| | | private String expenseDescription; |
| | | |
| | | @Schema(description = "ç³è¯·äººç¨æ·ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long applicantId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.finance.api.reimbursement.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | |
| | | @Schema(description = "RPC æå¡ - è´¢å¡æ¥éå Response DTO") |
| | | @Data |
| | | public class FinanceReimbursementRespDTO { |
| | | |
| | | @Schema(description = "æ¥éåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long id; |
| | | |
| | | @Schema(description = "æ¥éåå·", requiredMode = Schema.RequiredMode.REQUIRED, example = "BX20261201000001") |
| | | private String no; |
| | | |
| | | @Schema(description = "æ¥éäºç±/æ é¢") |
| | | private String title; |
| | | |
| | | @Schema(description = "æ¥éæ»éé¢ï¼å
ï¼", example = "50000.00") |
| | | private BigDecimal totalAmount; |
| | | |
| | | @Schema(description = "æ¥éåç¶æï¼0-è稿 15-审æ¹ä¸ 20-å·²éè¿ 35-已驳å 40-已彿¡£", example = "15") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "æµç¨å®ä¾ç¼å·") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "ç³è¯·æ¥æ", example = "2026-12-01") |
| | | private LocalDate applyDate; |
| | | |
| | | @Schema(description = "ç³è¯·äººç¨æ·ç¼å·", example = "1") |
| | | private Long applicantId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.finance.api.reimbursement.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.util.List; |
| | | |
| | | @Schema(description = "RPC æå¡ - è´¢å¡æ¥éåä¿®æ¹å¹¶éæ°æäº¤ Request DTO") |
| | | @Data |
| | | public class FinanceReimbursementUpdateReqDTO { |
| | | |
| | | @Schema(description = "æ¥éåç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private Long reimbursementId; |
| | | |
| | | @Schema(description = "æ¥éäºç±/æ é¢", requiredMode = Schema.RequiredMode.REQUIRED, example = "课é¢ãXXç ç©¶ãç¬¬ä¸æç»è´¹æ¨æ¬¾") |
| | | private String title; |
| | | |
| | | @Schema(description = "æ¥éæ»éé¢ï¼å
ï¼", requiredMode = Schema.RequiredMode.REQUIRED, example = "50000.00") |
| | | private BigDecimal totalAmount; |
| | | |
| | | @Schema(description = "ç³è¯·æ¥æ", example = "2026-12-01") |
| | | private LocalDate applyDate; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "åè¯éä»¶ BlobId å表ï¼å
¨éæ¿æ¢ï¼") |
| | | private List<Long> blobIds; |
| | | |
| | | @Schema(description = "èªå¨çæçå¯ä¸ä¸è¡æç»çè´¹ç¨è¯´æ", example = "课é¢ãXXç ç©¶ãç¬¬ä¸æç»è´¹æ¨æ¬¾") |
| | | private String expenseDescription; |
| | | |
| | | } |
| | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-finance-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-system</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.finance.api.reimbursement; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementCreateReqDTO; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementRespDTO; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementUpdateReqDTO; |
| | | import cn.iocoder.yudao.module.finance.controller.admin.reimbursement.vo.FinanceReimbursementSaveReqVO; |
| | | import cn.iocoder.yudao.module.finance.controller.admin.reimbursement.vo.item.FinanceReimbursementItemSaveReqVO; |
| | | import cn.iocoder.yudao.module.finance.dal.dataobject.reimbursement.FinanceReimbursementDO; |
| | | import cn.iocoder.yudao.module.finance.service.reimbursement.FinanceReimbursementService; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | import static cn.iocoder.yudao.module.finance.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * è´¢å¡æ¥éå API å®ç°ç±» |
| | | * |
| | | * ä¾å
¶ä»æ¨¡åï¼è¯¾é¢ç®¡çç»è´¹æ¨ä»ï¼ä»¥ãèªå¨å»ºå + èªå¨æäº¤å®¡æ¹ãçæ¹å¼è½ä¸å¼ è´¢å¡æ¥éåï¼ |
| | | * æç»ç±ç³»ç»åºå®çæ 1 è¡ï¼è´¹ç¨ç±»å=å
¶ä»ï¼ï¼å票éé¢åæ¥éæ»éé¢ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @RestController |
| | | @RequestMapping(FinanceReimbursementApi.PREFIX) |
| | | @Validated |
| | | public class FinanceReimbursementApiImpl implements FinanceReimbursementApi { |
| | | |
| | | /** è´¹ç¨ç±»åï¼å
¶ä»ï¼åå
¸ finance_expense_typeï¼1-å·®æ
2-åå
¬ 3-æå¾
4-交é 5-å
¶ä»ï¼ */ |
| | | private static final Integer EXPENSE_TYPE_OTHER = 5; |
| | | |
| | | @Resource |
| | | private FinanceReimbursementService reimbursementService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public CommonResult<Long> createReimbursementAndSubmit(FinanceReimbursementCreateReqDTO reqDTO) { |
| | | // 1. å
è§£æå¯ç¨çæ¥éå®¡æ¹æµç¨ï¼æ²¡æå·²å叿µç¨æ¶ç´æ¥å¤±è´¥ï¼é¿å
ç䏿 æ³æäº¤çå¤å¿è稿å |
| | | String processDefinitionKey = resolveApproveProcessDefinitionKey(); |
| | | |
| | | // 2. å建æ¥éåï¼1 è¡æç»ï¼ |
| | | FinanceReimbursementSaveReqVO createReqVO = buildSaveReqVO(null, reqDTO.getTitle(), |
| | | reqDTO.getTotalAmount(), reqDTO.getApplyDate(), reqDTO.getRemark(), |
| | | reqDTO.getBlobIds(), reqDTO.getExpenseDescription()); |
| | | Long reimbursementId = reimbursementService.createReimbursement(createReqVO); |
| | | |
| | | // 3. ç«å³æäº¤å®¡æ¹ |
| | | Long applicantId = reqDTO.getApplicantId() != null ? reqDTO.getApplicantId() : getLoginUserId(); |
| | | reimbursementService.submitReimbursement(reimbursementId, processDefinitionKey, applicantId); |
| | | |
| | | return success(reimbursementId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public CommonResult<Boolean> updateReimbursementAndResubmit(FinanceReimbursementUpdateReqDTO reqDTO) { |
| | | // 1. å
è§£æå¯ç¨çæ¥éå®¡æ¹æµç¨ |
| | | String processDefinitionKey = resolveApproveProcessDefinitionKey(); |
| | | |
| | | // 2. ä¿®æ¹æ¥éåï¼æç»é建为 1 è¡ï¼ |
| | | FinanceReimbursementSaveReqVO updateReqVO = buildSaveReqVO(reqDTO.getReimbursementId(), |
| | | reqDTO.getTitle(), reqDTO.getTotalAmount(), reqDTO.getApplyDate(), reqDTO.getRemark(), |
| | | reqDTO.getBlobIds(), reqDTO.getExpenseDescription()); |
| | | reimbursementService.updateReimbursement(updateReqVO); |
| | | |
| | | // 3. éæ°æäº¤å®¡æ¹ |
| | | reimbursementService.submitReimbursement(reqDTO.getReimbursementId(), processDefinitionKey, getLoginUserId()); |
| | | |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<Boolean> deleteReimbursement(Long reimbursementId) { |
| | | reimbursementService.deleteReimbursement(reimbursementId); |
| | | return success(true); |
| | | } |
| | | |
| | | @Override |
| | | public CommonResult<FinanceReimbursementRespDTO> getReimbursement(Long reimbursementId) { |
| | | // æ¥éåä¸å卿¶è¿å nullï¼ç±è°ç¨æ¹å³å®å¦ä½å¤çï¼è¯¾é¢ä¾§æ®æ¤å®¹å¿è¢«ç´æ¥å é¤çæ¥éåï¼ |
| | | FinanceReimbursementDO reimbursement = reimbursementService.getReimbursement(reimbursementId); |
| | | return success(BeanUtils.toBean(reimbursement, FinanceReimbursementRespDTO.class)); |
| | | } |
| | | |
| | | // ==================== å
鍿¹æ³ ==================== |
| | | |
| | | /** |
| | | * è§£ææ¥é审æ¹åç±»ä¸å¯ç¨çæµç¨å®ä¹ keyï¼åç±»ä¸æ²¡æå·²åå¸çæµç¨æ¶æåºå¯æ§è¡ç精确æç¤º |
| | | */ |
| | | private String resolveApproveProcessDefinitionKey() { |
| | | List<Map<String, Object>> definitionList = reimbursementService.getReimbursementApproveProcessDefinitionList(); |
| | | if (CollUtil.isEmpty(definitionList)) { |
| | | throw exception(REIMBURSEMENT_BPM_PROCESS_DEFINITION_NOT_EXISTS); |
| | | } |
| | | return String.valueOf(definitionList.get(0).get("key")); |
| | | } |
| | | |
| | | /** ç»è£
æ¥éåä¿å VOï¼æç»åºå® 1 è¡ï¼è´¹ç¨ç±»åãå
¶ä»ãï¼å票éé¢=æ¥éæ»éé¢ */ |
| | | private FinanceReimbursementSaveReqVO buildSaveReqVO(Long id, String title, BigDecimal totalAmount, |
| | | LocalDate applyDate, String remark, List<Long> blobIds, |
| | | String expenseDescription) { |
| | | FinanceReimbursementItemSaveReqVO item = new FinanceReimbursementItemSaveReqVO(); |
| | | item.setExpenseType(EXPENSE_TYPE_OTHER); |
| | | item.setInvoiceAmount(totalAmount); |
| | | item.setInvoiceDate(applyDate); |
| | | item.setDescription(expenseDescription); |
| | | |
| | | FinanceReimbursementSaveReqVO reqVO = new FinanceReimbursementSaveReqVO(); |
| | | reqVO.setId(id); |
| | | reqVO.setTitle(title); |
| | | reqVO.setTotalAmount(totalAmount); |
| | | reqVO.setApplyDate(applyDate != null ? applyDate : LocalDate.now()); |
| | | reqVO.setRemark(remark); |
| | | reqVO.setBlobIds(blobIds); |
| | | reqVO.setItems(Collections.singletonList(item)); |
| | | return reqVO; |
| | | } |
| | | |
| | | } |
| | |
| | | ErrorCode REIMBURSEMENT_ARCHIVE_FAIL_STATUS = new ErrorCode(1_030_107_006, "彿¡£å¤±è´¥ï¼åªæå·²éè¿ç¶æçæ¥éåæè½å½æ¡£"); |
| | | ErrorCode REIMBURSEMENT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_107_007, "æ´æ°å®¡æ¹ç¶æå¤±è´¥ï¼åªæå®¡æ¹ä¸çæ¥éåæè½æ´æ°"); |
| | | ErrorCode REIMBURSEMENT_BPM_CATEGORY_NOT_EXISTS = new ErrorCode(1_030_107_008, "æ¥é审æ¹åç±»ä¸åå¨ï¼è¯·å
å¨BPM模åå建æ¥éå®¡æ¹æµç¨åç±»"); |
| | | ErrorCode REIMBURSEMENT_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_107_009, "æ¥é审æ¹åç±»ä¸æ²¡æå¯ç¨çæµç¨æ¨¡åï¼è¯·å
å建并å叿µç¨"); |
| | | ErrorCode REIMBURSEMENT_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_107_009, "æ¥é审æ¹åç±»ï¼finance_reimbursement_approveï¼ä¸æ²¡æå·²åå¸çæµç¨ï¼æ æ³æäº¤æ¥é审æ¹ã请å
å¨ãBPM â æµç¨å®ä¹ãä¸å建并å叿¥éå®¡æ¹æµç¨åéè¯"); |
| | | ErrorCode REIMBURSEMENT_CUSTOM_NO_EXISTS = new ErrorCode(1_030_107_010, "æ¥éåå·({})已被å
¶ä»æ¥éå使ç¨ï¼è¯·æ´æ¢å
¶ä»åå·ï¼ææ¸
ç©ºè¯¥åæ®µç±ç³»ç»èªå¨çæ"); |
| | | ErrorCode REIMBURSEMENT_CUSTOM_NO_INVALID = new ErrorCode(1_030_107_011, "æ¥éåå·({})ä¸é´ä¸è½å
å«ç©ºæ ¼ï¼è¯·å»æç©ºæ ¼åéæ°è¾å
¥ï¼ææ¸
ç©ºè¯¥åæ®µç±ç³»ç»èªå¨çæ"); |
| | | |
| | |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- è´¢å¡æ¨¡å APIï¼ç»è´¹æ¨ä»èªå¨çæå¹¶æäº¤è´¢å¡æ¥éåï¼ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-finance-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | |
| | | <!-- Web ç¸å
³ --> |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | |
| | | @Schema(description = "æ¶æ¬¾åä½/è´¦æ·å", example = "XX大å¦") |
| | | private String payee; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¾
æ¨ä» 20-å·²æ¨ä»", example = "20") |
| | | @Schema(description = "ç¶æï¼0-å¾
æ¨ä» 15-æ¥é审æ¹ä¸ 20-å·²æ¨ä» 30-已驳å", example = "20") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "å
³èè´¢å¡æ¥éå ID", example = "1") |
| | | private Long reimbursementId; |
| | | |
| | | @Schema(description = "å
³èè´¢å¡æ¥éåå·", example = "BX20260928000001") |
| | | private String reimbursementNo; |
| | | |
| | | @Schema(description = "è´¢å¡æ¥é驳ååå ") |
| | | private String rejectReason; |
| | | |
| | | @Schema(description = "è´¢å¡æ¥é驳忶é´") |
| | | private LocalDateTime rejectTime; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | |
| | | @Schema(description = "æ¶æ¬¾åä½/è´¦æ·å", example = "XX大å¦") |
| | | private String payee; |
| | | |
| | | @Schema(description = "ç¶æï¼0-å¾
æ¨ä» 20-å·²æ¨ä»", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") |
| | | @NotNull(message = "æ¨ä»ç¶æä¸è½ä¸ºç©º") |
| | | private Integer status; |
| | | |
| | | @Schema(description = "夿³¨") |
| | | private String remark; |
| | | |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * 课é¢-ç»è´¹æ¨ä»è®°å½ DO |
| | |
| | | /** æ¶æ¬¾åä½/è´¦æ·å */ |
| | | private String payee; |
| | | |
| | | /** ç¶æï¼0-å¾
æ¨ä» 20-å·²æ¨ä» */ |
| | | /** ç¶æï¼0-å¾
æ¨ä» 15-æ¥é审æ¹ä¸ 20-å·²æ¨ä» 30-已驳å */ |
| | | private Integer status; |
| | | |
| | | /** å
³èè´¢å¡æ¥éå IDï¼finance_reimbursement.idï¼ */ |
| | | private Long reimbursementId; |
| | | |
| | | /** å
³èè´¢å¡æ¥éåå· */ |
| | | private String reimbursementNo; |
| | | |
| | | /** è´¢å¡æ¥é驳ååå ï¼BPM ååï¼ */ |
| | | private String rejectReason; |
| | | |
| | | /** è´¢å¡æ¥é驳忶é´ï¼BPM ååï¼ */ |
| | | private LocalDateTime rejectTime; |
| | | |
| | | /** 夿³¨ */ |
| | | private String remark; |
| | | |
| | |
| | | return selectList(ResearchFundRecordDO::getApplicationId, applicationId); |
| | | } |
| | | |
| | | default ResearchFundRecordDO selectByReimbursementId(Long reimbursementId) { |
| | | return selectOne(ResearchFundRecordDO::getReimbursementId, reimbursementId); |
| | | } |
| | | |
| | | } |
| | |
| | | ErrorCode FUND_NOT_EXISTS = new ErrorCode(1_030_109_300, "ç»è´¹æ¨ä»è®°å½ä¸åå¨"); |
| | | ErrorCode FUND_RECORD_FAIL_STATUS = new ErrorCode(1_030_109_301, "ç»è®°å¤±è´¥ï¼è¯¾é¢ç³æ¥ä¹¦({})å½åç¶æä¸ºã{}ãï¼åªæå·²ç«é¡¹çè¯¾é¢æè½ç»è®°ç»è´¹æ¨ä»"); |
| | | ErrorCode FUND_AMOUNT_EXCEEDED = new ErrorCode(1_030_109_302, "ç»è®°å¤±è´¥ï¼æ¬æ¬¡æ¨ä» {} å
ï¼å·²ç»è®° {} å
ï¼å计 {} å
ï¼è¶
åºè¯¥è¯¾é¢ç³è¯·é¢ç® {} å
ï¼è¯·è°ä½æ¬æ¬¡æ¨ä»éé¢"); |
| | | ErrorCode FUND_VOUCHER_REQUIRED = new ErrorCode(1_030_109_303, "ç»è®°å¤±è´¥ï¼ç¶æä¸ºãå·²æ¨ä»ãæ¶å¿
é¡»ä¸ä¼ åè¯éä»¶ï¼è¯·å
ä¸ä¼ åè¯éä»¶ååä¿å"); |
| | | ErrorCode FUND_UPDATE_FAIL_STATUS = new ErrorCode(1_030_109_304, "æ´æ°å¤±è´¥ï¼ç»è´¹æ¨ä»è®°å½({})å½åç¶æä¸ºã{}ãï¼åªæå¾
æ¨ä»ç¶ææè½ä¿®æ¹"); |
| | | ErrorCode FUND_DELETE_FAIL_STATUS = new ErrorCode(1_030_109_305, "å é¤å¤±è´¥ï¼ç»è´¹æ¨ä»è®°å½({})å½åç¶æä¸ºã{}ãï¼åªæå¾
æ¨ä»ç¶ææè½å é¤"); |
| | | ErrorCode FUND_VOUCHER_REQUIRED = new ErrorCode(1_030_109_303, "ç»è®°æ¨æ¬¾å¤±è´¥ï¼æ¬æ¬¡ç»è®°çã{}ãæªä¸ä¼ æ¨ä»åè¯éä»¶ãåè¯ééèªå¨çæçè´¢å¡æ¥éåä¸èµ·é交财å¡å®¡æ¹ï¼è¯·å
ä¸ä¼ æ¨ä»åè¯ååä¿å"); |
| | | ErrorCode FUND_UPDATE_FAIL_STATUS = new ErrorCode(1_030_109_304, "æ´æ°å¤±è´¥ï¼ç»è´¹æ¨ä»è®°å½({})å½åç¶æä¸ºã{}ãï¼åªæãå¾
æ¨ä»ãæã已驳åãç¶ææè½ä¿®æ¹å¹¶éæ°åèµ·æ¥éï¼ãæ¥é审æ¹ä¸ã请å
å¨è´¢å¡ç«¯æ¤åï¼æçå¾
è´¢å¡å®¡æ¹ç»æ"); |
| | | ErrorCode FUND_DELETE_FAIL_STATUS = new ErrorCode(1_030_109_305, "å é¤å¤±è´¥ï¼ç»è´¹æ¨ä»è®°å½({})å½åç¶æä¸ºã{}ãï¼åªæãå¾
æ¨ä»ãç¶ææè½å é¤ï¼ãæ¥é审æ¹ä¸ã请å
å¨è´¢å¡ç«¯æ¤åï¼å·²é©³åçè®°å½è¯·æ¹ä¸ºãä¿®æ¹å¹¶éæ°åèµ·æ¥éã"); |
| | | ErrorCode FUND_REIMBURSEMENT_NOT_EXISTS = new ErrorCode(1_030_109_306, "ç»è´¹æ¨ä»è®°å½({})å
³èçè´¢å¡æ¥éå(ID={})å·²ä¸åå¨ï¼å¯è½å·²è¢«å é¤ï¼ï¼è¯·å 餿¬æ¡æ¨æ¬¾è®°å½åéæ°ç»è®°"); |
| | | ErrorCode FUND_REIMBURSEMENT_STATUS_CHANGED = new ErrorCode(1_030_109_307, "éæ°åèµ·æ¥é失败ï¼å
³èçè´¢å¡æ¥éå({})å½åç¶æä¸ºã{}ãï¼åªæãè稿ãæã已驳åãçæ¥éåæè½éæ°æäº¤ï¼è¯·è系财å¡ç¡®è®¤è¯¥åæ®ç¶æ"); |
| | | |
| | | } |
| | |
| | | public enum ResearchFundStatusEnum { |
| | | |
| | | PENDING(0, "å¾
æ¨ä»"), |
| | | APPROVING(15, "æ¥é审æ¹ä¸"), |
| | | PAID(20, "å·²æ¨ä»"), |
| | | REJECTED(30, "已驳å"), |
| | | ; |
| | | |
| | | private final Integer status; |
| | |
| | | /** æè¯¾é¢ç³æ¥ä¹¦ä¸çå
¨é¨ç»è´¹æ¨ä»è®°å½ï¼æå建æ¶é´ååºï¼ */ |
| | | List<ResearchFundRecordDO> getFundRecordListByApplicationId(Long applicationId); |
| | | |
| | | /** |
| | | * è´¢å¡æ¥é审æ¹ç»æååå°è´¦ç¶æ |
| | | * |
| | | * @param reimbursementId è´¢å¡æ¥éåç¼å· |
| | | * @param bpmStatus BPM 审æ¹ç»æï¼BpmTaskStatusEnumï¼ |
| | | * @param reason 驳ååå |
| | | */ |
| | | void updateFundStatusByReimbursement(Long reimbursementId, Integer bpmStatus, String reason); |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.research.service.fund; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.FinanceReimbursementApi; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementCreateReqDTO; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementRespDTO; |
| | | import cn.iocoder.yudao.module.finance.api.reimbursement.dto.FinanceReimbursementUpdateReqDTO; |
| | | import cn.iocoder.yudao.module.research.controller.admin.fund.vo.ResearchFundRecordSaveReqVO; |
| | | import cn.iocoder.yudao.module.research.dal.dataobject.application.ResearchApplicationDO; |
| | | import cn.iocoder.yudao.module.research.dal.dataobject.fund.ResearchFundRecordDO; |
| | |
| | | import cn.iocoder.yudao.module.research.enums.ResearchApplicationStatusEnum; |
| | | import cn.iocoder.yudao.module.research.enums.ResearchFundStatusEnum; |
| | | import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | import static cn.iocoder.yudao.module.research.enums.ErrorCodeConstants.*; |
| | | |
| | | /** |
| | | * ç»è´¹æ¨ä»è®°å½ Service å®ç°ç±» |
| | | * |
| | | * 䏿åªå¨æ¬æ¨¡åå
è½å°æ¨æ¬¾è®°å½ï¼æ¹æ¬¡/éé¢/æ¥æ/æ¶æ¬¾æ¹/åè¯éä»¶ï¼ï¼ä¸ä¸è´¢å¡æ¨¡ååæ¥ï¼ |
| | | * æ¯æ¡æ¨æ¬¾è®°å½é½ä¼èªå¨çæå¹¶æäº¤ä¸å¼ 对åºçè´¢å¡æ¥éåï¼1:1ï¼éé¢ä¸è´ï¼ï¼ |
| | | * æ¥éå审æ¹ç»æç± {@code ResearchFundStatusListener} å忬å°è´¦ç¶æï¼ |
| | | * å¾
æ¨ä»(0) â æ¥é审æ¹ä¸(15) â å·²æ¨ä»(20) / 已驳å(30)ï¼è´¢å¡ç«¯æ¤ååéåå¾
æ¨ä»(0)ã |
| | | * 累计æ¨ä»éé¢ä»¥ç³æ¥å budget_amountï¼ç³è¯·é¢ç®ï¼ä¸ºä¸éã |
| | | */ |
| | | @Service |
| | |
| | | public class ResearchFundRecordServiceImpl implements ResearchFundRecordService { |
| | | |
| | | public static final String FUND_RECORD_TYPE = "research_fund_record"; |
| | | |
| | | /** è´¢å¡æ¥éåç¶æï¼è稿 */ |
| | | private static final Integer FINANCE_STATUS_DRAFT = 0; |
| | | |
| | | @Resource |
| | | private ResearchFundRecordMapper fundRecordMapper; |
| | |
| | | @Resource |
| | | private StorageAttachmentApi storageAttachmentApi; |
| | | |
| | | @Resource |
| | | private FinanceReimbursementApi financeReimbursementApi; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Long createFundRecord(ResearchFundRecordSaveReqVO createReqVO) { |
| | | ResearchApplicationDO application = validateApplicationApproved(createReqVO.getApplicationId()); |
| | | validateVoucherRequired(createReqVO); |
| | | validateVoucherRequired(createReqVO.getBlobIds(), createReqVO.getBatchName()); |
| | | |
| | | // ç´¯è®¡æ ¡éªï¼æ°ç»è®°éé¢ + è¯¥ç³æ¥åå·²æè®°å½éé¢ï¼ä¸å¾è¶
è¿ç³è¯·é¢ç® |
| | | BigDecimal registered = sumAmount(fundRecordMapper.selectListByApplicationId(application.getId()), null); |
| | | List<ResearchFundRecordDO> existList = fundRecordMapper.selectListByApplicationId(application.getId()); |
| | | BigDecimal registered = sumAmount(existList, null); |
| | | validateAmountNotExceeded(createReqVO.getAmount(), registered, application.getBudgetAmount()); |
| | | |
| | | // 1. è½è¯¾é¢ä¾§å°è´¦ï¼ç¶æå
ç½®å¾
æ¨ä»ï¼æ¥éæäº¤æååæ¹ä¸ºæ¥é审æ¹ä¸ï¼ |
| | | ResearchFundRecordDO fundRecord = BeanUtils.toBean(createReqVO, ResearchFundRecordDO.class, |
| | | in -> in.setId(null)); |
| | | fundRecord.setStatus(ResearchFundStatusEnum.PENDING.getStatus()); |
| | | fundRecordMapper.insert(fundRecord); |
| | | |
| | | // 2. åè¯éä»¶åæ¶ç»å®å°è¯¾é¢å°è´¦ï¼è´¢å¡ä¾§æ¥éåç± finance 模åèªè¡ç»å®å䏿¹ blobï¼ |
| | | storageAttachmentApi.bindAttachments("file", FUND_RECORD_TYPE, |
| | | fundRecord.getId(), createReqVO.getBlobIds()); |
| | | |
| | | // 3. èªå¨çæå¹¶æäº¤è´¢å¡æ¥éå |
| | | String title = buildReimbursementTitle(application, createReqVO, existList.size() + 1); |
| | | FinanceReimbursementCreateReqDTO reqDTO = new FinanceReimbursementCreateReqDTO(); |
| | | reqDTO.setTitle(title); |
| | | reqDTO.setTotalAmount(createReqVO.getAmount()); |
| | | reqDTO.setApplyDate(createReqVO.getPayDate() != null ? createReqVO.getPayDate() : LocalDate.now()); |
| | | reqDTO.setRemark(createReqVO.getRemark()); |
| | | reqDTO.setBlobIds(createReqVO.getBlobIds()); |
| | | reqDTO.setExpenseDescription(title); |
| | | reqDTO.setApplicantId(getLoginUserId()); |
| | | Long reimbursementId = financeReimbursementApi.createReimbursementAndSubmit(reqDTO).getCheckedData(); |
| | | FinanceReimbursementRespDTO reimbursement = |
| | | financeReimbursementApi.getReimbursement(reimbursementId).getCheckedData(); |
| | | |
| | | // 4. ååè´¢å¡æ¥éåä¿¡æ¯å¹¶è¿å
¥ãæ¥é审æ¹ä¸ã |
| | | fundRecordMapper.updateById(new ResearchFundRecordDO() |
| | | .setId(fundRecord.getId()) |
| | | .setStatus(ResearchFundStatusEnum.APPROVING.getStatus()) |
| | | .setReimbursementId(reimbursementId) |
| | | .setReimbursementNo(reimbursement != null ? reimbursement.getNo() : null)); |
| | | return fundRecord.getId(); |
| | | } |
| | | |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateFundRecord(ResearchFundRecordSaveReqVO updateReqVO) { |
| | | ResearchFundRecordDO exist = validateFundRecordExists(updateReqVO.getId()); |
| | | if (!ResearchFundStatusEnum.PENDING.getStatus().equals(exist.getStatus())) { |
| | | if (!isEditable(exist.getStatus())) { |
| | | throw exception(FUND_UPDATE_FAIL_STATUS, |
| | | exist.getId(), ResearchFundStatusEnum.nameOf(exist.getStatus())); |
| | | } |
| | | // è®°å½å½å±ç³æ¥åä¸å¯åæ´ï¼é²æ¢ææ¨æ¬¾æªå°å«ç课é¢ä¸ |
| | | ResearchApplicationDO application = validateApplicationApproved(exist.getApplicationId()); |
| | | validateVoucherRequired(updateReqVO); |
| | | validateVoucherRequired(updateReqVO.getBlobIds(), updateReqVO.getBatchName()); |
| | | |
| | | BigDecimal registered = sumAmount(fundRecordMapper.selectListByApplicationId(exist.getApplicationId()), |
| | | exist.getId()); |
| | | BigDecimal registered = sumAmount( |
| | | fundRecordMapper.selectListByApplicationId(exist.getApplicationId()), exist.getId()); |
| | | validateAmountNotExceeded(updateReqVO.getAmount(), registered, application.getBudgetAmount()); |
| | | |
| | | ResearchFundRecordDO updateObj = BeanUtils.toBean(updateReqVO, ResearchFundRecordDO.class); |
| | | updateObj.setApplicationId(exist.getApplicationId()); |
| | | fundRecordMapper.updateById(updateObj); |
| | | // 1. è´¢å¡ä¾§ä¿®æ¹æ¥éåå¹¶éæ°æäº¤å®¡æ¹ï¼å
åï¼å¤±è´¥å课é¢ä¾§ä¸è½ä»»ä½åæ´ï¼ |
| | | Long reimbursementId = exist.getReimbursementId(); |
| | | if (reimbursementId == null) { |
| | | throw exception(FUND_REIMBURSEMENT_NOT_EXISTS, exist.getId(), "空"); |
| | | } |
| | | FinanceReimbursementRespDTO reimbursement = |
| | | financeReimbursementApi.getReimbursement(reimbursementId).getCheckedData(); |
| | | if (reimbursement == null) { |
| | | throw exception(FUND_REIMBURSEMENT_NOT_EXISTS, exist.getId(), reimbursementId); |
| | | } |
| | | String title = buildReimbursementTitle(application, updateReqVO, null); |
| | | FinanceReimbursementUpdateReqDTO reqDTO = new FinanceReimbursementUpdateReqDTO(); |
| | | reqDTO.setReimbursementId(reimbursementId); |
| | | reqDTO.setTitle(title); |
| | | reqDTO.setTotalAmount(updateReqVO.getAmount()); |
| | | reqDTO.setApplyDate(updateReqVO.getPayDate() != null ? updateReqVO.getPayDate() : LocalDate.now()); |
| | | reqDTO.setRemark(updateReqVO.getRemark()); |
| | | reqDTO.setBlobIds(updateReqVO.getBlobIds()); |
| | | reqDTO.setExpenseDescription(title); |
| | | financeReimbursementApi.updateReimbursementAndResubmit(reqDTO).getCheckedData(); |
| | | |
| | | // 2. åå课é¢ä¾§å°è´¦ï¼æ¸
空驳åä¿¡æ¯ï¼åå°ãæ¥é审æ¹ä¸ã |
| | | fundRecordMapper.update(null, new LambdaUpdateWrapper<ResearchFundRecordDO>() |
| | | .eq(ResearchFundRecordDO::getId, exist.getId()) |
| | | .set(ResearchFundRecordDO::getBatchName, updateReqVO.getBatchName()) |
| | | .set(ResearchFundRecordDO::getAmount, updateReqVO.getAmount()) |
| | | .set(ResearchFundRecordDO::getPayDate, updateReqVO.getPayDate()) |
| | | .set(ResearchFundRecordDO::getPayee, updateReqVO.getPayee()) |
| | | .set(ResearchFundRecordDO::getRemark, updateReqVO.getRemark()) |
| | | .set(ResearchFundRecordDO::getStatus, ResearchFundStatusEnum.APPROVING.getStatus()) |
| | | .set(ResearchFundRecordDO::getReimbursementNo, reimbursement.getNo()) |
| | | .set(ResearchFundRecordDO::getRejectReason, "") |
| | | .set(ResearchFundRecordDO::getRejectTime, null)); |
| | | |
| | | storageAttachmentApi.updateAttachments("file", FUND_RECORD_TYPE, |
| | | updateReqVO.getId(), updateReqVO.getBlobIds()); |
| | |
| | | exist.getId(), ResearchFundStatusEnum.nameOf(exist.getStatus())); |
| | | } |
| | | |
| | | // è卿¸
çè´¢å¡ä¾§è稿æ¥éåï¼å·²è¢«è´¢å¡ä¾§å 餿¶ç´æ¥è·³è¿ï¼ |
| | | Long reimbursementId = exist.getReimbursementId(); |
| | | if (reimbursementId != null) { |
| | | FinanceReimbursementRespDTO reimbursement = |
| | | financeReimbursementApi.getReimbursement(reimbursementId).getCheckedData(); |
| | | if (reimbursement != null && reimbursement.getStatus() != null) { |
| | | if (!FINANCE_STATUS_DRAFT.equals(reimbursement.getStatus())) { |
| | | throw exception(FUND_REIMBURSEMENT_STATUS_CHANGED, |
| | | reimbursement.getNo(), financeStatusName(reimbursement.getStatus())); |
| | | } |
| | | financeReimbursementApi.deleteReimbursement(reimbursementId); |
| | | } |
| | | } |
| | | |
| | | fundRecordMapper.deleteById(id); |
| | | storageAttachmentApi.deleteAttachmentsByRecord(FUND_RECORD_TYPE, id); |
| | | } |
| | |
| | | return fundRecordMapper.selectListByApplicationId(applicationId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateFundStatusByReimbursement(Long reimbursementId, Integer bpmStatus, String reason) { |
| | | ResearchFundRecordDO fundRecord = fundRecordMapper.selectByReimbursementId(reimbursementId); |
| | | if (fundRecord == null) { |
| | | log.warn("[updateFundStatusByReimbursement] æªæ¾å°å
³èæ¥éå({})çç»è´¹æ¨ä»è®°å½", reimbursementId); |
| | | return; |
| | | } |
| | | |
| | | boolean rejected = BpmTaskStatusEnum.REJECT.getStatus().equals(bpmStatus); |
| | | LambdaUpdateWrapper<ResearchFundRecordDO> update = new LambdaUpdateWrapper<ResearchFundRecordDO>() |
| | | .eq(ResearchFundRecordDO::getId, fundRecord.getId()); |
| | | if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmStatus)) { |
| | | update.set(ResearchFundRecordDO::getStatus, ResearchFundStatusEnum.PAID.getStatus()); |
| | | } else if (rejected) { |
| | | update.set(ResearchFundRecordDO::getStatus, ResearchFundStatusEnum.REJECTED.getStatus()); |
| | | } else { |
| | | // æ¤å/åæ¶ï¼éåãå¾
æ¨ä»ãï¼ä¾è¯¾é¢ä¾§ä¿®æ¹åéæ°åèµ·æ¥é |
| | | update.set(ResearchFundRecordDO::getStatus, ResearchFundStatusEnum.PENDING.getStatus()); |
| | | } |
| | | update.set(ResearchFundRecordDO::getRejectReason, |
| | | rejected ? StrUtil.blankToDefault(reason, "è´¢å¡æªå¡«å驳ååå ") : "") |
| | | .set(ResearchFundRecordDO::getRejectTime, rejected ? LocalDateTime.now() : null); |
| | | fundRecordMapper.update(null, update); |
| | | } |
| | | |
| | | // =================== å
鍿¹æ³ =================== |
| | | |
| | | /** åªæãå¾
æ¨ä»ãæã已驳åãçå°è´¦æè½ä¿®æ¹å¹¶éæ°åèµ·æ¥é */ |
| | | private boolean isEditable(Integer status) { |
| | | return ResearchFundStatusEnum.PENDING.getStatus().equals(status) |
| | | || ResearchFundStatusEnum.REJECTED.getStatus().equals(status); |
| | | } |
| | | |
| | | private ResearchFundRecordDO validateFundRecordExists(Long id) { |
| | | ResearchFundRecordDO fundRecord = fundRecordMapper.selectById(id); |
| | |
| | | return application; |
| | | } |
| | | |
| | | /** ç¶æä¸ºãå·²æ¨ä»ãæ¶å¿
é¡»ä¸ä¼ åè¯éä»¶ */ |
| | | private void validateVoucherRequired(ResearchFundRecordSaveReqVO reqVO) { |
| | | if (ResearchFundStatusEnum.PAID.getStatus().equals(reqVO.getStatus()) |
| | | && CollUtil.isEmpty(reqVO.getBlobIds())) { |
| | | throw exception(FUND_VOUCHER_REQUIRED); |
| | | /** ç»è®°ä¸ä¿®æ¹æ¨æ¬¾é½å¿
é¡»ä¸ä¼ åè¯ï¼åè¯ä¼éèªå¨çæçè´¢å¡æ¥éåé交财å¡å®¡æ¹ */ |
| | | private void validateVoucherRequired(List<Long> blobIds, String batchName) { |
| | | if (CollUtil.isEmpty(blobIds)) { |
| | | throw exception(FUND_VOUCHER_REQUIRED, StrUtil.isBlank(batchName) ? "æ¬æ¬¡" : batchName); |
| | | } |
| | | } |
| | | |
| | | /** æ¥éåæ é¢ï¼è¯¾é¢ã课é¢åãç¬¬ä¸æç»è´¹æ¨æ¬¾ / 课é¢ã课é¢åã第2次ç»è´¹æ¨æ¬¾ */ |
| | | private String buildReimbursementTitle(ResearchApplicationDO application, |
| | | ResearchFundRecordSaveReqVO reqVO, Integer seq) { |
| | | String batch = reqVO.getBatchName(); |
| | | if (StrUtil.isBlank(batch)) { |
| | | int no = seq != null ? seq : fundRecordMapper.selectListByApplicationId(application.getId()).size() + 1; |
| | | batch = "第" + no + "次"; |
| | | } |
| | | return "课é¢ã" + application.getTitle() + "ã" + batch + "ç»è´¹æ¨æ¬¾"; |
| | | } |
| | | |
| | | /** ç´¯è®¡æµ®åºæ ¡éªï¼æ¬æ¬¡ + å·²ç»è®°ï¼æé¤ excludeId èªèº«ï¼ä¸å¾è¶
è¿ç³è¯·é¢ç® */ |
| | |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | } |
| | | |
| | | /** è´¢å¡æ¥éåç¶æä¸æåï¼finance æ¨¡åæªå¯¹å¤æ´é²ç¶ææä¸¾ï¼æ¤å¤æç¶æå¼è½¬å¯è¯»ææ¡ï¼ */ |
| | | private String financeStatusName(Integer status) { |
| | | if (status == null) { |
| | | return "æªç¥"; |
| | | } |
| | | return switch (status) { |
| | | case 0 -> "è稿"; |
| | | case 15 -> "审æ¹ä¸"; |
| | | case 20 -> "å·²éè¿"; |
| | | case 35 -> "已驳å"; |
| | | case 40 -> "已彿¡£"; |
| | | default -> String.valueOf(status); |
| | | }; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.research.service.fund.listener; |
| | | |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener; |
| | | import cn.iocoder.yudao.module.research.service.fund.ResearchFundRecordService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * ç»è´¹æ¨ä»å°è´¦ç¶æçå¬å¨ |
| | | * |
| | | * çå¬è´¢å¡æ¥éåï¼finance_reimbursement_approveï¼ç审æ¹ç»æï¼æç»æååå°è¯¾é¢ä¾§çç»è´¹æ¨ä»å°è´¦ï¼ |
| | | * éè¿ â å·²æ¨ä»(20)ï¼é©³å â 已驳å(30) + 驳ååå /æ¶é´ï¼æ¤åæåæ¶ â éåå¾
æ¨ä»(0)ã |
| | | * ä¸ finance 模åèªå·±ç FinanceReimbursementStatusListener 订é
å䏿µç¨ keyï¼ä¸¤è
äºä¸å¹²æ°ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class ResearchFundStatusListener extends BpmProcessInstanceStatusEventListener { |
| | | |
| | | /** è´¢å¡æ¥éåå®¡æ¹æµç¨å®ä¹ Key */ |
| | | private static final String PROCESS_DEFINITION_KEY = "finance_reimbursement_approve"; |
| | | |
| | | @Resource |
| | | private ResearchFundRecordService fundRecordService; |
| | | |
| | | @Override |
| | | protected String getProcessDefinitionKey() { |
| | | return PROCESS_DEFINITION_KEY; |
| | | } |
| | | |
| | | @Override |
| | | protected void onEvent(BpmProcessInstanceStatusEvent event) { |
| | | Long reimbursementId; |
| | | try { |
| | | reimbursementId = Long.parseLong(event.getBusinessKey()); |
| | | } catch (NumberFormatException e) { |
| | | log.warn("[onEvent] businessKey({}) 䏿¯ææçè´¢å¡æ¥éåç¼å·", event.getBusinessKey()); |
| | | return; |
| | | } |
| | | |
| | | log.info("[onEvent] æ¶å°è´¢å¡æ¥é审æ¹äºä»¶ï¼reimbursementId={}, status={}", reimbursementId, event.getStatus()); |
| | | |
| | | try { |
| | | fundRecordService.updateFundStatusByReimbursement(reimbursementId, event.getStatus(), event.getReason()); |
| | | log.info("[onEvent] ç»è´¹æ¨ä»å°è´¦(æ¥éå {}) ç¶ææ´æ°å®æ", reimbursementId); |
| | | } catch (Exception e) { |
| | | log.error("[onEvent] æ´æ°ç»è´¹æ¨ä»å°è´¦ç¶æå¤±è´¥ï¼reimbursementId={}", reimbursementId, e); |
| | | } |
| | | } |
| | | |
| | | } |