From 607f62b89eedb761c31e98eea259bbdd4ba5f639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=8E=E6=B0=B8=E9=A1=BA?= <971387674@qq.com> Date: Thu, 30 Nov 2023 13:47:44 +0800 Subject: [PATCH] =?UTF-8?q?feature/2.9.42310.01-=E8=96=AA=E8=B5=84?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=8B=93=E6=89=91=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/config.js | 1 + src/pages/ledgerSalaryItemDiagram/index.tsx | 120 ++++++++++++++++++++ src/pages/salaryItemDiagram/index.tsx | 32 ++++-- 3 files changed, 146 insertions(+), 7 deletions(-) create mode 100644 src/pages/ledgerSalaryItemDiagram/index.tsx diff --git a/src/layouts/config.js b/src/layouts/config.js index c6231a0..2aa7204 100644 --- a/src/layouts/config.js +++ b/src/layouts/config.js @@ -14,6 +14,7 @@ module.exports = { "/commonTable.*": "blank", "/calcTable.*": "blank", "/salaryItemDiagram.*": "blank", + "/ledgerSalaryItemDiagram.*": "blank", "/salaryItemFlowGraph.*": "blank", "/welfareLedgerTable.*": "blank", "/payrollFilesTable.*": "blank", diff --git a/src/pages/ledgerSalaryItemDiagram/index.tsx b/src/pages/ledgerSalaryItemDiagram/index.tsx new file mode 100644 index 0000000..38fe574 --- /dev/null +++ b/src/pages/ledgerSalaryItemDiagram/index.tsx @@ -0,0 +1,120 @@ +/* + * Author: 黎永顺 + * name: 薪资账套-薪资项目查看 + * Description: + * Date: 2023/11/30 + */ +import type { MutableRefObject } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; +import { notification } from "antd"; +import type { RelationGraphExpose, RGNode, RGNodeSlotProps, RGOptions } from "relation-graph/react"; +import RelationGraph from "relation-graph/react"; +import { exceptStr } from "@/utils/common"; +import { extractTree } from "@/pages/salaryItemDiagram"; +import cs from "classnames"; +import styles from "../salaryItemFlowGraph/index.less"; + +const NodeSlot: React.FC = ({ node }) => { + if (node.id === "0") { + return
{node.text}
; + } + // @ts-ignore + if (node.id !== "0" && !node.data.parentId) { + return
{node.text}
; + } + return
+ {node.text} +
; +}; +const Index: React.FC = () => { + const [itemsTree, setItemsTree] = useState([]); + const [i18n, setI18n] = useState({}); + const graphRef = useRef() as MutableRefObject; + useEffect(() => { + window.parent.postMessage({ type: "initDiagram" }, "*"); + window.addEventListener("message", receiveMessageFromIndex, false); + return () => { + window.removeEventListener("message", receiveMessageFromIndex, false); + }; + }, []); + const receiveMessageFromIndex = (event: any) => { + const data: any = exceptStr(event.data); + if (!_.isEmpty(data)) { + const { itemsTree, i18n } = data; + setI18n(i18n); + setItemsTree(itemsTree); + } + }; + const dataSource: any = useMemo(() => { + return { + rootId: "0", + nodes: [{ id: "0", text: i18n["薪资项目"] }, ..._.map(extractTree(itemsTree), o => ({ + id: o.salaryItemId, + text: o.salaryItemName, data: { ...o } + }))], + lines: _.map(extractTree(itemsTree), o => ({ + from: o.parentId ? o.parentId : "0", + to: o.salaryItemId + })) + }; + }, [itemsTree, i18n]); + useEffect(() => { + if (!_.isEmpty(dataSource.nodes) && !_.isEmpty(dataSource.lines)) { + const init = showGraph(); + } + }, [dataSource]); + const showGraph = async () => { + await graphRef.current.setJsonData(dataSource, (graphInstance) => { + }); + }; + const options: RGOptions = useMemo(() => { + return { + debug: false, + layout: { + label: "树", + layoutName: "tree", + layoutClassName: "seeks-layout-center", + from: "left", + // 通过这4个属性来调整 tree-层级距离&节点距离 + min_per_width: 500, + max_per_width: 500, + min_per_height: 60, + max_per_height: undefined + // levelDistance: "" // 如果此选项有值,则优先级高于上面那4个选项 + }, + defaultExpandHolderPosition: "right", + defaultNodeWidth: 180, + defaultNodeHeight: 50, + defaultLineShape: 4, + defaultNodeBorderWidth: 1, + defaultLineColor: "#333", + defaultExpandHolderColor: "rgba(0, 206, 209, 1)", + defaultNodeColor: "transparent", + defaultNodeBorderColor: "#333", + allowShowMiniToolBar: false //工具栏展示与否 + }; + }, []); + const onNodeClick = (node: RGNode) => { + if (node.type === "node") { + // @ts-ignore + const { formula } = node?.data; + notification.destroy(); + if (_.isEmpty(formula)) return; + const { formula: description } = formula; + notification.open({ + message: i18n["公式"], + duration: null, + description, + style: { maxWidth: 600 } + }); + } + return true; + }; + return
+ +
; +}; +export default Index; diff --git a/src/pages/salaryItemDiagram/index.tsx b/src/pages/salaryItemDiagram/index.tsx index 29024c0..4b29c25 100644 --- a/src/pages/salaryItemDiagram/index.tsx +++ b/src/pages/salaryItemDiagram/index.tsx @@ -72,8 +72,31 @@ const index: FunctionComponent = (props) => { nodeCfg: { getChildren, autoWidth: true, + title: { + style: { fill: "#333" }, + containerStyle: () => { + return { + fill: "#f7fbfe", + stroke: "#e5e5e5" + }; + } + }, + nodeStateStyles: { + hover: { + stroke: '#e5e5e5', + lineWidth: 1, + }, + }, items: { - layout: "follow" + style: (cfg: any, group: any, type: string) => { + const styles = { + value: { fill: "#333" } + }; + return styles[type]; + } + }, + style: { + stroke: "#e5e5e5" } }, markerCfg: (cfg: any) => { @@ -82,11 +105,6 @@ const index: FunctionComponent = (props) => { show: (g_level === 0 && !_.isEmpty(dataSource.children)) || getStorageIds(dataSource.children).includes(id) }; }, - layout: { - direction: "LR", - getVGap: () => 10, - getHGap: () => 80 - }, onReady: (graph: any) => { graph.on("node:click", (evt: any) => { if (_.isEmpty(evt.target.attrs) || JSON.stringify(evt.target.attrs).indexOf("cursor") !== -1) return; @@ -96,7 +114,7 @@ const index: FunctionComponent = (props) => { graph.zoom(1); }); }, - behaviors: ["drag-canvas", "zoom-canvas", "drag-node"] + behaviors: ["drag-canvas", "zoom-canvas"] }; // @ts-ignore return !_.isEmpty(dataSource) ? : null;