Commit bc62d01c7c7e4246aecc63ac833c9a28a8fa5a4e

Authored by qiang.tian
1 parent 97f7ab95

fix: builder error

@@ -7,14 +7,16 @@ const cwd = process.cwd(); @@ -7,14 +7,16 @@ const cwd = process.cwd();
7 7
8 module.exports = { 8 module.exports = {
9 output: { 9 output: {
10 - filename: 'index.js', 10 + filename: 'qx-[name]-[contenthash].bundle.js',
11 libraryTarget: 'umd', 11 libraryTarget: 'umd',
  12 + clean: true,
12 }, 13 },
13 entry: path.resolve(cwd, './src/index.tsx'), 14 entry: path.resolve(cwd, './src/index.tsx'),
14 module: { 15 module: {
15 rules: [ 16 rules: [
16 { 17 {
17 test: /\.(js|jsx)$/, 18 test: /\.(js|jsx)$/,
  19 + exclude: /node_modules/,
18 use: { 20 use: {
19 loader: 'babel-loader', 21 loader: 'babel-loader',
20 options: { 22 options: {
@@ -29,14 +31,23 @@ module.exports = { @@ -29,14 +31,23 @@ module.exports = {
29 }, 31 },
30 }, 32 },
31 { 33 {
32 - test: /\.(ttf|eot|woff(2)?)(\?[a-z0-9=&.]+)?$/, 34 + test: /\.(png|jpeg|jpg|ttf|eot|woff(2)?)(\?[a-z0-9=&.]+)?$/,
33 use: { 35 use: {
34 loader: 'file-loader', 36 loader: 'file-loader',
35 }, 37 },
36 }, 38 },
37 { 39 {
38 test: /\.less$/i, 40 test: /\.less$/i,
39 - use: ['style-loader', 'css-loader', 'less-loader'], 41 + use: [
  42 + 'style-loader',
  43 + 'css-loader',
  44 + {
  45 + loader: 'less-loader',
  46 + options: {
  47 + additionalData: `@import '@qx/ui/dist/src/style/variable.less';`,
  48 + },
  49 + },
  50 + ],
40 }, 51 },
41 { 52 {
42 test: /\.svg$/, 53 test: /\.svg$/,
@@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
24 "license": "ISC", 24 "license": "ISC",
25 "dependencies": { 25 "dependencies": {
26 "@ant-design/icons": "^5.2.5", 26 "@ant-design/icons": "^5.2.5",
  27 + "@qx/common": "0.2.31-alpha.5",
27 "@qx/flow": "1.0.0-alpha.10", 28 "@qx/flow": "1.0.0-alpha.10",
28 "@qx/icon-btn": "^0.0.13", 29 "@qx/icon-btn": "^0.0.13",
29 "@qx/ui": "0.0.3-beta.1", 30 "@qx/ui": "0.0.3-beta.1",
1 -import React, { memo } from 'react';  
2 -  
3 -const DynamicComponent: React.FC<DynamicComponentProps> = (props) => {  
4 - return <div>DynamicComponent</div>;  
5 -};  
6 -  
7 -interface DynamicComponentProps {  
8 - loader: (path: string) => any;  
9 -}  
10 -  
11 -export default memo(DynamicComponent);  
@@ -26,6 +26,7 @@ const FlowVersion: React.FC<FlowVersionProps> = (props) => { @@ -26,6 +26,7 @@ const FlowVersion: React.FC<FlowVersionProps> = (props) => {
26 return ( 26 return (
27 <> 27 <>
28 {versionText || 28 {versionText ||
  29 + // @ts-ignore
29 (statusEnums || FlowStatusEnums)[status || 'UNPUBLISHED'] ? ( 30 (statusEnums || FlowStatusEnums)[status || 'UNPUBLISHED'] ? (
30 <div 31 <div
31 className={cls( 32 className={cls(
@@ -51,6 +52,7 @@ const FlowVersion: React.FC<FlowVersionProps> = (props) => { @@ -51,6 +52,7 @@ const FlowVersion: React.FC<FlowVersionProps> = (props) => {
51 > 52 >
52 {!!versionText ? <span>V&nbsp;{versionText}</span> : null} 53 {!!versionText ? <span>V&nbsp;{versionText}</span> : null}
53 {!!status ? ( 54 {!!status ? (
  55 + // @ts-ignore
54 <span>{(statusEnums || FlowStatusEnums)[status]}</span> 56 <span>{(statusEnums || FlowStatusEnums)[status]}</span>
55 ) : null} 57 ) : null}
56 </div> 58 </div>
  1 +import React, { Suspense } from 'react';
  2 +import { Skeleton } from 'antd';
  3 +
  4 +const lazyComponent = (importComp: () => any) => {
  5 + const Comp = React.lazy(importComp);
  6 + return (
  7 + <Suspense fallback={<Skeleton.Input />}>
  8 + <Comp></Comp>
  9 + </Suspense>
  10 + );
  11 +};
  12 +
  13 +export default lazyComponent;
@@ -62,6 +62,7 @@ const NameDescriptionSetting: React.FC<NameDescriptionSettingProps> = ( @@ -62,6 +62,7 @@ const NameDescriptionSetting: React.FC<NameDescriptionSettingProps> = (
62 if (_.isEmpty(values)) { 62 if (_.isEmpty(values)) {
63 form.resetFields(); 63 form.resetFields();
64 } else { 64 } else {
  65 + // @ts-ignore
65 form.setValues(values); 66 form.setValues(values);
66 } 67 }
67 }, 100); 68 }, 100);
@@ -114,6 +115,7 @@ const NameDescriptionSetting: React.FC<NameDescriptionSettingProps> = ( @@ -114,6 +115,7 @@ const NameDescriptionSetting: React.FC<NameDescriptionSettingProps> = (
114 form={form} 115 form={form}
115 schema={FORM_SCHEMA} 116 schema={FORM_SCHEMA}
116 onMount={() => {}} 117 onMount={() => {}}
  118 + // @ts-ignore
117 onFinish={onFinish} 119 onFinish={onFinish}
118 watch={{}} 120 watch={{}}
119 /> 121 />
@@ -2,12 +2,13 @@ import React, { memo, useContext, useEffect, useState } from 'react'; @@ -2,12 +2,13 @@ import React, { memo, useContext, useEffect, useState } from 'react';
2 import { BuilderContext } from '@qx/flow'; 2 import { BuilderContext } from '@qx/flow';
3 import { Drawer, Spin, Tabs } from 'antd'; 3 import { Drawer, Spin, Tabs } from 'antd';
4 import NodeList, { NodeItemsProps } from './components/node-list'; 4 import NodeList, { NodeItemsProps } from './components/node-list';
5 -import { useLocation, useSearchParams } from 'react-router-dom'; 5 +import { useSearchParams } from '@/hooks';
6 import { getListGroupNode } from '@/services'; 6 import { getListGroupNode } from '@/services';
7 import { QxIcon } from '@/components'; 7 import { QxIcon } from '@/components';
8 import { ReactSortable } from 'react-sortablejs'; 8 import { ReactSortable } from 'react-sortablejs';
9 import { cloneDeep } from 'lodash-es'; 9 import { cloneDeep } from 'lodash-es';
10 import { v4 as uuid } from 'uuid'; 10 import { v4 as uuid } from 'uuid';
  11 +// @ts-ignore
11 import type { INodePanelProps } from '@qx/flow'; 12 import type { INodePanelProps } from '@qx/flow';
12 import Empty from './img/empty.png'; 13 import Empty from './img/empty.png';
13 14
@@ -31,10 +32,10 @@ const panelTabs = [ @@ -31,10 +32,10 @@ const panelTabs = [
31 ]; 32 ];
32 33
33 const NodePanel: React.FC<NodePanelProps> = (props) => { 34 const NodePanel: React.FC<NodePanelProps> = (props) => {
34 - const { visible, onClose } = props;  
35 // @ts-ignore 35 // @ts-ignore
36 - const [searchParams] = useSearchParams();  
37 - const appId = searchParams.get('appId'); 36 + const { visible, onClose } = props;
  37 + const [query] = useSearchParams<any>();
  38 + const appId = query?.appId;
38 const { registerNodes } = useContext(BuilderContext); 39 const { registerNodes } = useContext(BuilderContext);
39 const [loading, setLoading] = useState(false); 40 const [loading, setLoading] = useState(false);
40 const [activeKey, setActiveKey] = useState('SYSTEM'); 41 const [activeKey, setActiveKey] = useState('SYSTEM');
1 export * from './useTheme'; 1 export * from './useTheme';
  2 +export * from './useSearchParams';
  3 +export * from './useFlowTableScrollY';
  1 +import React, { useEffect, useMemo, useRef, useState } from 'react';
  2 +
  3 +// 表格 Scroll 高度计算
  4 +export const useFlowTableScrollY = (
  5 + deps: {
  6 + columns: any[];
  7 + size?: 'small' | 'middle' | 'default';
  8 + tableBoxClassName?: string;
  9 + classNames?: string[]; // 表格DOM内嵌元素 列名 添加在此,
  10 + hasPagination?: boolean;
  11 + listProps?: any;
  12 + } = {
  13 + size: 'small',
  14 + tableBoxClassName: '',
  15 + classNames: [],
  16 + hasPagination: false,
  17 + columns: [],
  18 + listProps: {},
  19 + },
  20 +) => {
  21 + const itemHeaderHeight =
  22 + (deps?.size === 'middle' ? 48 : deps?.size === 'default' ? 56 : 40) + 1;
  23 + const TABLE_VIEW_LIST = deps?.tableBoxClassName || 'qx-data-flow-table';
  24 + let tableHeader = itemHeaderHeight;
  25 + const tableViewListDefaultHeight = 400;
  26 + const defaultPagePadding = 0;
  27 +
  28 + const $ = (selectors: string) =>
  29 + document.querySelector<HTMLElement>(selectors);
  30 +
  31 + const defaultScrollY = useMemo(
  32 + () => document.body.clientHeight,
  33 + [tableHeader],
  34 + );
  35 +
  36 + const [scrollY, setScrollY] = useState<number>(defaultScrollY ?? 200);
  37 +
  38 + // @ts-ignore
  39 + const timer = useRef<NodeJS.Timer>();
  40 +
  41 + const getScrollY = () => {
  42 + const tableViewList = $(`.${TABLE_VIEW_LIST}`);
  43 +
  44 + const tableViewListClientHeight =
  45 + tableViewList?.clientHeight || tableViewListDefaultHeight;
  46 + // 分页大小 目前已经固定 所以直接用56px
  47 + const antPaginationHeight = deps?.hasPagination ? 56 : 0;
  48 +
  49 + const _domHeightByClassName = (deps?.classNames || []).map(
  50 + (_v: string) => $(`.${_v}`)?.clientHeight ?? 0,
  51 + );
  52 + let result =
  53 + tableViewListClientHeight -
  54 + tableHeader -
  55 + defaultPagePadding -
  56 + antPaginationHeight;
  57 + if (!!_domHeightByClassName?.length) {
  58 + result = result - eval(_domHeightByClassName.join('+'));
  59 + }
  60 +
  61 + if (tableViewList) {
  62 + tableViewList.style.overflowY = result < 200 ? 'auto' : 'hidden';
  63 + }
  64 +
  65 + setScrollY(result < 100 ? 100 : result);
  66 + };
  67 +
  68 + const observer = () => {
  69 + window.addEventListener('resize', getScrollY);
  70 + };
  71 +
  72 + const removeObserver = () => {
  73 + if (timer.current) window.clearTimeout(timer.current);
  74 + window.removeEventListener('resize', getScrollY);
  75 + };
  76 +
  77 + useEffect(() => {
  78 + observer();
  79 + return () => {
  80 + removeObserver();
  81 + };
  82 + }, [tableHeader]);
  83 +
  84 + useEffect(() => {
  85 + if (deps) {
  86 + timer.current = setTimeout(() => {
  87 + getScrollY();
  88 + }, 100);
  89 + }
  90 + }, [JSON.stringify(deps)]);
  91 +
  92 + return [scrollY, getScrollY];
  93 +};
  1 +import { useMemo } from 'react';
  2 +import { useSearchParams as useRouterDOMSearchParams } from 'react-router-dom';
  3 +
  4 +export const useSearchParams = <T = Record<string, any>>() => {
  5 + const [searchParams, setQuery] = useRouterDOMSearchParams();
  6 +
  7 + const query = useMemo<T>(() => {
  8 + const params = {} as T;
  9 + searchParams.forEach((value, key) => {
  10 + (params as Record<string, any>)[key] = value;
  11 + });
  12 + return params;
  13 + }, []);
  14 +
  15 + return [query, setQuery];
  16 +};
@@ -17,7 +17,7 @@ import { Start, End } from './nodes'; @@ -17,7 +17,7 @@ import { Start, End } from './nodes';
17 import { NodeTypes, ProcessItemProps, FlowStatusEnums } from '@/interface'; 17 import { NodeTypes, ProcessItemProps, FlowStatusEnums } from '@/interface';
18 import { handleWindowOpen } from '@qx/utils'; 18 import { handleWindowOpen } from '@qx/utils';
19 // import { history } from '@@/core/history'; 19 // import { history } from '@@/core/history';
20 -import { useLocation, useSearchParams } from 'react-router-dom'; 20 +import { useLocation } from 'react-router-dom';
21 import { useTitle } from 'ahooks'; 21 import { useTitle } from 'ahooks';
22 // 头部相关 22 // 头部相关
23 import { 23 import {
@@ -31,6 +31,7 @@ import cls from 'classnames'; @@ -31,6 +31,7 @@ import cls from 'classnames';
31 import styles from '@/components/header/index.module.less'; 31 import styles from '@/components/header/index.module.less';
32 import { getIcon } from '@/utils'; 32 import { getIcon } from '@/utils';
33 import { QxIcon } from '@/components'; 33 import { QxIcon } from '@/components';
  34 +import { useSearchParams } from '@/hooks';
34 import { 35 import {
35 getProcessDetailsById, 36 getProcessDetailsById,
36 publishProcessById, 37 publishProcessById,
@@ -71,8 +72,7 @@ const systemNodes: IRegisterNode[] = [ @@ -71,8 +72,7 @@ const systemNodes: IRegisterNode[] = [
71 export default () => { 72 export default () => {
72 const [nodes, setNodes] = useState<INode[]>([]); 73 const [nodes, setNodes] = useState<INode[]>([]);
73 const [remoteNodes, setRemoteNodes] = useState<IRegisterRemoteNode[]>([]); 74 const [remoteNodes, setRemoteNodes] = useState<IRegisterRemoteNode[]>([]);
74 - // @ts-ignore  
75 - const [searchParams] = useSearchParams(); 75 + const [query, setQuery] = useSearchParams<any>();
76 const [showEditTitle, setShowEditTitle] = useState(false); 76 const [showEditTitle, setShowEditTitle] = useState(false);
77 const { 77 const {
78 appId, // 应用id 78 appId, // 应用id
@@ -80,13 +80,7 @@ export default () => { @@ -80,13 +80,7 @@ export default () => {
80 returnUrl, // 来自页面跳转返回可跳转 80 returnUrl, // 来自页面跳转返回可跳转
81 processId, // 流程Id preview 81 processId, // 流程Id preview
82 type, // 流程类型 edit 编辑 preview 预览 82 type, // 流程类型 edit 编辑 preview 预览
83 - } = {  
84 - appId: searchParams.get('appId'),  
85 - funCode: searchParams.get('funCode'),  
86 - returnUrl: searchParams.get('returnUrl'),  
87 - processId: searchParams.get('processId'),  
88 - type: searchParams.get('type'),  
89 - }; 83 + } = query;
90 84
91 const [processDetails, setProcessDetails] = useState<ProcessItemProps>({ 85 const [processDetails, setProcessDetails] = useState<ProcessItemProps>({
92 id: '', 86 id: '',
@@ -116,6 +110,7 @@ export default () => { @@ -116,6 +110,7 @@ export default () => {
116 .catch((err: { msg?: string }) => { 110 .catch((err: { msg?: string }) => {
117 message.warning(err?.msg || '流程详情数据请求失败', 5); 111 message.warning(err?.msg || '流程详情数据请求失败', 5);
118 setProcessDetails( 112 setProcessDetails(
  113 + // @ts-ignore
119 _data || { 114 _data || {
120 id: _id, 115 id: _id,
121 name: '未命名流程', 116 name: '未命名流程',
@@ -198,7 +193,7 @@ export default () => { @@ -198,7 +193,7 @@ export default () => {
198 // 发布流程 193 // 发布流程
199 // TODO 要先校验是否保存 才能发布 194 // TODO 要先校验是否保存 才能发布
200 publishProcessById(processDetails.id || '') 195 publishProcessById(processDetails.id || '')
201 - .then((res) => { 196 + .then((res: any) => {
202 console.log('res ====', res); 197 console.log('res ====', res);
203 }) 198 })
204 .catch((err: { msg?: string }) => { 199 .catch((err: { msg?: string }) => {
@@ -237,11 +232,8 @@ export default () => { @@ -237,11 +232,8 @@ export default () => {
237 remark: data.remark, 232 remark: data.remark,
238 }); 233 });
239 if (!processDetails?.id) { 234 if (!processDetails?.id) {
240 - history.replace({  
241 - query: {  
242 - ...query,  
243 - processId: res,  
244 - }, 235 + setQuery({
  236 + processId: res,
245 }); 237 });
246 } 238 }
247 } 239 }
@@ -389,6 +381,7 @@ export default () => { @@ -389,6 +381,7 @@ export default () => {
389 useEffect(() => { 381 useEffect(() => {
390 let _data: ProcessItemProps = {}; 382 let _data: ProcessItemProps = {};
391 _data.name = '未命名流程'; 383 _data.name = '未命名流程';
  384 + // @ts-ignore
392 _data.appId = appId; 385 _data.appId = appId;
393 if (!!funCode) { 386 if (!!funCode) {
394 _data.funCode = funCode; 387 _data.funCode = funCode;
@@ -416,6 +409,7 @@ export default () => { @@ -416,6 +409,7 @@ export default () => {
416 defaultTools: INode[], 409 defaultTools: INode[],
417 actions: any, 410 actions: any,
418 ) => { 411 ) => {
  412 + console.log('nodes', nodes);
419 const { copyNodeAndChildren } = actions; 413 const { copyNodeAndChildren } = actions;
420 switch (node.type) { 414 switch (node.type) {
421 case 'condition': 415 case 'condition':
@@ -452,6 +446,7 @@ export default () => { @@ -452,6 +446,7 @@ export default () => {
452 registerNodes={systemNodes} 446 registerNodes={systemNodes}
453 historyTool 447 historyTool
454 zoomTool 448 zoomTool
  449 + // @ts-ignore
455 expandAllTool 450 expandAllTool
456 DrawerComponent={Drawer} 451 DrawerComponent={Drawer}
457 PopoverComponent={Popover} 452 PopoverComponent={Popover}
@@ -463,6 +458,7 @@ export default () => { @@ -463,6 +458,7 @@ export default () => {
463 registerRemoteNodes={remoteNodes} 458 registerRemoteNodes={remoteNodes}
464 ConfigDrawerContainer={ConfigDrawer} 459 ConfigDrawerContainer={ConfigDrawer}
465 NodePanel={NodesPanel} 460 NodePanel={NodesPanel}
  461 + // @ts-ignore
466 getNodeTool={getNodeTool} 462 getNodeTool={getNodeTool}
467 /> 463 />
468 <NameDescriptionSetting cRef={formModalRef} handleClick={handleClick} /> 464 <NameDescriptionSetting cRef={formModalRef} handleClick={handleClick} />
1 import React, { useContext, memo, useImperativeHandle } from 'react'; 1 import React, { useContext, memo, useImperativeHandle } from 'react';
2 -import { useForm } from '@qx/form-render';  
3 -import QxFormRender from '@/packages/qx-form-generator/src/form-render';  
4 -import { conditionSetting } from '../../setting-configs'; 2 +// import { useForm } from '@qx/form-render';
  3 +// import QxFormRender from '@/packages/qx-form-generator/src/form-render';
  4 +// import { conditionSetting } from '../../setting-configs';
5 import styles from './index.less'; 5 import styles from './index.less';
6 import type { IConfigComponent } from '@qx/flow'; 6 import type { IConfigComponent } from '@qx/flow';
7 7
8 const StartConfigComponent = React.forwardRef<any, StartConfigComponentProps>( 8 const StartConfigComponent = React.forwardRef<any, StartConfigComponentProps>(
9 (props, ref) => { 9 (props, ref) => {
10 - const form = useForm(); 10 + // const form = useForm();
11 11
12 const handleValuesChange = (values: any) => { 12 const handleValuesChange = (values: any) => {
13 props?.onChange(values); 13 props?.onChange(values);
14 }; 14 };
15 15
16 useImperativeHandle(ref, () => ({ 16 useImperativeHandle(ref, () => ({
17 - validateFields: form.validateFields, 17 + // validateFields: form.validateFields,
18 })); 18 }));
19 19
20 return ( 20 return (
21 <div className={styles['qx-flow-single-records-config']}> 21 <div className={styles['qx-flow-single-records-config']}>
22 - <QxFormRender 22 + {/* <QxFormRender
23 form={form} 23 form={form}
24 schema={conditionSetting} 24 schema={conditionSetting}
25 widgets={{}} 25 widgets={{}}
26 watch={{}} 26 watch={{}}
27 onValuesChange={handleValuesChange} 27 onValuesChange={handleValuesChange}
28 - /> 28 + /> */}
29 </div> 29 </div>
30 ); 30 );
31 }, 31 },
1 import React, { useContext, memo } from 'react'; 1 import React, { useContext, memo } from 'react';
2 -import { useForm } from '@qx/form-render'; 2 +// import { useForm } from '@qx/form-render';
3 import { useDrawer } from '@qx/flow'; 3 import { useDrawer } from '@qx/flow';
4 -import { ConfigComponentFooter } from '../../components';  
5 -import QxFormRender from '@/packages/qx-form-generator/src/form-render';  
6 -import { startSetting } from '../../setting-configs'; 4 +// import { ConfigComponentFooter } from '../../components';
  5 +// import QxFormRender from '@/packages/qx-form-generator/src/form-render';
  6 +// import { startSetting } from '../../setting-configs';
7 import styles from './index.less'; 7 import styles from './index.less';
8 import type { IConfigComponent } from '@qx/flow'; 8 import type { IConfigComponent } from '@qx/flow';
9 9
10 const EndConfigComponent: React.FC<EndConfigComponentProps> = (props) => { 10 const EndConfigComponent: React.FC<EndConfigComponentProps> = (props) => {
11 - const form = useForm();  
12 - const { closeDrawer: cancel, saveDrawer: save } = useDrawer(); 11 + // const form = useForm();
13 12
14 - const onSave = async () => {  
15 - try {  
16 - await form.submit();  
17 - const values = form.getValues();  
18 - console.log('values', values);  
19 - save(values);  
20 - } catch (error) {  
21 - console.log(error);  
22 - }  
23 - };  
24 -  
25 - return (  
26 - <div className={styles['qx-flow-single-records-config']}>  
27 - <QxFormRender form={form} schema={startSetting} widgets={{}} watch={{}} />  
28 - <ConfigComponentFooter onSave={onSave} onCancel={cancel} />  
29 - </div>  
30 - ); 13 + return <div className={styles['qx-flow-single-records-config']}></div>;
31 }; 14 };
32 15
33 interface EndConfigComponentProps extends IConfigComponent {} 16 interface EndConfigComponentProps extends IConfigComponent {}
1 import React, { memo } from 'react'; 1 import React, { memo } from 'react';
2 -// import { ReactComponent as Icon } from "../../public/icons/outlined.svg"; 2 +import { Button, Typography } from 'antd';
  3 +import { useAction } from '@qx/flow';
  4 +const { Text } = Typography;
3 import type { IDisplayComponent, INode } from '@qx/flow'; 5 import type { IDisplayComponent, INode } from '@qx/flow';
4 -import './index.less'; 6 +
  7 +const paramsEnums: Record<string, string> = {
  8 + STRING: '文本',
  9 + NUMBER: '数字',
  10 + TIME: '日期',
  11 + BOOL: '布尔',
  12 + OBJECT: '对象',
  13 + ARRAY: '数组',
  14 + ANNEX: '附件',
  15 + PIC: '图片',
  16 + FORM: '表单',
  17 + USER: '人员',
  18 + ORG: '部门',
  19 +};
5 20
6 const DisplayComponent: React.FC<DisplayComponentProps> = (props) => { 21 const DisplayComponent: React.FC<DisplayComponentProps> = (props) => {
7 const { node, nodes } = props; 22 const { node, nodes } = props;
8 23
  24 + const handleChangeName = (newValue: string) => {
  25 + node.name = newValue;
  26 + props.onChange?.([...nodes]);
  27 + };
  28 +
  29 + const { clickNode } = useAction();
  30 +
9 return ( 31 return (
10 <div className="qx-flow-default-node"> 32 <div className="qx-flow-default-node">
11 <div className="qx-flow-default-node__header"> 33 <div className="qx-flow-default-node__header">
@@ -16,13 +38,38 @@ const DisplayComponent: React.FC<DisplayComponentProps> = (props) => { @@ -16,13 +38,38 @@ const DisplayComponent: React.FC<DisplayComponentProps> = (props) => {
16 <span className="qx-flow-default-node__title--name">{node.name}</span> 38 <span className="qx-flow-default-node__title--name">{node.name}</span>
17 </span> 39 </span>
18 </div> 40 </div>
19 - <div className="qx-flow-default-node__content">  
20 - {!node.data ? (  
21 - <span className="qx-flow-start-node__button">设置入参</span>  
22 - ) : (  
23 - <span>节点配置内容</span>  
24 - )}  
25 - </div> 41 + {!!node?.data?.params?.length ? (
  42 + <>
  43 + <div className="qx-flow-default-node__content">
  44 + {props?.node?.data?.params.map((_v: any) => {
  45 + return (
  46 + <Text
  47 + style={{
  48 + width: '100%',
  49 + lineHeight: '22px',
  50 + }}
  51 + ellipsis={{
  52 + tooltip: `${paramsEnums?.[_v.type || '']}&nbsp;${
  53 + _v.title || '未命名'
  54 + }`,
  55 + }}
  56 + >
  57 + {paramsEnums?.[_v.type || '']}&nbsp;{_v.title || '未命名'}
  58 + </Text>
  59 + );
  60 + })}
  61 + </div>
  62 + </>
  63 + ) : (
  64 + <Button
  65 + style={{ marginTop: 8 }}
  66 + type="link"
  67 + size="small"
  68 + // onClick={() => clickNode()}
  69 + >
  70 + 设置入参
  71 + </Button>
  72 + )}
26 </div> 73 </div>
27 ); 74 );
28 }; 75 };
1 export { default as Start } from './start'; 1 export { default as Start } from './start';
2 export { default as End } from './end'; 2 export { default as End } from './end';
3 // export { default as Condition } from './condition'; 3 // export { default as Condition } from './condition';
4 -export { default as Loop } from './loop';  
1 -import React, { useContext, memo } from 'react';  
2 -import { useForm } from '@qx/form-render';  
3 -import { useDrawer } from '@qx/flow';  
4 -import { ConfigComponentFooter } from '../../components';  
5 -import QxFormRender from '@/packages/qx-form-generator/src/form-render';  
6 -import { loopSetting } from '../../setting-configs';  
7 -import styles from './index.less';  
8 -import type { IConfigComponent } from '@qx/flow';  
9 -  
10 -const LoopConfigComponent: React.FC<LoopConfigComponentProps> = (props) => {  
11 - const form = useForm();  
12 - const { closeDrawer: cancel, saveDrawer: save } = useDrawer();  
13 -  
14 - const onSave = async () => {  
15 - try {  
16 - await form.submit();  
17 - const values = form.getValues();  
18 - console.log('values', values);  
19 - save(values);  
20 - } catch (error) {  
21 - console.log(error);  
22 - }  
23 - };  
24 -  
25 - return (  
26 - <div className={styles['qx-flow-single-records-config']}>  
27 - <QxFormRender form={form} schema={LoopSetting} widgets={{}} watch={{}} />  
28 - <ConfigComponentFooter onSave={onSave} onCancel={cancel} />  
29 - </div>  
30 - );  
31 -};  
32 -  
33 -interface LoopConfigComponentProps extends IConfigComponent {}  
34 -  
35 -export default memo(LoopConfigComponent);  
1 -import React, { memo, useContext } from 'react';  
2 -import { useAction } from '@qx/flow';  
3 -import type { IDisplayComponent } from '@qx/flow';  
4 -  
5 -const ConditionDisplayComponent: React.FC<ConditionDisplayComponentProps> = (  
6 - props,  
7 -) => {  
8 - return <>条件节点内容</>;  
9 -};  
10 -  
11 -interface ConditionDisplayComponentProps extends IDisplayComponent {}  
12 -  
13 -export default memo(ConditionDisplayComponent);  
1 -import ConfigComponent from './configComponent';  
2 -import DisplayComponent from './displayComponent';  
3 -  
4 -export default {  
5 - // DisplayComponent,  
6 - // ConfigComponent,  
7 -};  
1 -import React, {  
2 - useContext,  
3 - memo,  
4 - useState,  
5 - useEffect,  
6 - useImperativeHandle,  
7 -} from 'react';  
8 -import { Checkbox, Form, Input, Radio, Space, Tooltip } from 'antd';  
9 -import type { CheckboxChangeEvent, RadioChangeEvent } from 'antd/es/checkbox';  
10 - 1 +import React, { memo, useState, useEffect, useImperativeHandle } from 'react';
  2 +import { Checkbox, Form, Radio, Space, Tooltip } from 'antd';
  3 +import type { RadioChangeEvent } from 'antd';
  4 +import type { CheckboxChangeEvent } from 'antd/es/checkbox';
11 import type { IConfigComponent } from '@qx/flow'; 5 import type { IConfigComponent } from '@qx/flow';
12 import { QxParameterSetting } from '@qx/common'; 6 import { QxParameterSetting } from '@qx/common';
13 import { QxIcon } from '@/components'; 7 import { QxIcon } from '@/components';
14 -import _ from 'lodash'; 8 +import { isEmpty, isEqual, cloneDeep } from 'lodash-es';
  9 +
  10 +const propagationList: {
  11 + value: string;
  12 + label: string;
  13 + tips: string;
  14 +}[] = [
  15 + {
  16 + value: 'REQUIRED',
  17 + label: '需要事务',
  18 + tips: '如果当前存在事务,则加入该事务;如果不存在事务,则创建一个新的事务',
  19 + },
  20 + {
  21 + value: 'SUPPORTS',
  22 + label: '支持当前事务',
  23 + tips: '如果当前存在事务,则加入该事务;如果不存在事务,则直接执行',
  24 + },
  25 + {
  26 + value: 'REQUIRES_NEW',
  27 + label: '新建事务',
  28 + tips: '不管当前是否存在事务,必定创建一个新事务,如果当前存在事务这个事务会被挂起。新事务在层级上与之前的事务是平级的,两者互不干扰',
  29 + },
  30 +];
  31 +
  32 +const isolationList: {
  33 + value: string;
  34 + label: string;
  35 + tips: string;
  36 +}[] = [
  37 + {
  38 + value: 'READ_UNCOMMITTED',
  39 + label: '读未提交',
  40 + tips: '可以读到其它事务未提交的数据',
  41 + },
  42 + {
  43 + value: 'READ_COMMITTED',
  44 + label: '已提交读取',
  45 + tips: '可以读到其它事务已提交的数据',
  46 + },
  47 + {
  48 + value: 'REPEATABLE_READ',
  49 + label: '可重复读取',
  50 + tips: '不会读到其它事务已提交的数据',
  51 + },
  52 + {
  53 + value: 'SERIALIZABLE',
  54 + label: '可串行化的',
  55 + tips: '串行化读',
  56 + },
  57 +];
15 58
16 -import { isolationList, propagationList } from '../../setting-configs/start';  
17 interface PropagationSettingProps { 59 interface PropagationSettingProps {
18 value: string; 60 value: string;
19 onChange: (val: string) => void; 61 onChange: (val: string) => void;
@@ -63,29 +105,24 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> = @@ -63,29 +105,24 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> =
63 })); 105 }));
64 106
65 const [values, setValues] = useState<{ 107 const [values, setValues] = useState<{
66 - params: any[];  
67 - enablePropagation: boolean;  
68 - propagation: string;  
69 - isolation: string;  
70 - }>({  
71 - params: [],  
72 - enablePropagation: false,  
73 - propagation: 'REQUIRED',  
74 - isolation: 'REPEATABLE_READ',  
75 - });  
76 - 108 + params?: any[];
  109 + enablePropagation?: boolean;
  110 + propagation?: string;
  111 + isolation?: string;
  112 + }>();
77 useEffect(() => { 113 useEffect(() => {
78 - if (_.isEmpty(props?.node?.data)) { 114 + if (isEmpty(props?.node?.data)) {
79 return; 115 return;
80 } 116 }
81 - if (_.isEqual(props?.node?.data, values)) { 117 + if (isEqual(props?.node?.data, values)) {
82 return; 118 return;
83 } 119 }
84 - setValues(props?.node?.data);  
85 - }, [props?.node?.data]); 120 + setValues({ ...props?.node?.data });
  121 + form.setFieldsValue({ ...props?.node?.data });
  122 + }, [JSON.stringify(props?.node?.data)]);
86 123
87 const onCheckedChange = (e: CheckboxChangeEvent) => { 124 const onCheckedChange = (e: CheckboxChangeEvent) => {
88 - const _cloneVal = _.cloneDeep(values); 125 + const _cloneVal = !!values ? cloneDeep(values) : {};
89 setValues({ 126 setValues({
90 ..._cloneVal, 127 ..._cloneVal,
91 enablePropagation: e.target.checked, 128 enablePropagation: e.target.checked,
@@ -93,11 +130,11 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> = @@ -93,11 +130,11 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> =
93 }; 130 };
94 131
95 useEffect(() => { 132 useEffect(() => {
96 - if (_.isEqual(props?.node?.data, values)) { 133 + if (!values || isEqual(props?.node?.data, values)) {
97 return; 134 return;
98 } 135 }
99 props.onChange(values); 136 props.onChange(values);
100 - }, [values]); 137 + }, [JSON.stringify(values)]);
101 138
102 return ( 139 return (
103 <Form 140 <Form
@@ -109,37 +146,55 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> = @@ -109,37 +146,55 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> =
109 isolation: 'REPEATABLE_READ', 146 isolation: 'REPEATABLE_READ',
110 }} 147 }}
111 > 148 >
112 - <Form.Item name="params"> 149 + <Form.Item
  150 + style={{
  151 + marginBottom: '24px',
  152 + }}
  153 + name="params"
  154 + >
113 <h3 className={'qx-flow-form__label-title'}>入参设置</h3> 155 <h3 className={'qx-flow-form__label-title'}>入参设置</h3>
114 <p className={'qx-flow-form__label-tips'}> 156 <p className={'qx-flow-form__label-tips'}>
115 参数可以被后面的所有数据流节点使用 157 参数可以被后面的所有数据流节点使用
116 </p> 158 </p>
117 <QxParameterSetting 159 <QxParameterSetting
118 - value={values.params} 160 + // @ts-ignore
  161 + value={values?.params || []}
119 onChange={(_v: any) => { 162 onChange={(_v: any) => {
120 - console.log('参数 === ', _v); 163 + const _cloneVal = cloneDeep(values);
  164 + setValues({
  165 + ..._cloneVal,
  166 + params: _v,
  167 + });
121 }} 168 }}
122 /> 169 />
123 </Form.Item> 170 </Form.Item>
124 - <Form.Item name="enablePropagation"> 171 + <Form.Item
  172 + style={{
  173 + marginBottom: '16px',
  174 + }}
  175 + name="enablePropagation"
  176 + >
125 <h3 className={'qx-flow-form__label-title'}>事务控制</h3> 177 <h3 className={'qx-flow-form__label-title'}>事务控制</h3>
126 <Checkbox 178 <Checkbox
127 - checked={values.enablePropagation} 179 + checked={values?.enablePropagation}
128 onChange={onCheckedChange} 180 onChange={onCheckedChange}
129 > 181 >
130 设置事务的传播行为和隔离级别 182 设置事务的传播行为和隔离级别
131 </Checkbox> 183 </Checkbox>
132 </Form.Item> 184 </Form.Item>
133 <Form.Item 185 <Form.Item
134 - hidden={!values.enablePropagation} 186 + hidden={!values?.enablePropagation}
135 label="事务传播行为" 187 label="事务传播行为"
136 name="propagation" 188 name="propagation"
  189 + style={{
  190 + marginBottom: '16px',
  191 + }}
137 > 192 >
138 <PropagationSetting 193 <PropagationSetting
139 optionsList={propagationList} 194 optionsList={propagationList}
140 - value={'REQUIRED'} 195 + value={values?.propagation || 'REQUIRED'}
141 onChange={(_v: string) => { 196 onChange={(_v: string) => {
142 - const _cloneVal = _.cloneDeep(values); 197 + const _cloneVal = cloneDeep(values);
143 setValues({ 198 setValues({
144 ..._cloneVal, 199 ..._cloneVal,
145 propagation: _v, 200 propagation: _v,
@@ -148,15 +203,15 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> = @@ -148,15 +203,15 @@ const StartConfigComponent: React.FC<StartConfigComponentProps> =
148 /> 203 />
149 </Form.Item> 204 </Form.Item>
150 <Form.Item 205 <Form.Item
151 - hidden={!values.enablePropagation} 206 + hidden={!values?.enablePropagation}
152 label="事务隔离级别" 207 label="事务隔离级别"
153 name="isolation" 208 name="isolation"
154 > 209 >
155 <PropagationSetting 210 <PropagationSetting
156 optionsList={isolationList} 211 optionsList={isolationList}
157 - value={'REPEATABLE_READ'} 212 + value={values?.isolation || 'REPEATABLE_READ'}
158 onChange={(_v: string) => { 213 onChange={(_v: string) => {
159 - const _cloneVal = _.cloneDeep(values); 214 + const _cloneVal = cloneDeep(values);
160 setValues({ 215 setValues({
161 ..._cloneVal, 216 ..._cloneVal,
162 isolation: _v, 217 isolation: _v,
1 import React, { memo } from 'react'; 1 import React, { memo } from 'react';
2 -// import { ReactComponent as Icon } from '../../public/icons/outlined.svg'; 2 +import { Button, Typography } from 'antd';
  3 +import { useAction } from '@qx/flow';
  4 +const { Text } = Typography;
3 import type { IDisplayComponent, INode } from '@qx/flow'; 5 import type { IDisplayComponent, INode } from '@qx/flow';
4 -// import './index.less'; 6 +
  7 +const paramsEnums: Record<string, string> = {
  8 + STRING: '文本',
  9 + NUMBER: '数字',
  10 + TIME: '日期',
  11 + BOOL: '布尔',
  12 + OBJECT: '对象',
  13 + ARRAY: '数组',
  14 + ANNEX: '附件',
  15 + PIC: '图片',
  16 + FORM: '表单',
  17 + USER: '人员',
  18 + ORG: '部门',
  19 +};
5 20
6 const DisplayComponent: React.FC<DisplayComponentProps> = (props) => { 21 const DisplayComponent: React.FC<DisplayComponentProps> = (props) => {
7 const { node, nodes } = props; 22 const { node, nodes } = props;
@@ -11,6 +26,8 @@ const DisplayComponent: React.FC<DisplayComponentProps> = (props) => { @@ -11,6 +26,8 @@ const DisplayComponent: React.FC<DisplayComponentProps> = (props) => {
11 props.onChange?.([...nodes]); 26 props.onChange?.([...nodes]);
12 }; 27 };
13 28
  29 + const { clickNode } = useAction();
  30 +
14 return ( 31 return (
15 <div className="qx-flow-default-node"> 32 <div className="qx-flow-default-node">
16 <div className="qx-flow-default-node__header"> 33 <div className="qx-flow-default-node__header">
@@ -21,13 +38,38 @@ const DisplayComponent: React.FC<DisplayComponentProps> = (props) => { @@ -21,13 +38,38 @@ const DisplayComponent: React.FC<DisplayComponentProps> = (props) => {
21 <span className="qx-flow-default-node__title--name">{node.name}</span> 38 <span className="qx-flow-default-node__title--name">{node.name}</span>
22 </span> 39 </span>
23 </div> 40 </div>
24 - <div className="qx-flow-default-node__content">  
25 - {!node.data ? (  
26 - <span className="qx-flow-end-node__button">设置入参</span>  
27 - ) : (  
28 - <span>节点配置内容</span>  
29 - )}  
30 - </div> 41 + {!!node?.data?.params?.length ? (
  42 + <>
  43 + <div className="qx-flow-default-node__content">
  44 + {props?.node?.data?.params.map((_v: any) => {
  45 + return (
  46 + <Text
  47 + style={{
  48 + width: '100%',
  49 + lineHeight: '22px',
  50 + }}
  51 + ellipsis={{
  52 + tooltip: `${paramsEnums?.[_v.type || '']}&nbsp;${
  53 + _v.title || '未命名'
  54 + }`,
  55 + }}
  56 + >
  57 + {paramsEnums?.[_v.type || '']}&nbsp;{_v.title || '未命名'}
  58 + </Text>
  59 + );
  60 + })}
  61 + </div>
  62 + </>
  63 + ) : (
  64 + <Button
  65 + style={{ marginTop: 8 }}
  66 + type="link"
  67 + size="small"
  68 + // onClick={() => clickNode()}
  69 + >
  70 + 设置入参
  71 + </Button>
  72 + )}
31 </div> 73 </div>
32 ); 74 );
33 }; 75 };
@@ -9,8 +9,9 @@ import { QxIcon } from '@/components'; @@ -9,8 +9,9 @@ import { QxIcon } from '@/components';
9 import { isEmpty } from 'lodash-es'; 9 import { isEmpty } from 'lodash-es';
10 import { handleWindowOpen } from '@qx/utils'; 10 import { handleWindowOpen } from '@qx/utils';
11 // import {} from '@/src/services/data-flow'; 11 // import {} from '@/src/services/data-flow';
12 -import { getIcon, useFlowTableScrollY } from '@/utils'; 12 +import { getIcon } from '@/utils';
13 import { useDebounceEffect } from 'ahooks'; 13 import { useDebounceEffect } from 'ahooks';
  14 +import { useFlowTableScrollY } from '@/hooks';
14 15
15 const { Text } = Typography; 16 const { Text } = Typography;
16 17
@@ -16,7 +16,8 @@ import { useDebounceEffect, useDebounceFn } from 'ahooks'; @@ -16,7 +16,8 @@ import { useDebounceEffect, useDebounceFn } from 'ahooks';
16 import { isEmpty, cloneDeep } from 'lodash-es'; 16 import { isEmpty, cloneDeep } from 'lodash-es';
17 17
18 import { FlowSettingProps } from '@/page/view/constant'; 18 import { FlowSettingProps } from '@/page/view/constant';
19 -import { getIcon, useFlowTableScrollY } from '@/utils'; 19 +import { getIcon } from '@/utils';
  20 +import { useFlowTableScrollY } from '@/hooks';
20 import actions from '@/utils/actions'; 21 import actions from '@/utils/actions';
21 22
22 import { copyProcessById, deleteProcessById, getListProcess } from '@/services'; 23 import { copyProcessById, deleteProcessById, getListProcess } from '@/services';
1 import React from 'react'; 1 import React from 'react';
2 // import { history } from '@@/core/history'; 2 // import { history } from '@@/core/history';
3 -import { useSearchParams } from 'react-router-dom'; 3 +import { useSearchParams } from '@/hooks';
4 import { useTitle } from 'ahooks'; 4 import { useTitle } from 'ahooks';
5 // @ts-ignore; 5 // @ts-ignore;
6 import { handleWindowOpen } from '@qx/utils'; 6 import { handleWindowOpen } from '@qx/utils';
@@ -13,16 +13,12 @@ import styles from '@/page/view/index.module.less'; @@ -13,16 +13,12 @@ import styles from '@/page/view/index.module.less';
13 const prefix = 'qx-data-flow'; 13 const prefix = 'qx-data-flow';
14 14
15 const DataFlowView: React.FC = ({}) => { 15 const DataFlowView: React.FC = ({}) => {
16 - const [searchParams] = useSearchParams(); 16 + const [query] = useSearchParams<any>();
17 const { 17 const {
18 appId, // 应用id 18 appId, // 应用id
19 funCode, // 表单id 19 funCode, // 表单id
20 returnUrl, // 来自页面跳转返回可跳转 20 returnUrl, // 来自页面跳转返回可跳转
21 - } = {  
22 - appId: searchParams.get('appId'),  
23 - funCode: searchParams.get('funCode'),  
24 - returnUrl: searchParams.get('returnUrl'),  
25 - }; 21 + } = query;
26 22
27 // 添加标题 23 // 添加标题
28 if (!!appId && !funCode) { 24 if (!!appId && !funCode) {
@@ -44,94 +44,3 @@ export const getIcon = (icon: string, type?: string) => { @@ -44,94 +44,3 @@ export const getIcon = (icon: string, type?: string) => {
44 ); 44 );
45 } 45 }
46 }; 46 };
47 -  
48 -// 表格 Scroll 高度计算  
49 -export const useFlowTableScrollY = (  
50 - deps: {  
51 - columns: any[];  
52 - size?: 'small' | 'middle' | 'default';  
53 - tableBoxClassName?: string;  
54 - classNames?: string[]; // 表格DOM内嵌元素 列名 添加在此,  
55 - hasPagination?: boolean;  
56 - listProps?: any;  
57 - } = {  
58 - size: 'small',  
59 - tableBoxClassName: '',  
60 - classNames: [],  
61 - hasPagination: false,  
62 - columns: [],  
63 - listProps: {},  
64 - },  
65 -) => {  
66 - const itemHeaderHeight =  
67 - (deps?.size === 'middle' ? 48 : deps?.size === 'default' ? 56 : 40) + 1;  
68 - const TABLE_VIEW_LIST = deps?.tableBoxClassName || 'qx-data-flow-table';  
69 - let tableHeader = itemHeaderHeight;  
70 - const tableViewListDefaultHeight = 400;  
71 - const defaultPagePadding = 0;  
72 -  
73 - const $ = (selectors: string) =>  
74 - document.querySelector<HTMLElement>(selectors);  
75 -  
76 - const defaultScrollY = useMemo(  
77 - () => document.body.clientHeight,  
78 - [tableHeader],  
79 - );  
80 -  
81 - const [scrollY, setScrollY] = useState<number>(defaultScrollY ?? 200);  
82 -  
83 - const timer = useRef<NodeJS.Timer>();  
84 -  
85 - const getScrollY = () => {  
86 - const tableViewList = $(`.${TABLE_VIEW_LIST}`);  
87 -  
88 - const tableViewListClientHeight =  
89 - tableViewList?.clientHeight || tableViewListDefaultHeight;  
90 - // 分页大小 目前已经固定 所以直接用56px  
91 - const antPaginationHeight = deps?.hasPagination ? 56 : 0;  
92 -  
93 - const _domHeightByClassName = (deps?.classNames || []).map(  
94 - (_v: string) => $(`.${_v}`)?.clientHeight ?? 0,  
95 - );  
96 - let result =  
97 - tableViewListClientHeight -  
98 - tableHeader -  
99 - defaultPagePadding -  
100 - antPaginationHeight;  
101 - if (!!_domHeightByClassName?.length) {  
102 - result = result - eval(_domHeightByClassName.join('+'));  
103 - }  
104 -  
105 - if (tableViewList) {  
106 - tableViewList.style.overflowY = result < 200 ? 'auto' : 'hidden';  
107 - }  
108 -  
109 - setScrollY(result < 100 ? 100 : result);  
110 - };  
111 -  
112 - const observer = () => {  
113 - window.addEventListener('resize', getScrollY);  
114 - };  
115 -  
116 - const removeObserver = () => {  
117 - if (timer.current) window.clearTimeout(timer.current);  
118 - window.removeEventListener('resize', getScrollY);  
119 - };  
120 -  
121 - useEffect(() => {  
122 - observer();  
123 - return () => {  
124 - removeObserver();  
125 - };  
126 - }, [tableHeader]);  
127 -  
128 - useEffect(() => {  
129 - if (deps) {  
130 - timer.current = setTimeout(() => {  
131 - getScrollY();  
132 - }, 100);  
133 - }  
134 - }, [JSON.stringify(deps)]);  
135 -  
136 - return [scrollY, getScrollY];  
137 -};  
@@ -11,14 +11,13 @@ import { @@ -11,14 +11,13 @@ import {
11 Avatar, 11 Avatar,
12 } from 'antd'; 12 } from 'antd';
13 13
14 -import { SettingOutlined } from '@ant-design/icons/lib';  
15 -import { useSearchParams } from 'react-router-dom'; 14 +import { useSearchParams } from '@/hooks';
16 import { useTitle } from 'ahooks'; 15 import { useTitle } from 'ahooks';
17 import { QxIcon } from '@/components'; 16 import { QxIcon } from '@/components';
18 import { handleWindowOpen } from '@qx/utils'; 17 import { handleWindowOpen } from '@qx/utils';
19 import { FlowHeader, FlowVersion } from '@/components'; 18 import { FlowHeader, FlowVersion } from '@/components';
20 19
21 -import { useFlowTableScrollY } from '@/utils'; 20 +import { useFlowTableScrollY } from '@/hooks';
22 import actions from '@/utils/actions'; 21 import actions from '@/utils/actions';
23 22
24 import { isEmpty, cloneDeep } from 'lodash-es'; 23 import { isEmpty, cloneDeep } from 'lodash-es';
@@ -33,17 +32,12 @@ import { FlowVersionStatusEnums } from '@/interface'; @@ -33,17 +32,12 @@ import { FlowVersionStatusEnums } from '@/interface';
33 const prefix = 'qx-flow-setting'; 32 const prefix = 'qx-flow-setting';
34 33
35 const DataFlowVersion: React.FC = ({}) => { 34 const DataFlowVersion: React.FC = ({}) => {
36 - // @ts-ignore  
37 - const [searchParams] = useSearchParams(); 35 + const [query] = useSearchParams<any>();
38 const { 36 const {
39 processId, // 流程ID 37 processId, // 流程ID
40 name, // 流程名称 38 name, // 流程名称
41 returnUrl, // 来自页面跳转返回可跳转 39 returnUrl, // 来自页面跳转返回可跳转
42 - } = {  
43 - processId: searchParams.get('processId'),  
44 - name: searchParams.get('name'),  
45 - returnUrl: searchParams.get('returnUrl'),  
46 - }; 40 + } = query;
47 const [pageData, setPageData] = useState<any[]>([]); 41 const [pageData, setPageData] = useState<any[]>([]);
48 const [tableLoading, setTableLoading] = useState<boolean>(true); // 表格loading 42 const [tableLoading, setTableLoading] = useState<boolean>(true); // 表格loading
49 // 表格是否添加scroll 属性 43 // 表格是否添加scroll 属性
1 import { createHashRouter, RouterProvider } from 'react-router-dom'; 1 import { createHashRouter, RouterProvider } from 'react-router-dom';
2 import Root from '../page/root'; 2 import Root from '../page/root';
3 -import About from '../page/about';  
4 -import Designer from '../page/designer';  
5 -import List from '../page/view/list';  
6 -import Version from '../page/view/version'; 3 +import lazyComponent from '@/components/lazy-component';
7 4
8 export default () => ( 5 export default () => (
9 <RouterProvider 6 <RouterProvider
@@ -14,19 +11,27 @@ export default () => ( @@ -14,19 +11,27 @@ export default () => (
14 children: [ 11 children: [
15 { 12 {
16 path: '/about', 13 path: '/about',
17 - element: <About />, 14 + element: lazyComponent(
  15 + () => import(/*qx-dataflow-about*/ '@/page/about'),
  16 + ),
18 }, 17 },
19 { 18 {
20 path: '/designer', 19 path: '/designer',
21 - element: <Designer />, 20 + element: lazyComponent(
  21 + () => import(/*qx-dataflow-designer*/ '@/page/designer'),
  22 + ),
22 }, 23 },
23 { 24 {
24 path: '/list', 25 path: '/list',
25 - element: <List />, 26 + element: lazyComponent(
  27 + () => import(/*qx-dataflow-list*/ '@/page/view/list'),
  28 + ),
26 }, 29 },
27 { 30 {
28 path: '/version', 31 path: '/version',
29 - element: <Version />, 32 + element: lazyComponent(
  33 + () => import(/*qx-dataflow-version*/ '@/page/view/version'),
  34 + ),
30 }, 35 },
31 ], 36 ],
32 }, 37 },
@@ -4,6 +4,7 @@ import request from '@/request'; @@ -4,6 +4,7 @@ import request from '@/request';
4 const qxSdk = new QxSdk(); 4 const qxSdk = new QxSdk();
5 5
6 qxSdk.registerSdk({ 6 qxSdk.registerSdk({
  7 + // @ts-ignore
7 getFormFields(appCode: string, funCode: string, viewCode: string) { 8 getFormFields(appCode: string, funCode: string, viewCode: string) {
8 return request.get( 9 return request.get(
9 `/qx-apaas-lowcode/app/${appCode}/form/${funCode}/field/option/${viewCode}?withRel=true`, 10 `/qx-apaas-lowcode/app/${appCode}/form/${funCode}/field/option/${viewCode}?withRel=true`,
1 -import React, { useEffect, useMemo, useRef, useState } from 'react';  
2 -  
3 -import { Button, Image, message, Modal, Tooltip, Upload } from 'antd'; 1 +import { Image, Skeleton } from 'antd';
4 import { QxIcon } from '@/components'; 2 import { QxIcon } from '@/components';
5 3
6 -import defaultImg from '@/components/default/default_cover.png'; 4 +import defaultImg from '@/public/imgs/default_cover.png';
7 5
8 const defaultIcon: Record<string, string> = { 6 const defaultIcon: Record<string, string> = {
9 form: 'icon-app-file-fill', 7 form: 'icon-app-file-fill',
@@ -44,94 +42,3 @@ export const getIcon = (icon: string, type?: string) => { @@ -44,94 +42,3 @@ export const getIcon = (icon: string, type?: string) => {
44 ); 42 );
45 } 43 }
46 }; 44 };
47 -  
48 -// 表格 Scroll 高度计算  
49 -export const useFlowTableScrollY = (  
50 - deps: {  
51 - columns: any[];  
52 - size?: 'small' | 'middle' | 'default';  
53 - tableBoxClassName?: string;  
54 - classNames?: string[]; // 表格DOM内嵌元素 列名 添加在此,  
55 - hasPagination?: boolean;  
56 - listProps?: any;  
57 - } = {  
58 - size: 'small',  
59 - tableBoxClassName: '',  
60 - classNames: [],  
61 - hasPagination: false,  
62 - columns: [],  
63 - listProps: {},  
64 - },  
65 -) => {  
66 - const itemHeaderHeight =  
67 - (deps?.size === 'middle' ? 48 : deps?.size === 'default' ? 56 : 40) + 1;  
68 - const TABLE_VIEW_LIST = deps?.tableBoxClassName || 'qx-data-flow-table';  
69 - let tableHeader = itemHeaderHeight;  
70 - const tableViewListDefaultHeight = 400;  
71 - const defaultPagePadding = 0;  
72 -  
73 - const $ = (selectors: string) =>  
74 - document.querySelector<HTMLElement>(selectors);  
75 -  
76 - const defaultScrollY = useMemo(  
77 - () => document.body.clientHeight,  
78 - [tableHeader],  
79 - );  
80 -  
81 - const [scrollY, setScrollY] = useState<number>(defaultScrollY ?? 200);  
82 -  
83 - const timer = useRef<NodeJS.Timer>();  
84 -  
85 - const getScrollY = () => {  
86 - const tableViewList = $(`.${TABLE_VIEW_LIST}`);  
87 -  
88 - const tableViewListClientHeight =  
89 - tableViewList?.clientHeight || tableViewListDefaultHeight;  
90 - // 分页大小 目前已经固定 所以直接用56px  
91 - const antPaginationHeight = deps?.hasPagination ? 56 : 0;  
92 -  
93 - const _domHeightByClassName = (deps?.classNames || []).map(  
94 - (_v: string) => $(`.${_v}`)?.clientHeight ?? 0,  
95 - );  
96 - let result =  
97 - tableViewListClientHeight -  
98 - tableHeader -  
99 - defaultPagePadding -  
100 - antPaginationHeight;  
101 - if (!!_domHeightByClassName?.length) {  
102 - result = result - eval(_domHeightByClassName.join('+'));  
103 - }  
104 -  
105 - if (tableViewList) {  
106 - tableViewList.style.overflowY = result < 200 ? 'auto' : 'hidden';  
107 - }  
108 -  
109 - setScrollY(result < 100 ? 100 : result);  
110 - };  
111 -  
112 - const observer = () => {  
113 - window.addEventListener('resize', getScrollY);  
114 - };  
115 -  
116 - const removeObserver = () => {  
117 - if (timer.current) window.clearTimeout(timer.current);  
118 - window.removeEventListener('resize', getScrollY);  
119 - };  
120 -  
121 - useEffect(() => {  
122 - observer();  
123 - return () => {  
124 - removeObserver();  
125 - };  
126 - }, [tableHeader]);  
127 -  
128 - useEffect(() => {  
129 - if (deps) {  
130 - timer.current = setTimeout(() => {  
131 - getScrollY();  
132 - }, 100);  
133 - }  
134 - }, [JSON.stringify(deps)]);  
135 -  
136 - return [scrollY, getScrollY];  
137 -};