Skip to content

Commit 6f4464d

Browse files
committed
1 parent 2cca1f3 commit 6f4464d

13 files changed

Lines changed: 300 additions & 19 deletions

File tree

flow-engine-framework/src/main/java/com/codingapi/flow/pojo/response/FlowContent.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ public void pushHistory(Workflow workflow,List<FlowRecord> historyRecords) {
144144
history.setNodeId(item.getNodeId());
145145
history.setNodeType(item.getNodeType());
146146
history.setUpdateTime(item.getUpdateTime());
147-
history.setCurrentOperatorId(item.getCurrentOperatorId());
148-
history.setCurrentOperatorName(item.getCurrentOperatorName());
147+
history.setCurrentOperator(new FlowOperator(item.getCurrentOperatorId(), item.getCurrentOperatorName()));
149148
this.histories.add(history);
150149
}
151150
}
@@ -221,14 +220,9 @@ public static class History{
221220
private long updateTime;
222221

223222
/**
224-
* 当前审批人Id
223+
* 当前审批人
225224
*/
226-
private long currentOperatorId;
227-
228-
/**
229-
* 当前审批人名称
230-
*/
231-
private String currentOperatorName;
225+
private FlowOperator currentOperator;
232226
}
233227

234228
@Data
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React from "react";
2+
import {ApprovalLayoutProps, State} from "../typings";
3+
import {Presenter} from "../presenters";
4+
5+
6+
export class ApprovalContextScope {
7+
private readonly presenter: Presenter;
8+
private readonly props: ApprovalLayoutProps;
9+
10+
constructor(presenter: Presenter, props: ApprovalLayoutProps) {
11+
this.presenter = presenter;
12+
this.props = props;
13+
}
14+
15+
public syncState(state: State) {
16+
this.presenter.syncState(state);
17+
}
18+
19+
public getPresenter() {
20+
return this.presenter;
21+
}
22+
23+
public close() {
24+
this.props.onClose?.();
25+
}
26+
27+
public initialState() {
28+
this.syncState({
29+
flow: this.props.content
30+
})
31+
}
32+
}
33+
34+
35+
export const ApprovalContext = React.createContext<ApprovalContextScope | undefined>(undefined);
36+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from "react";
2+
import {useDispatch, useSelector} from "react-redux";
3+
import {ApprovalContext, ApprovalContextScope} from "../context";
4+
import {ApprovalReduxState, updateState} from "../store";
5+
import {Presenter} from "../presenters";
6+
import {FlowApprovalApiImpl} from "../model";
7+
import {ApprovalLayoutProps} from "@/components/approval/typings";
8+
9+
export const useApprovalContext = () => {
10+
const context = React.useContext(ApprovalContext);
11+
const state = useSelector((state: ApprovalReduxState) => state.approval);
12+
if (!context) {
13+
throw new Error("ApprovalContext must be used within useContext");
14+
}
15+
return {
16+
state,
17+
context,
18+
};
19+
}
20+
21+
export const createApprovalContext = (props: ApprovalLayoutProps) => {
22+
const ref = React.useRef<ApprovalContextScope | undefined>(undefined);
23+
24+
const dispatch = useDispatch();
25+
26+
const state = useSelector((state: ApprovalReduxState) => state.approval);
27+
28+
if (!ref.current) {
29+
const presenter = new Presenter(
30+
state,
31+
(prevState) => {
32+
dispatch(updateState(prevState));
33+
return prevState;
34+
},
35+
new FlowApprovalApiImpl()
36+
);
37+
ref.current = new ApprovalContextScope(presenter, props);
38+
ref.current.initialState();
39+
}
40+
41+
React.useEffect(() => {
42+
ref.current?.syncState(state);
43+
}, [state]);
44+
45+
return {
46+
state,
47+
context: ref.current,
48+
}
49+
}

frontend/packages/flow-design/src/components/approval/index.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
11
import React from "react";
22
import {Drawer} from "@/components/drawer";
33
import {detail} from "@/api/record";
4+
import {FlowContent} from "@/components/approval/typings";
5+
import {ApprovalLayout} from "@/components/approval/layout";
46

57

68
interface ApprovalPanelProps {
79
workflowCode?: string;
8-
recordId?:string
10+
recordId?:string;
11+
onClose?: () => void;
912
}
1013

