@hzab/flowlong-designer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ # @hzab/flowlong-designer@0.0.1
2
+ 组件初始化
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # @hzab/flowlong-designer
2
+
3
+ 组件模板
4
+
5
+ - node@16.16.0
6
+
7
+ - 注意:首次克隆先执行 npm run prepare 命令
8
+
9
+ # 组件
10
+
11
+ ## 示例
12
+
13
+ ```jsx
14
+ import Demo from "@hzab/flowlong-designer";
15
+
16
+ <Demo />;
17
+ ```
18
+
19
+ ## API
20
+
21
+ ### InfoPanel Attributes
22
+
23
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
24
+ | ------ | ------ | ---- | ------ | ----------------- |
25
+ | schema | Object | 是 | - | 数据信息的 schema |
26
+
27
+ # 组件开发流程
28
+
29
+ - 在 config/webpack.config.js 中按需修改 library 配置的文件名
30
+ - 在 config/webpack.config.js 中按需修改 alias 配置的包名,便于本地调试
31
+ - 在 tsconfig.json 中按需修改 paths 配置的包名,解决 ts 报错问题
32
+ - npm run dev
33
+
34
+ ## 文件目录
35
+
36
+ - example 本地开发测试代码
37
+ - src 组件源码
38
+
39
+ ## 命令
40
+
41
+ - Mac 执行该命令,设置 pre-commit 为可执行文件
42
+
43
+ - npm run mac-chmod
44
+ - chmod +x .husky && chmod +x .husky/pre-commit
45
+
46
+ - 生成文档:npm run docs
47
+ - 本地运行:npm run dev
48
+ - 打包编译:npm run build
49
+
50
+ ## 发布
51
+
52
+ - 注意:示例代码生效,但发布之后未生效。确认是否执行了编译!!!
53
+
54
+ - 编译组件:npm run build
55
+ - 命令:npm publish --access public
56
+ - 发布目录:
57
+ - src
58
+
59
+ ## 配置
60
+
61
+ ### 配置文件
62
+
63
+ - 本地配置文件:config/config.js
64
+
65
+ ### webpack 配置文件
66
+
67
+ - config/webpack.config.js
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@hzab/flowlong-designer",
3
+ "version": "0.0.1",
4
+ "description": "自定义审批流配置组件",
5
+ "main": "src",
6
+ "scripts": {
7
+ "dev": "webpack serve -c ./config/webpack.config.js --env local",
8
+ "build": "webpack -c ./config/webpack.config.js --env production",
9
+ "publish-patch": "npm version patch && npm publish --access public",
10
+ "publish-minor": "npm version minor && npm publish --access public",
11
+ "publish-major": "npm version major && npm publish --access public",
12
+ "prepare": "husky install",
13
+ "mac-chmod": "chmod +x .husky && chmod +x .husky/pre-commit",
14
+ "docs": "typedoc"
15
+ },
16
+ "files": [
17
+ "src",
18
+ "CHANGELOG.md"
19
+ ],
20
+ "keywords": [],
21
+ "author": "CaiYansong",
22
+ "license": "ISC",
23
+ "devDependencies": {
24
+ "@hzab/permissions": "0.1.1",
25
+ "@hzab/webpack-config": "^0.7.1",
26
+ "@types/react": "^17.0.62",
27
+ "@types/react-dom": "^17.0.20",
28
+ "antd": "^4.14.0",
29
+ "axios": "^1.4.0",
30
+ "eslint": "^8.30.0",
31
+ "less": "^4.1.3",
32
+ "mobx": "^6.7.0",
33
+ "mobx-react": "^7.6.0",
34
+ "react": "^17.0.2",
35
+ "react-dom": "^17.0.2",
36
+ "react-router-dom": "^6.14.1",
37
+ "typedoc": "^0.24.8",
38
+ "typescript": "^4.9.4"
39
+ },
40
+ "directories": {
41
+ "src": "src"
42
+ },
43
+ "lint-staged": {
44
+ "**.{js,jsx,ts,tsx,css,scss,less,json,html}": [
45
+ "prettier --write"
46
+ ]
47
+ },
48
+ "dependencies": {
49
+ "nanoid": "^3.3.7"
50
+ }
51
+ }
@@ -0,0 +1,42 @@
1
+ import { nanoid } from "nanoid";
2
+
3
+ /**
4
+ * 流程数据
5
+ */
6
+ export interface IConfig {
7
+ /** 流程名称 */
8
+ name?: string;
9
+ }
10
+
11
+ /**
12
+ * 节点数据
13
+ */
14
+ export interface INodeConfig {
15
+ /** 节点名称 */
16
+ nodeName?: string;
17
+ }
18
+
19
+ /**
20
+ * 获取初始节点数据
21
+ * @param nodeConfig
22
+ * @param {Object} data 流程信息
23
+ * @param {Object} nodeConfig 节点数据
24
+ * @returns
25
+ */
26
+ export const getInitNodeData = function (data: IConfig = {}, nodeConfig: INodeConfig = {}) {
27
+ const id = nanoid();
28
+ const res = {
29
+ id: id,
30
+ name: data.name,
31
+ key: "k" + id,
32
+ nodeConfig: {
33
+ nodeName: nodeConfig.nodeName ?? "发起人",
34
+ nodeKey: "flk" + id,
35
+ type: 0,
36
+ nodeAssigneeList: [],
37
+ ...nodeConfig,
38
+ },
39
+ ...data,
40
+ };
41
+ return res;
42
+ };
@@ -0,0 +1,38 @@
1
+ .add-node-box {
2
+ width: 240px;
3
+ display: inline-flex;
4
+ flex-shrink: 0;
5
+ position: relative;
6
+ z-index: 1;
7
+ &:before {
8
+ content: "";
9
+ position: absolute;
10
+ top: 0px;
11
+ left: 0px;
12
+ right: 0px;
13
+ bottom: 0px;
14
+ z-index: -1;
15
+ margin: auto;
16
+ width: 2px;
17
+ height: 100%;
18
+ background-color: rgb(202, 202, 202);
19
+ }
20
+ .add-node-btn-box {
21
+ user-select: none;
22
+ width: 240px;
23
+ padding: 20px 0px 32px;
24
+ display: flex;
25
+ justify-content: center;
26
+ flex-shrink: 0;
27
+ flex-grow: 1;
28
+ }
29
+ }
30
+ .add-node-popover-body {
31
+ .add-node-popover-btn {
32
+ display: inline-block;
33
+ width: 80px;
34
+ margin: 0 8px;
35
+ text-align: center;
36
+ cursor: pointer;
37
+ }
38
+ }
@@ -0,0 +1,119 @@
1
+ import { Button, Popover } from "antd";
2
+ import { PlusOutlined, UserOutlined, ShareAltOutlined, SendOutlined } from "@ant-design/icons";
3
+ import { nanoid } from "nanoid";
4
+ import _ from "lodash";
5
+
6
+ import "./index.less";
7
+
8
+ /**
9
+ * 节点类型
10
+ */
11
+ export const NODE_TYPE = {
12
+ /** 审批节点 */
13
+ approvalNode: "ApprovalNode",
14
+ /** 抄送节点 */
15
+ ccNode: "CcNode",
16
+ /** 条件分支 */
17
+ conditionalBranching: "ConditionalBranching",
18
+ };
19
+
20
+ /**
21
+ * 类型数据枚举
22
+ */
23
+ export const typeDataEnum = {
24
+ [NODE_TYPE.approvalNode]: {
25
+ _Icon: UserOutlined,
26
+ nodeName: "审核人",
27
+ nodeKey: getNodeKey(),
28
+ type: 1, //节点类型
29
+ setType: 1, //审核人类型 1,选择成员 3,选择角色
30
+ nodeAssigneeList: [], //审核人员,根据 setType 确定成员还是角色
31
+ examineLevel: 1, //指定主管层级
32
+ directorLevel: 1, //自定义连续主管审批层级
33
+ selectMode: 1, //发起人自选类型
34
+ termAuto: false, //审批期限超时自动审批
35
+ term: 0, //审批期限
36
+ termMode: 1, //审批期限超时后执行类型
37
+ examineMode: 1, //多人审批时审批方式
38
+ directorMode: 0, //连续主管审批方式
39
+ },
40
+ [NODE_TYPE.ccNode]: {
41
+ _Icon: SendOutlined,
42
+ nodeName: "抄送人",
43
+ nodeKey: getNodeKey(),
44
+ type: 2,
45
+ userSelectFlag: true,
46
+ nodeAssigneeList: [],
47
+ },
48
+ [NODE_TYPE.conditionalBranching]: {
49
+ _Icon: ShareAltOutlined,
50
+ nodeName: "条件路由",
51
+ nodeKey: getNodeKey(),
52
+ type: 4,
53
+ conditionNodes: [
54
+ {
55
+ nodeName: "条件1",
56
+ nodeKey: getNodeKey(),
57
+ type: 3,
58
+ priorityLevel: 1,
59
+ conditionMode: 1,
60
+ conditionList: [],
61
+ },
62
+ {
63
+ nodeName: "条件2",
64
+ nodeKey: getNodeKey(),
65
+ type: 3,
66
+ priorityLevel: 2,
67
+ conditionMode: 1,
68
+ conditionList: [],
69
+ },
70
+ ],
71
+ },
72
+ };
73
+
74
+ const types = Object.keys(typeDataEnum);
75
+
76
+ export function getNodeKey() {
77
+ return "flk" + nanoid();
78
+ }
79
+
80
+ export const AddNode = (props) => {
81
+ const { modelValue, onChange } = props;
82
+
83
+ function addType(type) {
84
+ const data = _.cloneDeep(typeDataEnum[type]);
85
+ data.childNode = modelValue;
86
+ delete data._Icon;
87
+ onChange && onChange(data);
88
+ }
89
+
90
+ return (
91
+ <div className="add-node-box">
92
+ <div className="add-node-btn-box">
93
+ <Popover
94
+ className="popover"
95
+ trigger="click"
96
+ placement="bottom"
97
+ content={
98
+ <div className="add-node-popover-body">
99
+ {types?.map((key) => {
100
+ const data = typeDataEnum[key];
101
+ const Icon = data?._Icon;
102
+ return (
103
+ <div key={key} className="add-node-popover-btn" onClick={() => addType(key)}>
104
+ <Icon className="add-node-popover-btn-icon" />
105
+ <div className="add-node-popover-btn-text">{data?.nodeName}</div>
106
+ </div>
107
+ );
108
+ })}
109
+ </div>
110
+ }
111
+ >
112
+ <Button className="add-node-btn" type="primary" shape="circle" icon={<PlusOutlined />}></Button>
113
+ </Popover>
114
+ </div>
115
+ </div>
116
+ );
117
+ };
118
+
119
+ export default AddNode;
@@ -0,0 +1,72 @@
1
+ .approver-wrap {
2
+ .node-wrap {
3
+ display: inline-flex;
4
+ width: 100%;
5
+ flex-flow: column wrap;
6
+ justify-content: flex-start;
7
+ align-items: center;
8
+ padding: 0px 0px;
9
+ position: relative;
10
+ z-index: 1;
11
+ }
12
+ .node-wrap-box {
13
+ display: inline-flex;
14
+ flex-direction: column;
15
+ position: relative;
16
+ width: 220px;
17
+ min-height: 72px;
18
+ flex-shrink: 0;
19
+ background: rgb(255, 255, 255);
20
+ border-radius: 4px;
21
+ cursor: pointer;
22
+ box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.1);
23
+ }
24
+ .node-wrap-box::before {
25
+ content: "";
26
+ position: absolute;
27
+ top: -12px;
28
+ left: 50%;
29
+ transform: translateX(-50%);
30
+ width: 0px;
31
+ border-style: solid;
32
+ border-width: 8px 6px 4px;
33
+ border-color: rgb(202, 202, 202) transparent transparent;
34
+ }
35
+ .node-wrap-box.start-node:before {
36
+ content: none;
37
+ }
38
+ .node-wrap-box .title {
39
+ height: 24px;
40
+ line-height: 24px;
41
+ color: #fff;
42
+ padding-left: 16px;
43
+ padding-right: 30px;
44
+ border-radius: 4px 4px 0 0;
45
+ position: relative;
46
+ display: flex;
47
+ align-items: center;
48
+ }
49
+ .node-wrap-box .title .icon {
50
+ margin-right: 5px;
51
+ }
52
+ .node-wrap-box .title .node-close-btn {
53
+ font-size: 15px;
54
+ position: absolute;
55
+ top: 50%;
56
+ transform: translateY(-50%);
57
+ right: 10px;
58
+ display: none;
59
+ }
60
+ .node-wrap-box .content {
61
+ position: relative;
62
+ padding: 15px;
63
+ }
64
+ .node-wrap-box .content .placeholder {
65
+ color: #999;
66
+ }
67
+ }
68
+ .approver-drawer-footer {
69
+ .ant-btn + .ant-btn {
70
+ margin-left: 12px;
71
+ }
72
+ }