UNPKG

vue-willtable

Version:
343 lines (310 loc) 9.97 kB
# 快速上手 完整操作示例的工作区主要由菜单、画布以及表单弹窗三部分构成。组件自带菜单与画布,表单弹窗样式与内部表单由使用方自定义。代码示例如下: [POPE 运营操作代码示例](http://git.xiaojukeji.com/global-fe/marketing-group/open-source/strategyjs/tree/master/example/pages/pope) [普通事件流代码示例](http://git.xiaojukeji.com/global-fe/marketing-group/open-source/strategyjs/tree/master/example/pages/common) 如果只需流程图展示,只定义节点以及数据渲染画布即可。代理示例如下: [数据库运行代码示例](http://git.xiaojukeji.com/global-fe/marketing-group/open-source/strategyjs/tree/master/example/pages/readonly) [发布流水线代码示例](http://git.xiaojukeji.com/global-fe/marketing-group/open-source/strategyjs/tree/master/example/pages/pipeline) ## 1. 定义菜单数据 具体参数见 [节点菜单属性](/api/attributes.html#节点菜单属性) ```javascript import React from "react"; import { uuid } from "@didi/strategy"; import { Form, Input, Select, Button } from "antd"; import { CopyOutlined, DeleteOutlined } from "@ant-design/icons"; export const menuList = [ { menu: "triggers", name: "用户事件", nodeKey: "userEvent", nodeType: "multi", icon: "icon-pope pope-Submit", iconBgColor: "#5BB357", nodeBusType: "trigger", defaultPaths: [ { name: "Path 1", }, ], renderForm: (props) => { const { form } = props; return ( <Form {...props}> <Form.Item shouldUpdate> {({ getFieldValue }) => { const paths = getFieldValue("paths"); return ( <> {(paths || []).map((path, index) => ( <div className="mulit-path-item" key={path.key}> <p className="mulit-path-item-header">Path {index + 1}</p> <div className="actions"> <Button icon={ <CopyOutlined onClick={() => { form.setFieldsValue({ paths: [ ...paths, { key: uuid.v4(), name: "", data: null }, ], }); }} /> } /> {paths.length > 1 && ( <Button icon={<DeleteOutlined />} onClick={() => { form.setFieldsValue({ paths: paths.filter((v) => v.key !== path.key), }); }} /> )} </div> <Form.Item noStyle name={["paths", index, "key"]}> <span /> </Form.Item> <Form.Item name={["paths", index, "name"]} rules={[{ required: true, message: "请输入名称" }]} > <Input placeholder="请输入" /> </Form.Item> <Form.Item name={["paths", index, "data", "type"]} rules={[{ required: true, message: "请选择类型" }]} > <Select placeholder="请选择" getPopupContainer={(e) => e.parentNode} > <Select.Option value="bubble" key="bubble"> 冒泡 </Select.Option> <Select.Option value="finish_order" key="finish_order" > 完单 </Select.Option> </Select> </Form.Item> </div> ))} </> ); }} </Form.Item> <div> <Button block onClick={() => { const paths = form.getFieldValue("paths") || []; form.setFieldsValue({ paths: [...paths, { key: uuid.v4() }] }); }} > Add Path </Button> </div> </Form> ); }, }, ]; ``` ## 2. 编写表单弹窗 根据 `nodeClick` 获取当前触发点击的节点,表单弹窗动态渲染不同表单 ```javascript import React from "react"; import { Form, message } from "antd"; const Drawer = (props) => { const { currentNode, setCurrentNode, saveNodeData } = props; const [formRef] = Form.useForm(); const FormCom = currentNode?.renderForm; React.useEffect(() => { formRef.resetFields(); if (currentNode) { if (currentNode.nodeType === "multi") { formRef.setFieldsValue(currentNode); } else { formRef.setFieldsValue(currentNode.nodeDetail); } } }, [currentNode, formRef]); return ( <div className="strategy-drawer" style={{ right: currentNode ? 0 : -400 }}> <div className="strategy-drawer-header"> <div className="strategy-drawer-title">{currentNode?.name}</div> <i className="icon-pope pope-Close" onClick={() => { setCurrentNode(null); }} /> </div> {FormCom && <FormCom labelCol={{ span: 24 }} form={formRef} />} <div className="strategy-drawer-footer"> <div className="strategy-button" onClick={() => { formRef .validateFields() .then((res) => { if (currentNode) { if (currentNode.nodeType === "normal") { currentNode.nodeDetail = res; } if (currentNode.nodeType === "multi") { Object.keys(res).forEach((key) => { currentNode[key] = res[key]; }); } } saveNodeData(currentNode); setCurrentNode(null); }) .catch((err) => { if (err.errorFields) { err.errorFields.map((item) => message.error(item.errors?.join(",")) ); } }); }} > Done </div> </div> </div> ); }; export default Drawer; ``` ## 3. 使用组件 获取初始数据、设置数据、传入菜单列表数据以及传入相应的回调方法 ```javascript import React, { useRef } from "react"; import "@didi/strategy/dist/strategy.css"; import { StrategyEditor, uuid } from "@didi/strategy"; import { menuList } from "./menuList"; const App = () => { const strategyRef = useRef(null); const [currentNode, setCurrentNode] = React.useState(null); const nodeClick = (node) => { setCurrentNode(node); }; React.useEffect(() => { // 获取初始数据 const data: StrategyMetadata = { nodeMap: { "00": { nodeId: "00", nodeKey: "group", nodeType: NodeType.normal, nodeBusType: "common", nodeDetail: { id: "123456", }, }, "01": { nodeId: "01", nodeKey: "userEvent", nodeType: NodeType.multi, nodeBusType: "trigger", paths: [ { key: "01", name: "冒泡", data: { type: "bubble", }, }, { key: "02", name: "完单", data: { type: "finish_order", }, }, ], }, "02": { nodeId: "02", nodeKey: "userAttr", nodeBusType: "condition", nodeType: NodeType.multi, paths: [ { key: "03", name: "数量大于1", data: { type: "amount", }, }, ], }, "03": { nodeId: "03", nodeKey: "coupon", nodeBusType: "action", nodeType: NodeType.normal, nodeDetail: { content: "ddd", }, }, "04": { nodeId: "04", nodeKey: "placeholder", nodeType: NodeType.placeholder, }, }, edgeMap: { "00": { edgeId: "00", startNodeId: "00", endNodeId: "01", }, "01": { edgeId: "01", edgeName: "冒泡", startNodeId: "01", endNodeId: "02", }, "02": { edgeId: "02", edgeName: "完单", startNodeId: "01", endNodeId: "04", }, "03": { edgeId: "03", edgeName: "数量大于1", startNodeId: "02", endNodeId: "03", }, }, }; // 设置画布数据 strategyRef.current?.setData(data); }, []); return ( <div className="app"> <StrategyEditor editorStyle={{ height: "calc(100% - 50px)" }} ref={strategyRef} NodeMenuList={NodeMenuList} nodeClick={nodeClick} /> <Drawer currentNode={currentNode} setCurrentNode={setCurrentNode} saveNodeData={strategyRef.current.saveNodeData} /> </div> ); }; export default App; ```