1114
export const ApprovalPanel: React.FC<ApprovalPanelProps> = (props) => {
1215

16+
const [state,dispatch] = React.useState<FlowContent|undefined>(undefined);
17+
1318
React.useEffect(()=>{
1419
const id = props.workflowCode || props.recordId || '';
1520
detail(id).then(res=>{
1621
if(res.success){
17-
console.log(res.data)
22+
dispatch(res.data);
1823
}
1924
});
2025
},[]);
2126

2227
return (
23-
<>approval</>
28+
<>
29+
{state && <ApprovalLayout content={state} onClose={props.onClose}/>}
30+
</>
2431
)
2532
}
2633

@@ -35,8 +42,6 @@ export const ApprovalPanelDrawer: React.FC<ApprovalPanelDrawerProps> = (props) =
3542
<Drawer
3643
open={props.open}
3744
onClose={props.onClose}
38-
title={"发起流程"}
39-
closeIcon={true}
4045
>
4146
<ApprovalPanel
4247
{...props}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from "react";
2+
3+
export const Body = () => {
4+
return (
5+
<div>
6+
body
7+
</div>
8+
)
9+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from "react";
2+
import {useApprovalContext} from "@/components/approval/hooks/use-approval-context";
3+
4+
export const Header = () => {
5+
const {state,context} = useApprovalContext();
6+
7+
return (
8+
<div>
9+
Header
10+
<button onClick={()=>{
11+
context.close();
12+
}}>close</button>
13+
</div>
14+
)
15+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from "react";
2+
import {ApprovalLayoutProps} from "@/components/approval/typings";
3+
import {Provider} from "react-redux";
4+
import {approvalStore} from "@/components/approval/store";
5+
import {ApprovalContext} from "@/components/approval/context";
6+
import {createApprovalContext} from "@/components/approval/hooks/use-approval-context";
7+
import {Header} from "@/components/approval/layout/header";
8+
import {Body} from "@/components/approval/layout/body";
9+
10+
11+
const ApprovalLayoutScope: React.FC<ApprovalLayoutProps> = (props) => {
12+
const {context} = createApprovalContext(props);
13+
return (
14+
<ApprovalContext.Provider value={context}>
15+
<Header/>
16+
<Body/>
17+
</ApprovalContext.Provider>
18+
)
19+
}
20+
21+
export const ApprovalLayout: React.FC<ApprovalLayoutProps> = (props) => {
22+
23+
return (
24+
<Provider store={approvalStore}>
25+
<ApprovalLayoutScope {...props}/>
26+
</Provider>
27+
)
28+
};
29+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import {FlowApprovalApi} from "@/components/approval/typings";
2+
3+
export class FlowApprovalApiImpl implements FlowApprovalApi {
4+
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import {FlowApprovalApi, State} from "@/components/approval/typings";
2+
import {BasePresenter} from "@flow-engine/flow-core";
3+
4+
export class Presenter extends BasePresenter<State,FlowApprovalApi>{
5+
6+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import {configureStore, createSlice, PayloadAction} from '@reduxjs/toolkit';
2+
import {initStateData, State} from "./typings";
3+
import { original } from 'immer';
4+
5+
export type ApprovalStoreAction = {
6+
updateState: (state: State, action: PayloadAction<Partial<State> | ((prev: State) => Partial<State>)>) => void;
7+
}
8+
9+
export const approvalSlice = createSlice<State, ApprovalStoreAction, "approval", {}>({
10+
name: 'approval',
11+
initialState: {
12+
...initStateData
13+
},
14+
reducers: {
15+
updateState: (state, action) => {
16+
if(typeof action.payload === 'function') {
17+
const currentState = original(state) as State;
18+
Object.assign(state, action.payload(currentState));
19+
}else {
20+
Object.assign(state, action.payload);
21+
}
22+
},
23+
},
24+
});
25+
26+
27+
export const {
28+
updateState,
29+
} = approvalSlice.actions;
30+
export const approvalStore = configureStore({
31+
reducer: {
32+
approval: approvalSlice.reducer
33+
},
34+
});
35+
36+
export type ApprovalReduxState = ReturnType<typeof approvalStore.getState>;

0 commit comments

Comments
 (0)