From befe939222e83119518e010328cf5d078bda973e Mon Sep 17 00:00:00 2001 From: zichun <26684461+reporkey@users.noreply.github.com> Date: Tue, 21 Jul 2026 09:22:41 +0800 Subject: [PATCH] Add viw_kg_edge_flow: ERP document-flow KG edges (L2) --- sql/viw_kg_edge_flow.sql | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+), 0 deletions(-) create mode 100644 sql/viw_kg_edge_flow.sql diff --git a/sql/viw_kg_edge_flow.sql b/sql/viw_kg_edge_flow.sql new file mode 100644 index 0000000..b910ca5 --- /dev/null +++ b/sql/viw_kg_edge_flow.sql @@ -0,0 +1,63 @@ +-- ============================================================ +-- 视图:viw_kg_edge_flow —— ERP「业务单据流转」知识图谱·流转边 (L2, ⭐最高价值) +-- 一条边 = 源单据 --生成--> 目标单据 (报价→订单→工单→领料→入库→送货→对账→发票→收款) +-- +-- 边的来源:低代码平台把「生成下游单据」的按钮存成从表控件 +-- gdsconfigformslave.sControlName LIKE 'BtnCopyTo.<目标动作>' +-- 例:BtnCopyTo.ActDeliverGoods (中文=生成送货单) +-- +-- 目标表单如何解析(与存储过程 Sp_Ai_AddCommonAfterNew 完全一致): +-- 该过程按 (源菜单 + 按钮中文名) 定位到这条 BtnCopyTo 从表控件, +-- 直接取其 sActiveId 作为「目标菜单窗体 id」(= gdsmodule.sId)。 +-- 即:sControlName 里的 .ActXxx 只是标签,真正的目标存在 sActiveId。 +-- 过程随后 SELECT sChinese FROM gdsmodule WHERE sId = sActiveId 取目标名, +-- 并 SELECT sTbName FROM gdsconfigformmaster WHERE sParentId=sActiveId AND bGrd=0 取目标表。 +-- 本视图照搬这套解析。 +-- +-- 只取「真正的边」,剔除配置噪声: +-- 保留 BtnCopyTo.(携带 sActiveId 的主按钮) +-- 剔除 .slave / .Detail(从表映射伴生行,无 sActiveId)、裸 BtnCopyTo(按钮容器) +-- 剔除 sActiveId 指向本库不存在的菜单(跨租户/已删,约 8 行) +-- +-- 节点粒度 = 菜单窗体 gdsmodule.sId(= 接口 sModelsId,也是 BtnCopyTo 的目标粒度)。 +-- 端点富化的数据源 = 该菜单下 bGrd=0 的主表单 sTbName(与过程取表逻辑一致)。 +-- +-- 校验(本地库 xlyweberp_saas):411 条边 / 405 对 (源,目标) / 51 条自环(补单·追加同单) +-- 端点 401/405 命中 viw_ai_useful_forms(业务表单目录高度对齐)。 +-- ============================================================ +CREATE OR REPLACE VIEW viw_kg_edge_flow AS +SELECT + CONCAT(e.src_id, '>', e.tgt_id, '>', e.action_code) AS sEdgeKey, -- 稳定边键(源>目标>动作) + e.src_id AS sSrcModuleId, -- 源菜单窗体id (= 接口 sModelsId) + src.sChinese AS sSrcName, -- 源单据名称 + src.sModelType AS sSrcModelType, -- 源前端路由/业务域 + (SELECT f.sTbName FROM gdsconfigformmaster f + WHERE f.sParentId = e.src_id AND f.bGrd = 0 AND IFNULL(f.sTbName,'') <> '' + ORDER BY f.iOrder, f.iIncrement LIMIT 1) AS sSrcDataSource, -- 源主数据源(表/视图) + e.btn AS sBtnLabel, -- 业务动作(按钮中文名, 如 生成送货单) + e.action_code AS sActionCode, -- 目标动作码(如 ActDeliverGoods) + e.tgt_id AS sTgtModuleId, -- 目标菜单窗体id (= sActiveId) + tgt.sChinese AS sTgtName, -- 目标单据名称 + tgt.sModelType AS sTgtModelType, -- 目标前端路由/业务域 + (SELECT f.sTbName FROM gdsconfigformmaster f + WHERE f.sParentId = e.tgt_id AND f.bGrd = 0 AND IFNULL(f.sTbName,'') <> '' + ORDER BY f.iOrder, f.iIncrement LIMIT 1) AS sTgtDataSource, -- 目标主数据源(表/视图) + CAST(e.src_id = e.tgt_id AS UNSIGNED) AS bSelfLoop, -- 1=自环(补单/追加同单) + CAST(EXISTS(SELECT 1 FROM viw_ai_useful_forms u WHERE u.sModuleId = e.src_id) AS UNSIGNED) AS bSrcUseful, -- 源命中业务表单目录 + CAST(EXISTS(SELECT 1 FROM viw_ai_useful_forms u WHERE u.sModuleId = e.tgt_id) AS UNSIGNED) AS bTgtUseful -- 目标命中业务表单目录 +FROM ( + SELECT DISTINCT + m.sParentId AS src_id, -- 主表单所属菜单 = 源 + s.sActiveId AS tgt_id, -- BtnCopyTo 目标菜单 + s.sChinese AS btn, + SUBSTRING_INDEX(s.sControlName, '.', -1) AS action_code + FROM gdsconfigformslave s + JOIN gdsconfigformmaster m ON s.sParentId = m.sId + JOIN gdsmodule tgt0 ON s.sActiveId = tgt0.sId -- 目标菜单须真实存在 + WHERE s.sControlName LIKE 'BtnCopyTo.%' + AND s.sControlName NOT LIKE '%.slave' + AND s.sControlName NOT LIKE '%.Detail' + AND IFNULL(s.sActiveId, '') <> '' +) e +JOIN gdsmodule src ON e.src_id = src.sId -- 源菜单须真实存在 +JOIN gdsmodule tgt ON e.tgt_id = tgt.sId; -- libgit2 0.22.2