总览
项目概览
业务全景图
核心业务流程
销售流程
采购流程
生产流程
质量流程
仓储流程
售后流程
财务报销流程
会员入会流程
课题管理流程
档案管理流程
结构与数据
系统关系
数据流
业务对象
角色权限
扩展
AI 业务
待确认事项
业务全景图
按业务意义(而非代码包结构)归类的模块-能力思维导图。
系统关系
模块之间的调用与数据依赖:实线=单据/数据流向,虚线=审批回调与辅助能力。
数据流
跨模块单据的生成与回写关系(字段带入、数量状态回写、事件通知)。
核心业务对象
点击对象行查看作用、上游、下游与数据表。对象关系见文末 ER 图(仅核心业务对象)。
对象关系图(ER)
AI 业务
项目 AI 统一采用「业务侧组装 Prompt → 模型 → 结构化 JSON → 人工确认」模式,无 Function Calling;AI 不可用时各功能回退人工。
待确认事项
源码走读中发现与文档/预期不一致、疑似未完成或需业务确认的点,均标注了出处行为。
mindmap
root((MOM 工厂数字化平台))
基础主数据 MDM
物料与SKU
物料分类
计量单位与品牌
仓库主数据
销售管理 CRM
线索
客户与联系人
商机与阶段
报价单
销售合同
开票与回款
销售目标
数据权限与公海
供应商管理 SRM
供应商档案
准入审批
资质证书
招标与比价
绩效评价
进销存与财务 ERP
采购申请
采购订单
采购来票
销售订单
付款单
收款单
结算账户
财务报销 FIN 独立
报销单主表
报销明细行
发票附件上传
提交审批与驳回重提
归档终态
会员管理 UMS 独立
入会申请单
个人与单位二型字段
会员等级个人与单位两套
秘书处理事会两级审批
审批通过自动建会员
自动创建系统登录账号
会员列表与通讯录检索
课题管理 RES 独立
课题指南发布
重点与一般课题分类
指导申报期与截止
在线课题申报书
从会员带出申报人信息
专家评审明细与加权排名
秘书处理事会三级审批
立项编号与立项通知公告
经费拨付记录与凭证
档案管理 ARCHIVE 独立
档案分类书架分层分列
档案文档集中存储与检索
电子附件与实体位置兼具
密级管控与敏感权限
借阅登记与两级审批
归还登记与流转闭环
逾期未还实时提醒
档案存量与流转统计
课题会员财务三方归档联动
生产管理 MES
主生产计划 MPS
生产工单
生产任务
生产报工
工艺路线与工序
工单BOM
研发设计项目
安灯
仓储管理 MES-WM
仓库库区库位
到货通知
采购入库
生产领料与退料
生产入库
销售出库与退货
转移调拨
盘点
库存台账与事务
批次SN条码装箱
质量管理 MES-QC
IQC 来料检验
IPQC 过程检验
OQC 出货检验
RQC 退货检验
NCR 不合格品
质检方案与指标缺陷
智能质检报告 QC-REPORT
报告模板与多版本
可视化设计器
组件绑定与判定规则
HTML 渲染引擎
报告出件与编号
数据快照冻结
设备与排班
设备台账
点检与保养
维修工单
工装夹具
班组班次与排班
售后服务
售后工单
维修记录
退货申请
数据权限
人力资源 HRM
员工档案
请假加班调岗离职
离职交接映射
考勤排班汇总
薪酬核算与发放
协同审批 BPM
Flowable 引擎
业务状态回调监听
AI 智能
发票OCR识别
报价单OCR识别
质检结果判定
物料短缺预测
生产时长与风险预测
交付预测
RAG 知识库
BI 与管理驾驶舱
SQL 配置式大屏
采购销售库存生产质量人力主题
系统底座
认证与RBAC
数据权限
字典
附件中心
定时任务与消息
flowchart TD
A[线索 crm_clue] -->|转化·仅一次| B[客户 crm_customer]
B --> C[联系人 crm_contact]
B --> D[商机 crm_business]
D -->|自定义阶段推进| E{商机结束}
E -->|赢单| F[报价单 QT·草稿0→已转合同10]
E -->|输单或无效| X[结束]
F -->|转合同·带入客户产品折扣| G[合同 HT·草稿0→审批中10]
D -->|直接建合同| G
G -->|BPM审批通过20| H[生成 ERP 销售订单 XSDD]
H -->|提交BPM| I[销售订单审批·审批中15→已审核20]
I -->|明细需生产·自动创建| J[MES 主生产计划 MPS]
I --> K[发货通知单]
K -->|审核通过| L[销售出库单·OQC→拣货→发运→出库完成]
L -->|回写出库数量与状态| M[销售订单 部分出库2/全部出库3]
G --> N[回款计划·按期数分期]
G -->|提交BPM| O[开票 KP·审批中10→通过20·累计不超合同额]
O -->|回款前必须先开票| P[回款 HK·创建即审批中10→手动审核20]
P -->|校验合同剩余额与开票剩余额| N
flowchart TD
S0[SRM 准入申请 AP·待提交0→审批中10→已通过40] --> S1[供应商档案 srm_supplier]
S1 --> S2[资质证书管理]
S1 --> S3[绩效评价·质量交付价格服务四维]
S4[SRM 招标比价·发布→投标→开标→评标→定标] -->|定标审批通过生成订单| C3
C1[采购申请 CGSQ·草稿0→审批中10] -->|提交BPM| C2{审批}
C2 -->|驳回30→可重置回草稿| C1
C2 -->|通过20且有供应商·自动生成| C3[采购订单 CGDD·审批中15→已审核20]
C2 -->|通过20无供应商| C4[手动指定供应商生成订单]
C4 --> C3
C3 -->|确认收货| C5[到货通知单·草稿0→待质检2→待入库3→完成4]
C5 -->|物料需检验·自动创建| C6[IQC 来料检验]
C6 -->|合格1或特采2 可入库| C7[采购入库单·草稿0→待上架2→待执行3→完成4]
C6 -->|不合格退货3| C8[供应商退货·待拣货→待执行→完成·库存扣减]
C6 -->|不合格报废4| C9[NCR 不合格品处置]
C7 -->|回写 inCount 与 inStatus 未入库0部分1全部2| C3
C7 -->|回写申请明细 inCount| C1
C3 -->|订单总价控制| C10[采购来票 FPD·累计金额≤订单总价]
C10 -->|付款单必须关联来票| C11[付款单 FKD·审批中15→已审核20·累计付款≤来票金额]
flowchart TD
P0[销售订单明细 needProduction=1] -->|审批通过自动创建| P1[MPS 主生产计划·草稿0→已下发1]
P1 -->|下发或合并下发| P2[生产工单·草稿0→已确认1]
P2 -->|按工艺路线工序自动生成| P3[生产任务×N·预备0→生产中1→部分完成2→完成4·可暂停9]
P3 --> P4[生产领料 或 线边虚拟库备料]
P4 --> P5[报工提交·草稿0]
P5 -->|校验:上一道工序未报满则拦截| P5
P5 -->|启用BPM则提交审批| P6{报工审批}
P6 -->|驳回| P5
P6 -->|通过且倒冲工序| P7[按工单BOM自动生成物料消耗·扣线边虚拟库FIFO允许负库存]
P6 -->|通过且质检工序| P8[产出行待检→IPQC 过程检验]
P6 -->|通过且非质检关键工序| P9[产品产出直接完工入库]
P8 -->|检验合格| P10[拆合格与不合格行入库]
P8 -->|不合格| P11[NCR 不合格品]
P9 --> P12[进度回写·仅最后一道工序报工才更新工单已生产数量]
P10 --> P12
P12 -->|已生产数量≥计划数量·自动| P13[工单完成2]
P12 -->|累计| P14[MPS 回写已生产数量并判断完成2]
P14 -->|全部完成| P15[发布 ProductionFinishedEvent→回写销售订单生产状态]
flowchart TD
T1[到货通知单 或 外协入库单] --> A1[IQC 来料检验·草稿0→完成4]
T2[报工质检工序通过后产出行] --> A2[IPQC 过程检验·草稿0→完成4]
T3[销售出库单提交] --> A3[OQC 出货检验·草稿0→完成4]
T4[生产退料单 或 销售退货单 或 售后退货] --> A4[RQC 退货检验·草稿0→完成4]
A1 --> R{检验判定 MesQcCheckResultEnum}
A2 --> R
A3 --> R
A4 --> R
R -->|1 合格| Q1[允许入库·回写来源单据推进状态]
R -->|2 特采| Q2[允许入库·并生成NCR留痕]
R -->|3 不合格退货| Q3[生成NCR·走供应商退货或销售退货]
R -->|4 不合格报废| Q4[生成NCR·走报废出库]
A2 -->|合格数量| Q5[报工转完成·产出拆行入库]
A3 -->|完成| Q6[销售出库单推进待拣货]
A4 -->|完成| Q7[退货单推进上架或入库·售后回调结论]
N1[NCR 待评审0] -->|评审| N2[已评审6]
N2 -->|处置方式:退货1报废2返工3让步接收4降级使用5| N3[已处置7]
N3 -->|关闭| N4[已关闭8]
Q8[支撑数据:质检方案·检验指标·缺陷库·指标结果] --- A1
Q8H["检验指标的层级可在质检指标页维护·条目类型 所属分组 公式 排序号·只允许两层·删分组级联删子项"] --- Q8
A1 -->|出件 generate-from-qc| GATE{出件六道校验·按业务优先级只报第一处}
A2 -->|出件 generate-from-qc| GATE
A3 -->|出件 generate-from-qc| GATE
A4 -->|出件 generate-from-qc| GATE
GATE -->|000 类型非法| GE0[105_000 qcType 不在 1~4]
GATE -->|001 单据不存在| GE1[105_001]
GATE -->|002 未完成检验| GE2[105_002·带当前状态中文名]
GATE -->|003 未填判定| GE3[105_003·列出四个可选判定]
GATE -->|005 模板类型不符| GE5[105_005·两边类型中文名都给·前端按 reportType 预过滤]
GATE -->|006 无可用检验项| GE6[105_006]
GATE -->|通过·只允许同类型已发布模板| RP[智能质检报告平台 qcreport]
RP --> RPT[报告模板 qc_report_template·启用0停用1]
RPT --> RPTV[模板版本 qc_report_template_version·草稿0已发布1已停用2·当前版本不可停用 101_010]
RPTVSAVE[设计器保存 create 或 update] -->|写入侧闸门·规则101_006 与画布安全101_009 不合格一律不落库| RPTV
RPTVSAVE -.->|只卡新写入·存量脏画布不回溯核查| CVNOTE[画布校验覆盖三处注入面·tagName 属性名 整段CSS]
RPTV -->|按已发布版本渲染| RPI[报告实例 qc_report_instance·编号 QR+yyyyMMdd+4位流水·按天独立]
RPI --> SNAP[冻结 data_snapshot·判定后数据含 PASS FAIL 与合格率]
RPI --> RHTML[render_html 完整 HTML 文档·出站已剥离事件属性与危险协议]
RPI --> RREGEN[重新生成 regenerate·冻结快照+同一模板版本重渲·数据与编号不变·并作废已归档PDF]
RPI --> RPDF[导出PDF 后端调Chromium打印已存HTML·归档 system_storage_attachment·recordType=qc_report_instance]
RPI --> RUI[报告实例页 /qc/report-instance·菜单挂质量管理 parent_id=5500]
RUI -->|权限码| RPERM["qc-report:instance:query 查询·:export 导出PDF·:delete 删除·:create 通用出件·:generate 质检单出件(menu 1075416)"]
RUI -->|反查 businessType=mes_qc_iqc 等表名 + businessId| RBACK[同一张质检单可出多份报告·历史留痕需要·不做重复拦截]
RUI --> RPREVIEW[详情弹窗·iframe sandbox空属性渲染 render_html·数据快照页签展示冻结 data_snapshot]
A1 -.->|前端入口·行操作「出报告」仅 status=已完成可见| UIREP[出报告弹窗·IQC IPQC OQC RQC 四页共用]
A2 -.->|同上| UIREP
A3 -.->|同上| UIREP
A4 -.->|同上| UIREP
UIREP -->|只列 reportType 与本单一致·启用·当前版本已发布且画布非空·避免选中必被拒的组合| UIPICK[用户选模板]
UIPICK -->|POST generate-from-qc| GATE
UIREP -->|结果就地展示 reportNo itemCount| UIRES["undecidableCount>0 蓝色信息条(多为过程参数无判定规则·黄色会几乎每单误报)·warnings 与 errors 逐条展示·不落库事后看不到"]
UIRES -->|查看报告列表| RUI
RUI -->|路由 query 带入 businessType+businessId 并预填搜索| RBACK
GATE -->|MesQcReportApi.getQcReportData| MESMAP[MES 四层取数归一·单头 / 判定依据行 max min threshold / 样品 indicator_result / 实测值 result_detail]
MESMAP --> RCTX[报告上下文 report+inspectionItems·由后端映射器产出·前端不再自己拼]
RCTX --> RCITEM[检验项=样品×指标交叉展开·全指标进不过滤·多样品时样品号折进 remark]
RCTX --> RCQC[携带单据原判定 qcResult 数·qcResultText 中文·与引擎判定并存互不覆盖]
MESMAP -->|分组项 item_type=2 与它的子项按 parent_id 还原两层·归属不看 type 也不看行序| RCTXG
RCTXG["分组还原·组头行背组名与 formula_text 公式·组内第一行背 span=该组总行数·同组其余行 span=1 且 hidden 让位·合并的是模板 columns 里带 # 的那一列(默认列即检验项目)·合并行数是本单该组实际行数而非主数据子项数·该组本单无子项行则不合并"] --- RCTX
MESMAP -.->|分组项本单没有属于它的子项 / 组头本单没有行由后端补一行| RCWARN
MESMAP -.->|指标已删 / 未录实测值(组头锚点行按定义无值·不报) / 样品超 3 个·进 warnings| RCWARN
RCWARN[warnings 软提示·不落库·事后看不到需自行留痕] --- RCTX
RCITEM --- RCTX
RCQC --- RCTX
RCTX --> RPI
RCTX --> RUNDEC["undecidableCount 没有判定结论的项数=快照里 result 为空串的项·含无判定规则与待判定两种·不计入合格率分母与报告结论·生成时弹提示不回填"]
RPT -->|进入设计器并带 templateId·权限 qc-report:template:ai-import| AIIMP[AI导入 qc-report/ai-import/draft]
AISRC["源文件 扫描件照片·电子版PDF·Word(.docx) Excel(.xlsx)·txt csv"] -->|上传走 system Storage API 取 blobId·绑为 qc_report_template 附件| AIIMP
AISRC -.->|同一模板重复导入按替换处理·先删旧附件再绑新的·连同 blob 行与磁盘文件一起清| AIIMP
AISRC -.->|docx 的 Word 页眉页脚读取并以 页眉 页脚 标记并入识别内容·页眉在正文前页脚在正文后·同时进 warnings·扫描件照片不受影响| AIIMP
AIIMP -->|识别·只产草稿不落库| AIRD[模板草稿 扁平组件+属性清单]
AIHINT[积木清单每项带 hint 选型说明·来自前端注册表 aiHint·组件选型的唯一真相来源] -.->|选型以 hint 为准·有专门组件就不退用通用组件凑数| AIIMP
AIIMP -->|表格末行的落款签署行属落款不属数据行·与原件页脚合并且人名日期留空手填·不得自造绑定键| AIRD
AIIMP -.->|原件列比默认多或表头分两层或样品字段不同时·写进组件的 columns headerSpans fields 三个文本属性覆盖·不换组件| AIRD
AIKEY[报告可绑定键白名单·由后端 ReportFields 反射生成·不手写] -.->|只禁编造不给可选集合模型只能猜·故全量枚举| AIIMP
AIRD -->|人工在设计器确认·装配器编译进画布后保存| RPTV
AIRD -.->|画布上的 ReportHeader ReportFooter 是正文里的抬头落款·与 PDF 每页重复的版式页眉页脚不是一回事| RPTV
AIIMP -.->|表头某列自己既是列名又是上格·原件里是一格纵向合并跨住上下两层、下层那格在提取文本里写着↑同上| AIRD
AIIMP -.->|该段标题与列名一字不差才认成纵向合并格、出 rowspan=2 一格且下层跳过该列·不一致就被当成另一层分组标题、结论二字上下各印一遍| AIRD
RPTVSAVE -.->|设计器画布不跑绑定·组名格的 hidden 占位符会被浏览器当成真 hidden 让整行左移、末列挤成竖排细条| CVNOTE
RPTVSAVE -.->|自定列不带宽度声明·列宽只能由最小内容宽度倒推·而值是占位符这类不含空格的长串·整表会被撑出纸张、末列挤成竖条| CVWIDTH
CVWIDTH["故自定列的单元格带 overflow-wrap:anywhere 允许长串折行·默认列有手工宽度声明不加·实测加了反而把检验项目子项挤到 30 余像素、行高翻几倍"] --- RPTVSAVE
flowchart LR
subgraph INB [入库·事务IN·库存加]
I1[采购入库]
I2[生产入库单]
I3[报工产出自动入库]
I4[销售退货入库]
I5[外协入库]
I6[杂项入库]
end
subgraph OUTB [出库·事务OUT·库存减]
O1[销售出库]
O2[生产领料]
O3[物料消耗倒冲·允许负库存]
O4[外协发料]
O5[生产退料回仓]
O6[供应商退货]
O7[杂项出库·调整或报废]
end
W[(库存台账 mes_wm_material_stock 物料×仓库×库区×库位×批次×供应商)]
INB -->|getOrCreate 加数量| W
OUTB -->|校验可用量后扣减| W
W -->|占用预留 reservedQuantity| RES[库存占用 销售出库·领料·外协·杂项·调拨]
MV[转移调拨·内部或外部] -->|成对事务 MOVE_OUT+MOVE_IN 在途| W
ST[盘点 方案→任务→明细行→结果] -->|盘盈 ADJUST_IN·盘亏 ADJUST_OUT·可冻结库存| W
W --> TX[事务流水 mes_wm_transaction 只读全量留痕]
BT[批次 mes_wm_batch·SN码·条码·装箱嵌套] --- W
WIP[[线边虚拟库 WIP_VIRTUAL_WAREHOUSE·懒初始化]] --- O3
FR[四级冻结:仓库·库区·库位·库存记录] --- W
flowchart TD
F1[客户反馈·后台人工录入工单·关联客户联系人销售订单合同] --> K1[售后工单·草稿0]
K1 -->|assignTicket 分配处理人| K2[处理中10·问题判定:一般1维修2退货3·严重度0-3]
K2 -->|维修类| R1[维修记录·待处理0→维修中10→已完成20→已关闭30·现场返厂远程]
R1 -->|completeRepair| K4[已完结50]
K2 -->|退货类创建退货申请| T1[退货申请·草稿0]
T1 -->|approveReturn 审核通过| T2[已审核20·自动创建MES销售退货单]
T2 --> T3[MES 销售退货·草稿→待检验RQC→待上架→待入库→完成]
T3 -->|质检结论回调 onReturnQualityFinished 合格特采退货报废| T4[已质检40]
T3 -->|入库完成回调 onReturnInboundFinished| T5[已入库50]
T5 -->|退款完成回调 onRefundCompleted 记录实际退款额| T6[已退款60]
T6 --> T7[已关闭70]
T2 -.->|状态流转中| T8[审核中10·预留未启用]
K2 -->|退货链路联动工单| K3[待入库30→待退款40]
K3 --> K4
K2 -->|resolveTicket| K4
K4 -->|closeTicket| K5[已关闭60]
K1 -->|cancelTicket| K9[已取消99]
K2 -->|cancelTicket| K9
PM[数据权限 bizType+bizId+userId+级别 负责人只读读写·我负责我参与下属全部四视图] --- K1
flowchart LR
MDM[MDM 主数据 物料单位仓库品牌分类] --> MES[MES 生产·仓储·质量·设备]
MDM --> ERP[ERP 采购·销售·财务]
MDM --> CRM
CRM[CRM 线索客户商机报价合同回款] -->|合同生成销售订单| ERP
SRM[SRM 供应商准入资质证书招标绩效] -->|定标生成采购订单| ERP
ERP -->|确认收货生成到货通知| MES
ERP -->|销售订单审批生成MPS| MES
MES -->|入库出库回写单据进度| ERP
MES -->|ProductionFinishedEvent| ERP
MES -->|退货质检入库回调| AS[售后工单维修退货]
CRM -->|客户主数据| AS
HRM[HRM 员工入转调离交接考勤薪酬] -.->|expandUserIds 数据可见性扩展·接口已就绪待各模块接入| CRM
BPM[BPM Flowable 审批引擎] -.->|状态事件回调·15个监听器| ERP
BPM -.-> CRM
BPM -.-> SRM
BPM -.-> MES
BPM -.-> HRM
AI[AI 平台 通义千问+Milvus] -.->|发票OCR| ERP
AI -.->|报价OCR| CRM
AI -.->|质检判定与生产预测| MES
MES -.->|质检单上下文·本轮由调用方传入 待 MesQcReportApi 打通| QCR[智能质检报告 qcreport 模板版本实例快照]
QCR -.->|PDF 归档·后续轮次| STG
MES --> BI[BI 管理驾驶舱 SQL配置大屏]
ERP --> BI
CRM --> BI
HRM --> BI
SYS[系统底座 认证·RBAC·字典·附件中心·定时任务] --- MDM
SYS --- MES
STG[附件中心 storage-blob+attachment 全模块统一挂附件] --- ERP
FIN[财务报销 独立模块 yudao-module-finance 报销单 明细 发票附件] -.->|复用 BPM 审批与状态回调| BPM
FIN -.->|发票走附件中心 recordType=finance_reimbursement| STG
FIN -.->|"对外仅提供 yudao-module-finance-api(FinanceReimbursementApi)供他模块建单"| ERP
UMS[会员管理 独立模块 yudao-module-ums 入会申请 会员 通讯录] -.->|复用 BPM 两级审批与状态回调| BPM
UMS -.->|证明材料走附件中心 recordType=ums_application / ums_member| STG
UMS -.->|审批通过经 AdminUserApi.createUser 建系统登录账号| SYS
UMS -.->|独立模块·不与其它业务模块产生单据或数据关联| ERP
RES[课题管理 独立模块 yudao-module-research 指南 申报书 专家评审 经费拨付] -.->|复用 BPM 三级审批与状态回调·流程 key=research_topic_approve| BPM
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
ARC[档案管理 独立模块 yudao-module-archive 分类 档案 借阅 归还 统计] -.->|复用 BPM 两级审批与状态回调·流程 key=archive_borrow_approve| BPM
ARC -.->|档案电子附件走附件中心 recordType=archive_document / archive_borrow| STG
RES -->|已立项申报单归档·经 yudao-module-archive-api 生成档案并回写 archive_document_id| ARC
UMS -->|正常状态会员归档·经 yudao-module-archive-api 生成档案并回写 archive_document_id| ARC
FIN -->|已通过报销单归档·同事务叠加生成「保密」档案并回写 archive_document_id| ARC
ARC -.->|不反向依赖 ums / finance / research·仅提供 -api 子模块由三方手动调归档| RES
flowchart LR
subgraph S1 [销售前端 CRM]
CL[线索] --> CU[客户]
CU --> BU[商机]
BU --> QU[报价单]
QU --> CT[合同]
CT --> IV[开票]
IV --> RK[回款]
CT --> PL[回款计划]
end
subgraph S2 [执行链 ERP+MES]
SO[销售订单] --> MP[MPS]
MP --> WO[工单]
WO --> TK[任务]
TK --> FB[报工]
FB --> PP[产品产出]
PR[采购申请] --> PO[采购订单]
PO --> AN[到货通知]
AN --> IR[采购入库]
end
subgraph S3 [仓储与财务]
ST[库存台账]
PS[销售出库]
RC[收款单]
PI[采购来票] --> PA[付款单]
end
CT -->|generateSaleOrder 带入客户产品折扣定金·回写orderId| SO
SO -->|审批通过带入 saleOrderId 行ID 数量 客户 交期| MP
PO -->|确认收货带入订单行物料供应商数量| AN
AN -->|IQC完成后生成·带入合格行| IR
FB -->|BOM倒冲扣减| ST
PP -->|IN事务入库| ST
IR -->|IN事务入库·回写inCount| PO
PS -->|OUT事务出库·回写outCount| SO
FB -->|最后一道工序回写已生产数量| WO
FB -->|ProductionFinishedEvent 回写生产状态| SO
IV -->|回款强制先开票| RK
RC -->|关联CRM客户校验| CU
PA -->|关联来票与供应商| PI
subgraph S4 [智能质检报告 qcreport]
RPT[报告模板] --> RPTV[模板版本]
RPTVSAVE[设计器保存 create 或 update] -->|写入侧闸门 规则101_006 画布安全101_009 不合格不落库| RPTV
RPTVSAVE -.->|只卡新写入 存量脏画布不回溯核查| CVNOTE[画布校验覆盖 tagName 属性名 整段CSS 三处注入面]
RPTV --> RPI[报告实例]
RPI --> SNAP[数据快照冻结]
RPI --> RHTML[HTML 渲染产物]
RPI --> RPDF[PDF 产物]
AISRC[源文件 扫描件照片·电子版PDF·Word Excel·txt csv] -->|上传走 system Storage API 取 blobId 并绑为模板附件| AIRD[AI 识别草稿]
AIRD -->|人工在设计器确认后保存| RPTV
end
QCDOC[质检单 IQC IPQC OQC RQC] -->|generate-from-qc·带 qcType qcId templateId| QCGATE{五道校验 类型 存在 已完成 已判定 模板类型 有检验项}
QCGATE -->|任一不过·按业务优先级只报第一处| QCERR[105_000~105_006]
QCGATE -->|通过| MESQCAPI[MesQcReportApi 四层取数·单头 判定依据行 样品 实测值]
MESQCAPI -->|纯函数映射器归一 含原判定 qcResult qcResultText| RPI
MESQCAPI -.->|分组标题跳过 指标已删 未录实测值 样品超3| QCWARN[warnings 软提示·不落库]
QCWARN -.-> RPI
RPI -.->|undecidableCount=快照 result 为空串的项·生成时弹提示| QCFE
RPI -.->|businessType=mes_qc_iqc 等表名 + businessId 反查·一单可出多份| QCFE
RPT -.->|report_type 数字字符串须等于 qcType·前端据此过滤模板列表| QCGATE
RPTV -->|模板停用后不再出新件·历史实例不受影响·当前版本不可停用 101_010| RPI
RPT -->|进入设计器带 templateId 调 AI 导入| AIRD
RPI -->|列表 详情 预览 打印| QCFE["前端报告页面 /qc/report-instance 已落地·iframe 渲染 render_html + 快照页签 + 导出PDF"]
RPDF -->|归档 附件中心 recordType=qc_report_instance| PDFARCH[system_storage_attachment]
AISRC -.->|归属 附件中心 recordType=qc_report_template| PDFARCH
AISRC -.->|同一模板重复导入按替换处理·先删旧附件·连同 blob 行与磁盘文件一起清| PDFARCH
QCFE -.->|权限码 qc-report:instance:query/export/delete/create 已入 system_menu| SYS1[system_menu]
QCGATE -.->|权限码 qc-report:instance:generate 已入 system_menu id=1075416| SYS1[system_menu]
QCDOC -.->|前端入口 行操作「出报告」仅 status=已完成可见·四页共用同一弹窗| UIREP[出报告弹窗·只列同类型 启用 且有生效版本的模板]
UIREP -->|选模板后 POST generate-from-qc| QCGATE
UIREP -.->|结果就地展示 reportNo itemCount 与 undecidableCount 告警| QCFE
QCFE -.->|进入时带 businessType+businessId 路由 query·预填搜索表单的「业务单据」字段| UIREP
RPT -.->|权限码 qc-report:template:ai-import 已入 system_menu| SYS1
subgraph S5 [独立财务报销 finance]
RBM[报销单 finance_reimbursement] --> RBI[报销明细 finance_reimbursement_item]
RBM --> RBA[发票附件 recordType=finance_reimbursement]
RBM --> RBS[状态 草稿0 审批中15 已通过20 已驳回35 已归档40]
end
RBM -->|create 带主表与 items 数组与 blobIds 一次性提交| RBI
RBI -.->|invoiceAmount 求和回填 totalAmount·用户可手改·后端不校验一致性| RBM
RBM -->|submit 带 id 与 processDefinitionKey 走 query| RBS
RBS -.->|BPM 监听器结果回写 通过20 驳回35 取消退回0| RBM
RBA -.->|上传与保存分离·禁在业务表存文件地址| PDFARCH
FINNOTE[独立模块·销售采购链条任意单据均不生成报销单·报销单亦不回写任何外部单据·唯一例外是课题经费拨付] -.-> RBM
subgraph S6 [独立课题管理 research]
RGL[课题指南 research_guideline] --> RAP[课题申报书 research_application]
RAP --> RRV[专家评审明细 research_topic_review]
RAP --> RFR[经费拨付记录 research_fund_record]
RAP --> RST[状态 草稿0 审批中15 已立项20 已驳回35]
end
UMSM[会员 ums_member] -->|"选会员带出 applicantName workUnit jobTitle contactPhone contactEmail·软关联无外键"| RAP
RGL -->|"申报时引用·要求 publishStatus=已发布20 且 现在在 applyStartTime 至 applyEndTime 内"| RAP
RAP -->|"category 冗余自指南·不信任前端传值"| RAP
RAP -->|"submit 带 id 与 processDefinitionKey 走 query·回写 processInstanceId"| RST
RST -.->|"BPM 监听器 ResearchApplicationStatusListener 回写 通过20 驳回35 取消退回0"| RAP
RAP -->|"审批通过后 approveApplication 生成 researchNo LX 与 approveTime·已有编号幂等跳过"| RAP
RRV -->|"recalculate: compositeScore 加权 0.3/0.3/0.2/0.2 → ranking 降序重排 → 主单 reviewAvgScore 与 reviewPass"| RAP
RRV -.->|"明细删空时主单汇总清为 null"| RAP
RAP -->|"publishNotice 生成 system_notice 公告并回写 noticeId·重复发布拦截"| SYS2[system_notice 系统公告]
RFR -->|"金额校验 已登记 + 本次 不得超出 budgetAmount 申请经费"| RAP
RFR -.->|"凭证走附件中心 recordType=research_fund_record·同一批 blob 双绑 finance_reimbursement·表内不存文件地址"| PDFARCH
RAP -.->|"申报附件 recordType=research_application"| PDFARCH
RGL -.->|"指南附件 recordType=research_guideline"| PDFARCH
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
subgraph S7 [独立档案管理 archive]
ACD[档案分类 archive_category 树形] --> ADO[档案 archive_document]
ADO --> ABR[借阅单 archive_borrow]
ADO --> AST[档案状态 10在库 20借出中]
ABR --> ABS[借阅状态 0草稿 15审批中 20借出中 30已归还 35已驳回]
end
ACD -->|"新建档案按分类带出 default_secret_level 默认密级·财务分类=3 保密"| ADO
ADO -.->|"电子附件 recordType=archive_document·表内不存文件地址"| PDFARCH
ADO -->|"档案编号 DA + yyyyMMdd + 6位流水(Redis·每日重置)·借阅单号 JY + 同日流水"| ADO
RAP -->|"手动「归档」经 yudao-module-archive-api.archiveBySource(sourceType=2·密级 2内部·sourceNo=立项编号·blobIds=申报书附件)·幂等"| ADO
UMSM -->|"手动「归档」(sourceType=3·密级 2内部·sourceNo=会员编号·blobIds=会员材料)"| ADO
RBM -->|"既有 archive 归档同事务叠加 archiveBySource(sourceType=4·密级 3保密·sourceNo=报销单号·blobIds=发票附件)·报销单 20→40 与生成档案两表并写"| ADO
ADO -->|"回写来源表 archive_document_id 作为已归档硬标记·来源侧重复点归档按其错误码拦截并给出已生成档案编号"| RAP
ADO -->|"回写 archive_document_id"| RBM
ABR -->|"submit 前校验: 同一档案不得已有 审批中 15 或 借出中 20 的借阅单·命中报已借用(带档案名与已存在借阅单号)"| ABS
ABS -.->|"BPM 监听器 ArchiveBorrowStatusListener 回写 通过20 驳回35 取消退回0"| ABR
ABS -->|"业务动作: 归还登记 仅放行 20 借出中 → 30 已归还·回写 returnTime 与归还确认人"| ABR
ABR -->|"审批通过条件更新 archive_document SET status=20 WHERE status=10·归还条件更新回 10·影响 0 行即报冲突并回滚"| AST
ABR -.->|"逾期不落库·查询时实时计算 status=20 且 return_deadline 早于今天·overdue-page 为独立入口非查询参数"| ABS
ADO -.->|"密级=3 保密 且无 archive:document:sensitive 时·详情报错·列表与导出强制过滤 secret_level 不等于 3"| SEC3[权限点 archive:document:sensitive]
ARCNOTE[独立模块·三方归档为列表页手动按钮而非事件驱动·归档只生成档案不回写来源单据业务状态(财务侧 20→40 是既有逻辑·本模块仅叠加)] -.-> ADO
erDiagram
crm_customer ||--o{ crm_business : "拥有商机"
crm_business ||--o{ crm_sale_quotation : "形成报价"
crm_sale_quotation |o--o| crm_contract : "转为合同"
crm_contract ||--o| erp_sale_order : "生成销售订单"
crm_contract ||--o{ crm_receivable_plan : "分期计划"
crm_contract ||--o{ crm_invoice : "开票"
crm_invoice ||--o{ crm_receivable : "凭票回款"
erp_sale_order ||--o{ mes_pro_mps : "需生产行触发"
mes_pro_mps ||--o{ mes_pro_work_order : "下发工单"
mes_pro_work_order ||--o{ mes_pro_task : "按工序拆任务"
mes_pro_task ||--o{ mes_pro_feedback : "报工"
mes_pro_work_order ||--o{ mes_pro_work_order_bom : "工序投料BOM"
erp_purchase_request ||--o{ erp_purchase_order : "生成采购订单"
erp_purchase_order ||--o| mes_wm_arrival_notice : "确认收货"
mes_wm_arrival_notice ||--o| mes_qc_iqc : "触发IQC"
mes_wm_arrival_notice ||--o{ mes_wm_item_receipt : "生成采购入库"
erp_sale_order ||--o{ mes_wm_product_sales : "销售出库"
mes_wm_product_sales ||--o| mes_qc_oqc : "触发OQC"
mes_pro_feedback ||--o| mes_qc_ipqc : "质检工序触发IPQC"
mes_pro_feedback ||--o{ mes_wm_product_produce : "产出入库"
mes_pro_feedback ||--o{ mes_wm_item_consume : "BOM倒冲消耗"
mes_qc_iqc ||--o| mes_qc_ncr : "不合格生成NCR"
mes_wm_item_receipt ||--o{ mes_wm_material_stock : "库存增加"
mes_wm_material_stock ||--o{ mes_wm_transaction : "事务流水"
mes_wm_material_stock }o--|| mes_wm_batch : "按批次"
after_sale_ticket ||--o{ after_sale_return : "退货申请"
after_sale_return ||--o| mes_wm_return_sales : "生成MES退货单"
mdm_item ||--o{ erp_sale_order_items : "销售明细"
mdm_item ||--o{ erp_purchase_order_items : "采购明细"
mdm_item ||--o{ mes_wm_material_stock : "库存物料"
srm_supplier ||--o{ erp_purchase_order : "供货"
srm_supplier ||--o{ mes_wm_arrival_notice : "到货来源"
erp_purchase_order ||--o{ erp_purchase_invoice : "来票"
erp_purchase_invoice ||--o{ erp_finance_payment : "付款"
ums_application ||--o| ums_member : "审批通过自动建档"
hrm_employee ||--o| hrm_user_handover : "离职交接映射"
qc_report_template ||--o{ qc_report_template_version : "多版本"
qc_report_template_version ||--o{ qc_report_instance : "冻结出件版本"
finance_reimbursement ||--o{ finance_reimbursement_item : "费用明细"
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 : "申报人(软关联无外键)"
archive_category ||--o{ archive_document : "分类归档(树形书架)"
archive_document ||--o{ archive_borrow : "借阅登记"
research_application ||--o| archive_document : "已立项归档(archive_document_id)"
ums_member ||--o| archive_document : "正常会员归档(archive_document_id)"
finance_reimbursement ||--o| archive_document : "已通过报销归档(archive_document_id)"
flowchart TD
U1[采购员上传发票文件 blobId] --> O1{文件类型}
O1 -->|图片 png/jpg/gif/bmp| O2[chatWithImage 多模态视觉模型]
O1 -->|PDF| O3[PDFBox 抽取文本 → chat]
O1 -->|txt/csv| O4[直读文本 → chat]
O2 --> O5[JSON 发票号 抬头 供应商 金额 税率 日期]
O3 --> O5
O4 --> O5
O5 --> O6[预填采购来票表单·人工确认]
Q1[销售上传报价单 PDF/Word/Excel/图片] --> Q2[POI/PDFBox/视觉识别]
Q2 --> Q3[JSON 报价头+产品明细行] --> Q4[预填报价单表单]
J1[质检单头+指标结果+缺陷记录] --> J2[业务侧组装Prompt → chat]
J2 --> J3[MdmItemApi 物料名·SrmSupplierApi 供应商名·CrmCustomerApi 客户名 拼入上下文]
J3 --> J4[建议结果:合格/特采/退货/报废+理由+要点]
J4 --> J5[质检员参考判定·AI不可用时提示人工判定]
R1[工单BOM+库存可用量+已投料] --> R2[物料短缺预测·风险等级与缺口清单]
R3[工序标准工时+设备每小时产量+传送倍率] --> R4[生产时长预测]
R5[IPQC缺陷率+设备保养点检+物料可用率+关键工序] --> R6[生产风险预测]
R7[进度+剩余天数+任务完成状态+客户交期] --> R8[交付预测·能否按时+置信度+延误因素]
W1[质检员上传既有检验报告文件 blobId] --> W2{扩展名与内容判定}
W2 -->|png/jpg/bmp/gif/webp| W3[原字节走 chatWithImage]
W2 -->|PDF 有文本层| W4[PDFBox 抽取文本 → chat]
W2 -->|PDF 扫描版| W5[PDFRenderer 逐页转PNG → 每页 chatWithImage]
W2 -->|docx/xlsx| W6["POI 抽取·表格归一成稳定网格(gridSpan 补空占位 / vMerge 续格标 ↑同上)"]
W2 -->|txt/csv| W7[直读文本 → chat]
W2 -->|doc/xls| W8[拒绝·提示另存为 docx/xlsx]
W3 --> W9[多页逐页识别]
W4 --> W9
W5 --> W9
W6 --> W9
W7 --> W9
W9 --> W10["按(type,props)去重合并→扁平组件草稿+summary+warnings"]
W10 --> W11[弹窗预览·人工确认后装进设计器画布]
W11 --> W12[人工调整→保存为模板版本·这是唯一落库点]
WCL[组件积木清单由前端从活注册表生成并随请求上传] --- W9
WSAFE[只产草稿不落库·未注册type在装配阶段被跳过·永远产不出任意HTML] --- W10
KB1[知识库文档上传URL] --> KB2[POI/Tika提取文本] --> KB3[切片约800tokens→向量化→Milvus]
KB3 --> KB4[分段检索接口 topK+相似度阈值]
KB4 -.-> KB5[暂未接入业务问答流程·待确认]
MODE[模型层:通义千问为主·预留DeepSeek/OpenAI/Ollama未实现] --- O2
NOTE[全项目无Function Calling·AI只输出结构化JSON由业务侧解析] --- J2
flowchart TD
U1["报销人填报报销单·主表: 报销单号(选填) 报销标题 报销总金额 申请日期 备注"] --> U2["录入报销明细 1..n 行: 费用类型 发票号码 发票金额 发票日期 开票方 费用说明"]
U2 --> U3[发票附件: 图片或 PDF 先传 system storage-blob upload 取 blobId]
U3 --> S1[保存 create·主表与明细与全部 blobIds 一次性提交]
S1 --> G1["报销单号:可自定义;留空(含纯空格)则由后端生成 BX + yyyyMMdd + 6位流水(Redis·每日重置)"]
G1 --> B1["明细先删后增全量覆盖·提交剥掉行 id(软删后重插避免主键冲突)"]
B1 --> A1["附件绑定 recordType = finance_reimbursement·按该单全部 blobId 全量替换"]
A1 --> K1[草稿 0]
K1 -->|update 修改主表 明细 附件| K1
K1 -->|submit 选审批流程 processDefinitionKey| K2[审批中 15·回写 processInstanceId]
K2 -->|BPM 审批通过| K3[已通过 20]
K2 -->|BPM 审批驳回| K4[已驳回 35]
K2 -->|BPM 审批取消| K1
K4 -->|改发票后重新 submit| K2
K3 -->|archive 归档| K5[已归档 40·终态·写入 archiveTime]
D1["仅草稿 0 可 delete·连带清理明细与发票附件"] -.-> K1
E1["仅草稿 0 与已驳回 35 可 update·其余状态只读"] -.-> K4
N1["独立模块·与销售采购链条任何单据均无关联;唯一例外是被课题经费拨付 1:1 自动生成(经 yudao-module-finance-api)"] --- K1
flowchart TD
A1[填报入会申请·选会员类型 1个人 / 2单位] --> A2[个人分支: 姓名 联系电话 邮箱 工作单位 职称 研究方向 行业 地区]
A1 --> A3[单位分支: 单位名称 法定代表人 统一社会信用代码 研究方向 行业 地区]
A2 --> A4[选申请等级·按会员类型切换字典 ums_personal_grade / ums_unit_grade]
A3 --> A4
A4 --> A5[证明材料附件: 先传 system storage-blob upload 取 blobId]
A5 --> S1[保存 create·附件按该单全部 blobIds 绑定]
S1 --> G1["申请编号 SQ + yyyyMMdd + 6位流水(Redis·每日重置)·后端生成不可改"]
G1 --> K1[草稿 0]
K1 -->|update 修改申请| K1
K1 -->|submit 选审批流程 processDefinitionKey| K2[审批中 15·回写 processInstanceId]
K2 -->|BPM 审批通过| K3[已通过 20]
K2 -->|BPM 审批驳回| K4[已驳回 35]
K2 -->|BPM 审批取消| K1
K4 -->|修改后重新 submit| K2
K3 --> M1["审批通过钩子: 自动创建会员 ums_member (内部先查状态确为已通过才执行)"]
M1 --> M2["会员编号 HY + yyyyMMdd + 6位流水(Redis)"]
M2 --> M3["创建系统登录账号 AdminUserApi.createUser·用户名与初始密码=联系电话·昵称=申请人姓名·部门=学会会员"]
M3 --> M4[会员落库·入会日期=当天·状态 1正常·来源申请单 applicationId 回填]
M4 --> D2[会员列表·可手工 create / update / delete]
D2 --> V1["等级类型校验: 单位会员(memberType=2) 不可选『理事长』(memberGrade=5) 直接拒绝"]
M4 --> D1[会员通讯录·只读·按地区 regionCode 与行业 industry 检索]
ATT1["附件 recordType = ums_application"] -.-> K1
ATT2["附件 recordType = ums_member"] -.-> M4
RES1["仅草稿 0 可 delete·连带清理附件"] -.-> K1
RES2["仅草稿 0 与已驳回 35 可 update·其余状态只读"] -.-> K4
ROL["审批链: BPM 流程定义 ums_membership_approve(归属分类 ums_membership_approve) 秘书处初审 → 理事会审议·两节点审批人=角色策略(超管角色兜底)·后端按分类实时取流程、不写死 key"] -.-> K2
F1["审批中心看单: 流程定义表单类型=自定义表单·查看路径 /ums/application/detail/approve/index.vue·按 businessKey 回显申请单"] -.-> K2
N1["独立模块·不与其他业务模块产生单据关联·仅复用 BPM 审批与 system 附件中心"] --- K1
flowchart TD
subgraph P1 [课题指南发布]
G0[新建指南·选类别 1重点课题 / 2一般课题] --> G1[填指南名称 申报起止时间 指南正文 附件]
G1 --> G2["指南编号 GL + yyyyMMdd + 6位流水(Redis·每日重置)"]
G2 --> G3[草稿 0·仅草稿可改可删]
G3 -->|已产生申报单则禁止删除| G3B["提示该指南下已有 N 张申报单·需先处理申报单"]
G3 -->|publish 发布| G4["已发布 20·回写 publishTime"]
G4 -->|close 截止| G5[已截止 30]
end
G4 -->|"指南已发布才可作为申报前提"| A1
subgraph P2 [在线申报]
A1[选指南·要求已发布 且在申报期内] --> A2[选会员 ums_member 自动带出 姓名 工作单位 职称 电话 邮箱]
A2 --> A3[填课题名称 课题组成员 申请经费 申报书正文 申报附件]
A3 --> A4["申报编号 SB + yyyyMMdd + 6位流水·类别冗余自指南不信任前端传值"]
A4 --> K1[草稿 0]
end
K1 -->|update 修改·仅草稿 0 与已驳回 35 放行| K1
K1 -->|delete 删除·仅草稿 0 放行·连带清理附件| K1
K1 -->|submit 选审批流程 processDefinitionKey| K2["审批中 15·回写 processInstanceId"]
K1 -->|"submit 前逐条校验: ① 指南必须已发布 ② 当前时间必须在申报起止期内"| KERR["任一不满足即拒绝提交·提示带指南名与实际状态或起止时间"]
K2 -->|"仅审批中可增删改专家评分"| RK[专家评审明细 research_topic_review·一位专家一行]
RK -->|"后端逐行重算 compositeScore = 选题0.3 + 方案0.3 + 团队0.2 + 成果0.2"| RC[按加权分降序重排名次 ranking]
RC -->|"回写主单: reviewAvgScore=全部专家均分 · reviewPass=均分达标 且 多数结论为推荐立项"| SUM[申报单评审汇总·删除最后一条明细时清空汇总]
SUM -->|"秘书处汇总申报书与评审结果"| K3
K2 --> K3
subgraph P3 [立项审批 BPM research_topic_approve]
K3["三节点顺序·审批方法与审批人在流程定义内配置"] --> KA[Activity_secretariat_review 秘书处形式审查]
KA -->|通过| KB[Activity_expert_review 专家评审]
KB -->|通过| KC[Activity_council_approve 学会立项审批]
end
KC -->|BPM 审批通过| K4["已立项 20·监听器生成 立项编号 LX + yyyyMMdd + 6位流水 与 approveTime·已有编号则幂等跳过"]
KC -->|BPM 审批驳回| K5[已驳回 35]
KC -->|BPM 审批取消| K1
KA -->|驳回| K5
K5 -->|修改后重新 submit| K2
K4 -->|publishNotice 发布立项通知| N1["system_notice 公告·标题『关于公布立项课题的通知』·正文含课题名 立项编号 类别 申报人 单位 资助金额·回写 noticeId·重复发布被拦截"]
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·同一批 blob 双绑 finance_reimbursement(按 recordType+recordId 隔离互不影响)"] -.-> F1
ROL["审批中心看单: 流程定义表单类型=自定义表单·创建路径 /research/application/index · 查看路径 /research/application/detail/approve/index.vue·按 businessKey 回显申报单"] -.-> K3
ROL2["审批人取值: 三节点在流程定义内配好审批方法(依次审批)与审批人策略·部署后由管理员在 BPM 流程设计器按学会实际组织调整·提交时前端只让选流程不选审批人"] -.-> K3
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 为软关联(无外键)·对财务模块走 -api 子模块本地调用·仅复用 BPM 审批、system 公告与附件中心"] --- K1
flowchart TD
subgraph P1 [档案分类·书架管理 archive_category]
C1[新建分类·可选父分类形成分类树] --> C2["填 分类名称 · 编码 code · 排序 · 分类说明 · 默认密级 · 状态"]
C2 --> C3["编码全局唯一 uk_code · 状态 0启用 1停用 · 默认密级 1公开 2内部 3保密"]
C3 --> C4["初始 6 条分类: 会员档案 member · 课题档案 research · 会议档案 meeting · 财务档案 finance(默认密级=保密 3) · 文书档案 document · 党建档案 party"]
C4 --> C5["可改可删 · 有子分类禁删 · 该分类下有档案禁删 · 父分类不能是自身或其子分类 · 停用分类不能新增档案"]
end
subgraph P2 [档案管理 archive_document]
D1["新建档案: 标题 · 分类 · 密级 · 载体(1电子 2实体 3电子+实体) · 归档日期 · 摘要 · 关键词 tags"] --> D2["实体位置四字段: 书架号 shelfNo · 层号 layerNo · 列号 columnNo · 册号档案盒 boxNo · 存放位置描述 storePlace"]
D2 --> D3["电子附件走 system 附件中心 · recordType=archive_document · 表内不存文件地址 · blobIds 为全量替换语义"]
D3 --> D4["档案编号 DA + yyyyMMdd + 6位流水 (Redis·每日重置)"]
D4 --> D5["状态 10 在库 · 可改可删"]
D5 -->|"借阅审批通过"| D6["状态 20 借出中 · 禁改 · 存在未归还借阅单时禁删"]
D6 -->|"归还登记"| D5
end
subgraph P3 [三方归档联动·列表页手动「归档」按钮→yudao-module-archive-api]
AD["ArchiveDocumentApi.archiveBySource 幂等: 先按 source_type + source_id 查 · 命中直接返回既有档案 ID"]
AD2["按 categoryCode 取分类(member / research / finance) · 分类不存在报 DOCUMENT_SOURCE_CATEGORY_NOT_EXISTS"]
AD3["生成 DA 编号 + 落库 + bindAttachments(recordType=archive_document)"]
AD4["回写来源表 archive_document_id 作为已归档硬标记 · 来源侧重复归档按其自身错误码拦截并给出已生成档案编号(archive 侧 DOCUMENT_DUPLICATE_SOURCE 为兜底)"]
R1["课题申报书 research_application · 仅 status=20 已立项 · 权限 research:application:archive"] -->|"sourceType=2 · 密级 2内部 · sourceNo=立项编号 · blobIds=申报书附件"| AD
M1["会员 ums_member · 仅 status=1 正常 · 权限 ums:member:archive"] -->|"sourceType=3 · 密级 2内部 · sourceNo=会员编号"| AD
F1["财务报销单 finance_reimbursement · 仅 status=20 已通过 · 权限 finance:reimbursement:archive"] -->|"sourceType=4 · 密级 3保密 · sourceNo=报销单号 · blobIds=发票附件 · 与既有 20→40 归档同事务叠加"| AD
AD --> AD2
AD2 --> AD3
AD3 --> AD4
end
AD3 -->|"归档结果: 新档案直接落为 在库 10"| D5
subgraph P4 [借阅登记与审批 archive_borrow]
B1["登记借阅: 选档案(仅 在库 10 可选) · 借阅人 · 部门 · 联系电话 · 借阅日期 · 借阅目的 · 归还期限"] --> B2["借阅单号 JY + yyyyMMdd + 6位流水 (Redis·每日重置) · 状态 0 草稿"]
B2 --> B3["submit 前校验: 同一档案不得存在 审批中 15 或 借出中 20 的借阅单 · 命中报 已借用(带档案名与已存在借阅单号)"]
B3 --> B4["submit 传 id 与 processDefinitionKey (query 参数) · 先解析流程列表再建单(无已发布流程则直接报错·不留孤儿草稿) · 状态 15 审批中 · 回写 processInstanceId"]
B4 --> B5["BPM 流程 archive_borrow_approve 两级: 档案管理员审核 → 分管领导审批"]
end
B5 -->|"审批通过"| B6["状态 20 借出中 · 回写 approveTime · 条件更新档案 SET status=20 WHERE status=10(影响 0 行则报 档案已被占用 并回滚)"]
B5 -->|"审批驳回"| B7["状态 35 已驳回 · 回写驳回原因与时间 · 修改后可重新 submit"]
B5 -->|"取消流程"| B2
B6 -->|"归还登记 return · 条件更新 status=20 → 30"| B8["状态 30 已归还 · 回写 returnTime 与归还确认人 · 归还备注"]
B8 -->|"条件更新档案 SET status=10 WHERE status=20"| D5
B6 -->|"仅 0 草稿 与 35 已驳回 可改可重提 · 仅 0 草稿 可删"| B2
B6 -->|"仅 20 借出中 可登记归还"| B8
OV["逾期不落库·查询时实时计算: status=20 且 return_deadline 早于今天 · overdueDays = 今天 减 归还期限"] -.-> B6
OVP["GET /archive/borrow/overdue-page 独立入口(非查询参数) · 列表「逾期」列渲染红色「逾期 N 天」 · 不建 infra_job 不发站内信 · 列表页另有「只看逾期」切换"] -.-> OV
ST["档案统计 GET /archive/stat/overview: 档案总数 · 在库数 · 借出中数 · 逾期未还数 + 按分类/按密级/按载体 三组分布"] -.-> D5
SEC["敏感档案管控: 密级=3 保密 且当前用户无 archive:document:sensitive 时 · 详情接口直接报错 · 列表与导出强制过滤 secret_level 不等于 3"] -.-> D1
ATT["附件 recordType = archive_document / archive_borrow"] -.-> D3
ROL["审批中心看单: 流程定义表单类型=自定义表单 · 创建路径 /archive/borrow/index · 查看路径 /archive/borrow/detail/approve/index.vue · 按 businessKey 回显借阅单"] -.-> B5
LIS["监听器 ArchiveBorrowStatusListener(流程 key=archive_borrow_approve · businessKey=借阅单 ID): 通过→20 借出中 + approveTime 并条件更新档案 → 20 · 驳回→35 + 原因与时间 · 取消→退回 0 · 与 finance/research 监听器订阅不同 key 互不干扰"] -.-> B5
BOUND["独立模块 yudao-module-archive(含 -api 子模块)·依赖 system/bpm·不反向依赖 ums/finance/research(避免循环依赖)·三方仅依赖 archive-api 手动调归档"] --- D1