Commit 2dc87cfe42f9085f1360dd990cd6043e19bcd37f

Authored by 李婷
2 parents fb9ccb11 f60a1554

Merge remote-tracking branch 'origin/feature/dataflow' into feature/dataflow

1 { 1 {
2 "name": "@qx/common", 2 "name": "@qx/common",
3 - "version": "3.0.0-alpha.30", 3 + "version": "3.0.0-alpha.31",
4 "description": "A react library developed with dumi", 4 "description": "A react library developed with dumi",
5 "license": "MIT", 5 "license": "MIT",
6 "module": "dist/index.js", 6 "module": "dist/index.js",
  1 +import { createContext } from 'react'
  2 +
  3 +export interface QxFieldExtract {
  4 + widget: string;
  5 + $base?: boolean;
  6 + allowSelect?: boolean;
  7 + fieldKey: string;
  8 + fieldType: string;
  9 + fieldGroupType?: string;
  10 + relId?: string;
  11 + [key: string]: any;
  12 +}
  13 +
  14 +export interface QxField {
  15 + name: string;
  16 + code: string;
  17 + extract: QxFieldExtract;
  18 +}
  19 +
  20 +export interface FieldContextType {
  21 + fields: QxField[];
  22 + setFields: (fields: QxField[]) => void
  23 +}
  24 +
  25 +export const FieldContext = createContext<FieldContextType>({} as FieldContextType)
  1 +import React, { useState } from 'react';
  2 +import { FieldContext, QxField } from '../../context';
  3 +
  4 +export const QxFieldProvider: React.FC<QxFieldProviderProps> = (props) => {
  5 + const [fields, setFields] = useState<QxField[]>([]);
  6 +
  7 + return (
  8 + <FieldContext.Provider value={{ fields, setFields }}>
  9 + {props.children}
  10 + </FieldContext.Provider>
  11 + );
  12 +};
  13 +
  14 +interface QxFieldProviderProps {
  15 + children?: React.ReactNode;
  16 +}
@@ -2,7 +2,7 @@ import { QxWidgetIcon } from '@qx/common'; @@ -2,7 +2,7 @@ import { QxWidgetIcon } from '@qx/common';
2 import { Collapse, Dropdown, Empty, Tag } from 'antd'; 2 import { Collapse, Dropdown, Empty, Tag } from 'antd';
3 import cls from 'classnames'; 3 import cls from 'classnames';
4 import { cloneDeep } from 'lodash-es'; 4 import { cloneDeep } from 'lodash-es';
5 -import React, { useEffect, useState } from 'react'; 5 +import React, { useEffect, useMemo, useState } from 'react';
6 import { FieldBaseType } from '../qx-base-condition'; 6 import { FieldBaseType } from '../qx-base-condition';
7 import { QxBaseIcon } from '../qx-base-icon'; 7 import { QxBaseIcon } from '../qx-base-icon';
8 import { request } from '../utils'; 8 import { request } from '../utils';
@@ -99,60 +99,75 @@ export const useNodeFieldDisplay = ({ @@ -99,60 +99,75 @@ export const useNodeFieldDisplay = ({
99 const [inputDisplay, setInputDisplay] = useState<React.ReactNode>(); 99 const [inputDisplay, setInputDisplay] = useState<React.ReactNode>();
100 const [optionalNodes, setOptionalNodes] = useState<INode[]>([]); // 根据 fieldType 过滤后的 nodes 100 const [optionalNodes, setOptionalNodes] = useState<INode[]>([]); // 根据 fieldType 过滤后的 nodes
101 101
102 - const getId = (val?: string) => {  
103 - if (!val) return; 102 + const getIds = (val?: string) => {
  103 + if (!val) return [];
  104 + let newVal = val;
104 const startIndex = val.indexOf('|') + 1; 105 const startIndex = val.indexOf('|') + 1;
105 const endIndex = val.indexOf('}'); 106 const endIndex = val.indexOf('}');
106 if (startIndex < endIndex) { 107 if (startIndex < endIndex) {
107 - return val.substring(startIndex, endIndex); 108 + newVal = val.substring(startIndex, endIndex);
108 } 109 }
109 - return null;  
110 - };  
111 -  
112 - const getDisplayConfig = (value: string, nodes: INode[] = optionalNodes) => {  
113 - const itemId = getId(value);  
114 - if (!itemId) return [];  
115 - let displayConfig: any[] = [];  
116 - let n = true;  
117 - let index = 0;  
118 - while (n && index <= 20) {  
119 - displayConfig = [];  
120 - // eslint-disable-next-line @typescript-eslint/no-use-before-define  
121 - const curNode = cloneDeep(nodes[index]) || {};  
122 - displayConfig.push({  
123 - title: curNode.name,  
124 - icon: curNode.icon,  
125 - ...curNode,  
126 - });  
127 - // eslint-disable-next-line @typescript-eslint/no-use-before-define  
128 - recursionNodeResult(curNode.data?.result);  
129 - index++;  
130 - }  
131 -  
132 - function recursionNodeResult(result: FiledType[], idx = 1) {  
133 - if (Array.isArray(result)) {  
134 - for (let i = 0; i < result.length; i++) {  
135 - const item = result[i];  
136 - if (!n) return;  
137 110
138 - displayConfig.splice(idx, 1, item);  
139 - displayConfig = displayConfig.slice(0, idx + 1); 111 + const nodeId = val.split('|')[0].substring(2);
140 112
141 - if (itemId === item.id) {  
142 - n = false;  
143 - return;  
144 - }  
145 -  
146 - if (Array.isArray(item.child)) {  
147 - recursionNodeResult(item.child, idx + 1);  
148 - }  
149 - } 113 + return [nodeId, ...newVal.split('.').reduce<string[]>((pre, cur, idx) => {
  114 + if (idx === 0) {
  115 + pre.push(`${nodeId}|${cur}`);
150 } else { 116 } else {
151 - n = false; 117 + pre.push(`${pre[idx - 1]}.${cur}`);
152 } 118 }
153 - }  
154 119
155 - return displayConfig; 120 + return pre;
  121 + }, [])];
  122 + };
  123 +
  124 + const getDisplayConfig = (value: string, nodes: INode[] = optionalNodes) => {
  125 + const itemIds = getIds(value);
  126 +
  127 + if (!itemIds || !itemIds.length) return [];
  128 +
  129 + // let displayConfig: any[] = [];
  130 + // let n = true;
  131 + // let index = 0;
  132 + // while (n && index <= 20) {
  133 + // displayConfig = [];
  134 + // // eslint-disable-next-line @typescript-eslint/no-use-before-define
  135 + // const curNode = cloneDeep(nodes[index]) || {};
  136 + // displayConfig.push({
  137 + // title: curNode.name,
  138 + // icon: curNode.icon,
  139 + // ...curNode,
  140 + // });
  141 + // // eslint-disable-next-line @typescript-eslint/no-use-before-define
  142 + // recursionNodeResult(curNode.data?.result);
  143 + // index++;
  144 + // }
  145 +
  146 + // function recursionNodeResult(result: FiledType[], idx = 1) {
  147 + // if (Array.isArray(result)) {
  148 + // for (let i = 0; i < result.length; i++) {
  149 + // const item = result[i];
  150 + // if (!n) return;
  151 +
  152 + // displayConfig.splice(idx, 1, item);
  153 + // displayConfig = displayConfig.slice(0, idx + 1);
  154 +
  155 + // if (itemId === item.id) {
  156 + // n = false;
  157 + // return;
  158 + // }
  159 +
  160 + // if (Array.isArray(item.child)) {
  161 + // recursionNodeResult(item.child, idx + 1);
  162 + // }
  163 + // }
  164 + // } else {
  165 + // n = false;
  166 + // }
  167 + // }
  168 +
  169 + // eslint-disable-next-line @typescript-eslint/no-use-before-define
  170 + return itemIds.map((id) => resultFieldMaps[id]);
156 }; 171 };
157 172
158 const genDisplayDom = (value: string, nodes: INode[] = optionalNodes) => { 173 const genDisplayDom = (value: string, nodes: INode[] = optionalNodes) => {
@@ -171,7 +186,7 @@ export const useNodeFieldDisplay = ({ @@ -171,7 +186,7 @@ export const useNodeFieldDisplay = ({
171 FieldMapType[item.type] && 186 FieldMapType[item.type] &&
172 !item.icon && 187 !item.icon &&
173 `[${FieldMapType[item.type]}]`} 188 `[${FieldMapType[item.type]}]`}
174 - {item.title} 189 + {item.title || item.name}
175 </span> 190 </span>
176 {idx !== displayConfig.length - 1 && ( 191 {idx !== displayConfig.length - 1 && (
177 <span className="qx-node-select-input__content-item__arrow"> 192 <span className="qx-node-select-input__content-item__arrow">
@@ -274,22 +289,36 @@ export const useNodeFieldDisplay = ({ @@ -274,22 +289,36 @@ export const useNodeFieldDisplay = ({
274 return sourceParentNodes; 289 return sourceParentNodes;
275 }; 290 };
276 291
277 - const correctionNodeField = (fields: FiledType[] | FiledType) => { 292 + /**
  293 + * 统一字段格式
  294 + */
  295 + const correctionNodeField = (
  296 + fields: FiledType[] | FiledType,
  297 + nodeId: string,
  298 + parent?: FiledType | INode,
  299 + ) => {
278 if (Array.isArray(fields)) { 300 if (Array.isArray(fields)) {
279 for (let i = 0; i <= fields.length; i++) { 301 for (let i = 0; i <= fields.length; i++) {
280 - correctionNodeField(fields[i]); 302 + correctionNodeField(fields[i], nodeId, parent);
281 } 303 }
282 } else if (fields) { 304 } else if (fields) {
283 Object.assign(fields, { 305 Object.assign(fields, {
284 ...fields, 306 ...fields,
285 name: fields.title, 307 name: fields.title,
  308 + code: parent
  309 + ? `${parent.code}.${fields.code}`
  310 + : `${nodeId}|${fields.code}`,
286 extract: { 311 extract: {
287 ...(fields.extract || {}), 312 ...(fields.extract || {}),
288 fieldType: fields.type, 313 fieldType: fields.type,
289 fieldKey: fields.code, 314 fieldKey: fields.code,
290 }, 315 },
291 - child: correctionNodeField(fields.child!),  
292 }); 316 });
  317 + fields.child = correctionNodeField(
  318 + fields.child!,
  319 + nodeId,
  320 + fields,
  321 + ) as FiledType[];
293 } 322 }
294 323
295 return fields; 324 return fields;
@@ -299,7 +328,10 @@ export const useNodeFieldDisplay = ({ @@ -299,7 +328,10 @@ export const useNodeFieldDisplay = ({
299 const targetParentNodes = await handleGetAppsFields(); 328 const targetParentNodes = await handleGetAppsFields();
300 329
301 for (let i = 0; i < targetParentNodes.length; i++) { 330 for (let i = 0; i < targetParentNodes.length; i++) {
302 - correctionNodeField(targetParentNodes[i].data?.result || []); 331 + correctionNodeField(
  332 + targetParentNodes[i].data?.result || [],
  333 + targetParentNodes[i].id,
  334 + );
303 } 335 }
304 336
305 if (!limitTypes || !limitTypes.length) { 337 if (!limitTypes || !limitTypes.length) {
@@ -308,11 +340,14 @@ export const useNodeFieldDisplay = ({ @@ -308,11 +340,14 @@ export const useNodeFieldDisplay = ({
308 return; 340 return;
309 } 341 }
310 342
  343 + /**
  344 + * 根据 limitType 获取可选择的字段
  345 + */
311 function getEffectiveResult(result: FiledType[]) { 346 function getEffectiveResult(result: FiledType[]) {
312 const newResult = []; 347 const newResult = [];
313 for (let i = 0; i < result.length; i++) { 348 for (let i = 0; i < result.length; i++) {
314 const resultItem = result[i] || {}; 349 const resultItem = result[i] || {};
315 - correctionNodeField(resultItem); 350 + // correctionNodeField(resultItem, nodeId, parent);
316 351
317 if (resultItem.child) { 352 if (resultItem.child) {
318 resultItem.child = getEffectiveResult(resultItem.child); 353 resultItem.child = getEffectiveResult(resultItem.child);
@@ -355,6 +390,27 @@ export const useNodeFieldDisplay = ({ @@ -355,6 +390,27 @@ export const useNodeFieldDisplay = ({
355 renderInputDisplay([...newNodes]); 390 renderInputDisplay([...newNodes]);
356 }; 391 };
357 392
  393 + const resultFieldMaps = useMemo(() => {
  394 + const resultMap: Record<string, FiledType | INode> = {};
  395 + function genResultMap(result: FiledType[]) {
  396 + if (Array.isArray(result)) {
  397 + result.forEach((i) => {
  398 + resultMap[i.code] = i;
  399 + if (i.child) {
  400 + genResultMap(i.child);
  401 + }
  402 + });
  403 + }
  404 + }
  405 +
  406 + for (let i = 0; i < optionalNodes.length; i++) {
  407 + resultMap[optionalNodes[i].id] = optionalNodes[i];
  408 + genResultMap(optionalNodes[i]?.data?.result);
  409 + }
  410 +
  411 + return resultMap;
  412 + }, [optionalNodes]);
  413 +
358 useEffect(() => { 414 useEffect(() => {
359 getOptionalNodes(); 415 getOptionalNodes();
360 }, []); 416 }, []);
@@ -365,6 +421,7 @@ export const useNodeFieldDisplay = ({ @@ -365,6 +421,7 @@ export const useNodeFieldDisplay = ({
365 renderInputDisplay, 421 renderInputDisplay,
366 getDisplayConfig, 422 getDisplayConfig,
367 inputDisplay, 423 inputDisplay,
  424 + resultFieldMaps,
368 }; 425 };
369 }; 426 };
370 427
@@ -456,7 +513,6 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( @@ -456,7 +513,6 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
456 useNodeFieldDisplay(props); 513 useNodeFieldDisplay(props);
457 514
458 const getOptions = () => { 515 const getOptions = () => {
459 - console.log('optionalNodes', optionalNodes);  
460 return optionalNodes.map((node) => ({ 516 return optionalNodes.map((node) => ({
461 label: ( 517 label: (
462 <div className={cls('qx-node-select-dropdown-header')}> 518 <div className={cls('qx-node-select-dropdown-header')}>
@@ -485,7 +541,7 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = ( @@ -485,7 +541,7 @@ export const QxFlowNodeFieldSelector: React.FC<NodeFieldSelectProps> = (
485 }; 541 };
486 542
487 const handleItemClick = (nodeKey: string, item: any) => { 543 const handleItemClick = (nodeKey: string, item: any) => {
488 - const newValue = '${' + `${nodeKey}|${item.id}` + '}'; 544 + const newValue = '${' + item.code + '}';
489 props.onChange?.(newValue, item); 545 props.onChange?.(newValue, item);
490 if (!props.children) { 546 if (!props.children) {
491 renderInputDisplay(optionalNodes, newValue); 547 renderInputDisplay(optionalNodes, newValue);