Commit b6d9ac793f045e9ec2fcedfba87766865ac26b4b

Authored by 田强
1 parent 0cc560e7

refactor: 合并表头

1 -Subproject commit 16bddbb35931fb0371a6a31229de0fee5dddfe02 1 +Subproject commit 737655fcfa7b7a088a8e554aafadb982789b7c74
@@ -28,11 +28,11 @@ @@ -28,11 +28,11 @@
28 "@antv/x6": "^1.34.6", 28 "@antv/x6": "^1.34.6",
29 "@antv/x6-react-shape": "^1.6.0", 29 "@antv/x6-react-shape": "^1.6.0",
30 "@formulajs/formulajs": "^3.1.7", 30 "@formulajs/formulajs": "^3.1.7",
31 - "@qx/common": "0.2.12-beta.5", 31 + "@qx/common": "^0.2.13",
32 "@qx/form-design": "^0.0.35", 32 "@qx/form-design": "^0.0.35",
33 - "@qx/form-render": "0.0.51", 33 + "@qx/form-render": "^0.0.60",
34 "@qx/utils": "^0.0.37", 34 "@qx/utils": "^0.0.37",
35 - "@qx/view-render": "0.1.9-beta.19", 35 + "@qx/view-render": "0.1.19",
36 "@tinymce/tinymce-react": "^4.2.0", 36 "@tinymce/tinymce-react": "^4.2.0",
37 "ahooks": "^3.7.2", 37 "ahooks": "^3.7.2",
38 "antd": "^4.24.1", 38 "antd": "^4.24.1",
1 -// import { QIXIAO_TOKEN } from '@/libs/token'; 1 +import { QIXIAO_TOKEN } from '@/libs/token';
2 import { SYSTEM_WIDGETS } from '@/packages/qx-form-generator/src/utils/common'; 2 import { SYSTEM_WIDGETS } from '@/packages/qx-form-generator/src/utils/common';
3 import QxIcon from '@/packages/qx-icon'; 3 import QxIcon from '@/packages/qx-icon';
4 import { RelMoreModal, RelSingleModal } from '@/pages/app-view/form'; 4 import { RelMoreModal, RelSingleModal } from '@/pages/app-view/form';
@@ -43,7 +43,7 @@ interface QxRuntimeTableProps { @@ -43,7 +43,7 @@ interface QxRuntimeTableProps {
43 sort?: any[]; 43 sort?: any[];
44 onChange?: (pagination: any, filters: any, sorter: any) => void; 44 onChange?: (pagination: any, filters: any, sorter: any) => void;
45 [propName: string]: any; 45 [propName: string]: any;
46 - bodyHeight?: number; 46 + bodyHeight?: number
47 } 47 }
48 48
49 const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => { 49 const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => {
@@ -84,15 +84,11 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => { @@ -84,15 +84,11 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => {
84 return customAlphabet('abcdefghijklmnopqistuvwxyz', 6)(); 84 return customAlphabet('abcdefghijklmnopqistuvwxyz', 6)();
85 } 85 }
86 86
87 - const handleCellClick = (  
88 - record: any,  
89 - schemaData: QxTableCellAPISchema,  
90 - info?: any,  
91 - ) => { 87 + const handleCellClick = (record: any, schemaData: QxTableCellAPISchema, info?: any) => {
92 // console.log(record,schemaData,info) 88 // console.log(record,schemaData,info)
93 setRowData(record); //点击行的数据 89 setRowData(record); //点击行的数据
94 setCellSchema(schemaData); //列的schema 90 setCellSchema(schemaData); //列的schema
95 - setClickInfo(info || ''); // 点击标签的data_title id 91 + setClickInfo(info || '') // 点击标签的data_title id
96 setRandom(getId()); 92 setRandom(getId());
97 }; 93 };
98 94
@@ -104,10 +100,7 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => { @@ -104,10 +100,7 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => {
104 //1、关联记录以标签显示的时候,直接弹出该条数据详情 100 //1、关联记录以标签显示的时候,直接弹出该条数据详情
105 //2、关联记录以表格显示的时候,弹出关联记录表格 101 //2、关联记录以表格显示的时候,弹出关联记录表格
106 if (cellSchema?.widget === 'relSelector') { 102 if (cellSchema?.widget === 'relSelector') {
107 - if (  
108 - cellSchema?.mode === 'TABLE' &&  
109 - (rowData[cellSchema?.dataIndex] || []).length  
110 - ) { 103 + if (cellSchema?.mode === 'TABLE' && (rowData[cellSchema?.dataIndex] || []).length) {
111 //关联记录 表格形式 104 //关联记录 表格形式
112 relMoreModalRef.current.open({ 105 relMoreModalRef.current.open({
113 appCode: appCode, 106 appCode: appCode,
@@ -135,10 +128,7 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => { @@ -135,10 +128,7 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => {
135 modalTitle: clickInfo?.data_title, //表名 128 modalTitle: clickInfo?.data_title, //表名
136 }); 129 });
137 } 130 }
138 - } else if (  
139 - cellSchema?.widget === 'subform' &&  
140 - cellSchema?.type === 'TABLE'  
141 - ) { 131 + } else if (cellSchema?.widget === 'subform' && cellSchema?.type === 'TABLE') {
142 //子表 132 //子表
143 relMoreModalRef.current.open({ 133 relMoreModalRef.current.open({
144 appCode: appCode, 134 appCode: appCode,
@@ -171,7 +161,7 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => { @@ -171,7 +161,7 @@ const QxRuntimeTable: React.FC<QxRuntimeTableProps> = (props) => {
171 max={props.max} 161 max={props.max}
172 sort={props?.sort} 162 sort={props?.sort}
173 onPage={props?.onPage} 163 onPage={props?.onPage}
174 - // QIXIAO_TOKEN={QIXIAO_TOKEN} 164 + QIXIAO_TOKEN={QIXIAO_TOKEN}
175 /> 165 />
176 <RelMoreModal cRef={relMoreModalRef} /> 166 <RelMoreModal cRef={relMoreModalRef} />
177 <RelSingleModal cRef={relSingleModalRef} /> 167 <RelSingleModal cRef={relSingleModalRef} />
@@ -274,26 +264,23 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => { @@ -274,26 +264,23 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => {
274 }); 264 });
275 }; 265 };
276 266
277 - const generateTreeData = useCallback(  
278 - (_data: any[], _keywords?: string): any[] => {  
279 - const _treeNode: any[] = [];  
280 - _data.map((item) => {  
281 - if (typeof item.visible === 'boolean' && !item.visible) {  
282 - return;  
283 - }  
284 - const _item: any = {  
285 - ...item,  
286 - children: [],  
287 - };  
288 - if (item.children) {  
289 - _item.children = generateTreeData(item.children, _keywords);  
290 - }  
291 - _treeNode.push(_item);  
292 - });  
293 - return _treeNode;  
294 - },  
295 - [],  
296 - ); 267 + const generateTreeData = useCallback((_data: any[], _keywords?: string): any[] => {
  268 + const _treeNode: any[] = [];
  269 + _data.map((item) => {
  270 + if (typeof item.visible === 'boolean' && !item.visible) {
  271 + return;
  272 + }
  273 + const _item: any = {
  274 + ...item,
  275 + children: [],
  276 + };
  277 + if (item.children) {
  278 + _item.children = generateTreeData(item.children, _keywords);
  279 + }
  280 + _treeNode.push(_item);
  281 + });
  282 + return _treeNode;
  283 + }, []);
297 284
298 const filter = (word: string) => { 285 const filter = (word: string) => {
299 setKeyword(word); 286 setKeyword(word);
@@ -429,9 +416,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => { @@ -429,9 +416,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => {
429 416
430 // 渲染节点 417 // 渲染节点
431 const renderTitle = (nodeData: any) => { 418 const renderTitle = (nodeData: any) => {
432 - const btnList = (  
433 - treeSchema?.tree?.action?.renderData?.buttons || []  
434 - ).filter((item: any) => { 419 + const btnList = (treeSchema?.tree?.action?.renderData?.buttons || []).filter((item: any) => {
435 if (!!nodeData?.extract?.[item.flag]) { 420 if (!!nodeData?.extract?.[item.flag]) {
436 return item; 421 return item;
437 } 422 }
@@ -472,9 +457,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => { @@ -472,9 +457,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => {
472 <Menu> 457 <Menu>
473 {_.drop(btnList, MAX).map((val: any) => { 458 {_.drop(btnList, MAX).map((val: any) => {
474 return ( 459 return (
475 - <Menu.Item key={val.code}>  
476 - {getBtnDom(val, nodeData, treeSchema)}  
477 - </Menu.Item> 460 + <Menu.Item key={val.code}>{getBtnDom(val, nodeData, treeSchema)}</Menu.Item>
478 ); 461 );
479 })} 462 })}
480 </Menu> 463 </Menu>
@@ -492,10 +475,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => { @@ -492,10 +475,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => {
492 }; 475 };
493 476
494 return ( 477 return (
495 - <div  
496 - className={'qx-tree-list'}  
497 - style={{ padding: '20px', backgroundColor: '#fff' }}  
498 - > 478 + <div className={'qx-tree-list'} style={{ padding: '20px', backgroundColor: '#fff' }}>
499 {data && data.length > 0 && treeSchema?.tree?.searchSwitch && ( 479 {data && data.length > 0 && treeSchema?.tree?.searchSwitch && (
500 <Input 480 <Input
501 className={'qx-selector-sub-search'} 481 className={'qx-selector-sub-search'}
@@ -545,10 +525,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => { @@ -545,10 +525,7 @@ const QxRuntimeTree: React.FC<QxRuntimeTreeProps> = (props) => {
545 onExpand={(keys) => setExpandedKeys(keys)} 525 onExpand={(keys) => setExpandedKeys(keys)}
546 /> 526 />
547 ) : ( 527 ) : (
548 - <Empty  
549 - className={'qx-tree-list__empty'}  
550 - image={Empty.PRESENTED_IMAGE_SIMPLE}  
551 - /> 528 + <Empty className={'qx-tree-list__empty'} image={Empty.PRESENTED_IMAGE_SIMPLE} />
552 )} 529 )}
553 </> 530 </>
554 </div> 531 </div>
@@ -596,8 +573,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => { @@ -596,8 +573,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => {
596 setScroll(SCROLL.start); 573 setScroll(SCROLL.start);
597 } else if (Math.abs(Number(translateNum)) > 0) { 574 } else if (Math.abs(Number(translateNum)) > 0) {
598 if ( 575 if (
599 - Math.abs(Number(translateNum)) ==  
600 - Math.abs(tabsDom?.offsetWidth - tabsDom?.scrollWidth) 576 + Math.abs(Number(translateNum)) == Math.abs(tabsDom?.offsetWidth - tabsDom?.scrollWidth)
601 ) { 577 ) {
602 setScroll(SCROLL.end); 578 setScroll(SCROLL.end);
603 } else { 579 } else {
@@ -614,19 +590,15 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => { @@ -614,19 +590,15 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => {
614 const tabItemWidth = e.currentTarget.clientWidth; 590 const tabItemWidth = e.currentTarget.clientWidth;
615 const tabsDom: any = document?.getElementById('quickSearchTabs'); 591 const tabsDom: any = document?.getElementById('quickSearchTabs');
616 const translate = tabsDom.style?.transform; 592 const translate = tabsDom.style?.transform;
617 - const translateNum = Math.abs(  
618 - Number(translate.split('(').pop().split('p').shift() || 0),  
619 - );  
620 - let widget =  
621 - translateNum + tabsDom.clientWidth - (tabItemLeft + tabItemWidth); 593 + const translateNum = Math.abs(Number(translate.split('(').pop().split('p').shift() || 0));
  594 + let widget = translateNum + tabsDom.clientWidth - (tabItemLeft + tabItemWidth);
622 if (widget > 0) { 595 if (widget > 0) {
623 if (translateNum === 0) { 596 if (translateNum === 0) {
624 tabsDom.style.cssText = 'transform: translate(0px,0px);'; 597 tabsDom.style.cssText = 'transform: translate(0px,0px);';
625 } else { 598 } else {
626 widget = index > 0 ? tabItemLeft + 20 : tabItemLeft; 599 widget = index > 0 ? tabItemLeft + 20 : tabItemLeft;
627 if (translateNum > tabItemLeft) { 600 if (translateNum > tabItemLeft) {
628 - tabsDom.style.cssText =  
629 - 'transform: translate(' + -widget + 'px,0px);'; 601 + tabsDom.style.cssText = 'transform: translate(' + -widget + 'px,0px);';
630 } 602 }
631 } 603 }
632 } else if (widget < 0) { 604 } else if (widget < 0) {
@@ -641,9 +613,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => { @@ -641,9 +613,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => {
641 const scrollPrev = () => { 613 const scrollPrev = () => {
642 const tabsDom: any = document?.getElementById('quickSearchTabs'); 614 const tabsDom: any = document?.getElementById('quickSearchTabs');
643 const translate = tabsDom.style?.transform; 615 const translate = tabsDom.style?.transform;
644 - const translateNum = Math.abs(  
645 - Number(translate.split('(').pop().split('p').shift() || 0),  
646 - ); 616 + const translateNum = Math.abs(Number(translate.split('(').pop().split('p').shift() || 0));
647 let widget = translateNum - tabsDom?.offsetWidth; 617 let widget = translateNum - tabsDom?.offsetWidth;
648 if (widget < 0) { 618 if (widget < 0) {
649 widget = 0; 619 widget = 0;
@@ -657,9 +627,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => { @@ -657,9 +627,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => {
657 const scrollNext = () => { 627 const scrollNext = () => {
658 const tabsDom: any = document?.getElementById('quickSearchTabs'); 628 const tabsDom: any = document?.getElementById('quickSearchTabs');
659 const translate = tabsDom.style?.transform; 629 const translate = tabsDom.style?.transform;
660 - const translateNum = Math.abs(  
661 - Number(translate.split('(').pop().split('p').shift() || 0),  
662 - ); 630 + const translateNum = Math.abs(Number(translate.split('(').pop().split('p').shift() || 0));
663 let widget = translateNum + tabsDom?.offsetWidth; 631 let widget = translateNum + tabsDom?.offsetWidth;
664 if (widget > Math.abs(tabsDom?.offsetWidth - tabsDom?.scrollWidth)) { 632 if (widget > Math.abs(tabsDom?.offsetWidth - tabsDom?.scrollWidth)) {
665 widget = Math.abs(tabsDom?.offsetWidth - tabsDom?.scrollWidth); 633 widget = Math.abs(tabsDom?.offsetWidth - tabsDom?.scrollWidth);
@@ -696,9 +664,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => { @@ -696,9 +664,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => {
696 <Button 664 <Button
697 className={'left-button'} 665 className={'left-button'}
698 type="text" 666 type="text"
699 - icon={  
700 - <QxIcon type={'icon-tag-left-translate'} style={{ fontSize: 10 }} />  
701 - } 667 + icon={<QxIcon type={'icon-tag-left-translate'} style={{ fontSize: 10 }} />}
702 disabled={scroll == SCROLL.start} 668 disabled={scroll == SCROLL.start}
703 onClick={scrollPrev} 669 onClick={scrollPrev}
704 /> 670 />
@@ -734,12 +700,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => { @@ -734,12 +700,7 @@ const QxQuickSearchTabs: React.FC<QxQuickSearchTabsProps> = (props: any) => {
734 <Button 700 <Button
735 className={'right-button'} 701 className={'right-button'}
736 type="text" 702 type="text"
737 - icon={  
738 - <QxIcon  
739 - type={'icon-tag-right-translate'}  
740 - style={{ fontSize: 10 }}  
741 - />  
742 - } 703 + icon={<QxIcon type={'icon-tag-right-translate'} style={{ fontSize: 10 }} />}
743 disabled={scroll == SCROLL.end} 704 disabled={scroll == SCROLL.end}
744 onClick={scrollNext} 705 onClick={scrollNext}
745 /> 706 />
@@ -62,8 +62,11 @@ function loopSchema( @@ -62,8 +62,11 @@ function loopSchema(
62 callbacks?: any, // 关联记录表格展示时,存储操作按钮的回调函数 62 callbacks?: any, // 关联记录表格展示时,存储操作按钮的回调函数
63 _isVirtualListExit?: boolean, 63 _isVirtualListExit?: boolean,
64 isDataSet = false, //代表是否为聚合表,聚合表查询的currentFunCode需要为relFunCode 64 isDataSet = false, //代表是否为聚合表,聚合表查询的currentFunCode需要为relFunCode
  65 + merge_field?: string,
65 ) { 66 ) {
66 - const properties = schema.properties; 67 + const properties = merge_field?.startsWith('merge|')
  68 + ? schema
  69 + : schema.properties;
67 if (!properties) { 70 if (!properties) {
68 return; 71 return;
69 } 72 }
@@ -76,9 +79,15 @@ function loopSchema( @@ -76,9 +79,15 @@ function loopSchema(
76 property.default_init = true; 79 property.default_init = true;
77 } 80 }
78 const { widget } = property; 81 const { widget } = property;
  82 + if (merge_field?.startsWith('merge|')) {
  83 + property.belongRelForm = true;
  84 + property.relformKey = merge_field.split('|')[1];
  85 + property.readOnly = true;
  86 + }
79 87
80 if (typeof property.auth === 'boolean' && property.auth === false) { 88 if (typeof property.auth === 'boolean' && property.auth === false) {
81 property.hidden = true; 89 property.hidden = true;
  90 + property.bind = false;
82 // 仅有一个子元素且子元素被隐藏时,隐藏父元素 91 // 仅有一个子元素且子元素被隐藏时,隐藏父元素
83 if (type === 'view' && Object.keys(properties).length === 1) { 92 if (type === 'view' && Object.keys(properties).length === 1) {
84 schema.hidden = true; 93 schema.hidden = true;
@@ -568,6 +577,18 @@ function loopSchema( @@ -568,6 +577,18 @@ function loopSchema(
568 property.qxProps.currentFunCode = param.referQuery?.funCode; 577 property.qxProps.currentFunCode = param.referQuery?.funCode;
569 property.props.isSub = true; 578 property.props.isSub = true;
570 delete property.items; 579 delete property.items;
  580 + } else if (key.indexOf('_merge_field') > -1) {
  581 + loopSchema(
  582 + property.children,
  583 + param,
  584 + callback,
  585 + undefined,
  586 + type,
  587 + '',
  588 + isVirtualListExit,
  589 + false,
  590 + 'merge|' + property.relformKey,
  591 + );
571 } 592 }
572 593
573 // 处理关联属性 594 // 处理关联属性
@@ -869,6 +890,20 @@ export const handleEditFormSchema = ( @@ -869,6 +890,20 @@ export const handleEditFormSchema = (
869 property.default = _data[key]; 890 property.default = _data[key];
870 property.defaultData = _data[key + '_info_'] || []; 891 property.defaultData = _data[key + '_info_'] || [];
871 } 892 }
  893 + if (property.originWidget === 'subform') {
  894 + Object.keys(property.items.properties || {}).forEach((sub: any) => {
  895 + if (Array.isArray(_data[key])) {
  896 + _data[key].map((item: string) => {
  897 + if (
  898 + item[sub] &&
  899 + property.items.properties[sub].widget === 'relSelector'
  900 + ) {
  901 + property.items.properties[sub].default = item[sub];
  902 + }
  903 + });
  904 + }
  905 + });
  906 + }
872 //TODO 临时对按钮参数值处理 obj 对象 907 //TODO 临时对按钮参数值处理 obj 对象
873 if ( 908 if (
874 !property.belongSubForm && 909 !property.belongSubForm &&
@@ -1863,12 +1898,22 @@ function executeActions( @@ -1863,12 +1898,22 @@ function executeActions(
1863 1898
1864 Object.keys(actionMap).forEach((key) => { 1899 Object.keys(actionMap).forEach((key) => {
1865 if (pathMap[key]) { 1900 if (pathMap[key]) {
1866 - const widget =  
1867 - targetForm.getSchemaByPath(pathMap[key]).originWidget || '';  
1868 - if (widget === 'subform' && actionMap[key].hasOwnProperty('readOnly')) { 1901 + const schema = targetForm.getSchemaByPath(pathMap[key]) || {};
  1902 + if (
  1903 + schema.originWidget === 'subform' &&
  1904 + actionMap[key].hasOwnProperty('readOnly')
  1905 + ) {
1869 // 子表的只读单独处理 1906 // 子表的只读单独处理
1870 actionMap[key].subReadOnly = actionMap[key].readOnly; 1907 actionMap[key].subReadOnly = actionMap[key].readOnly;
1871 delete actionMap[key].readOnly; 1908 delete actionMap[key].readOnly;
  1909 + } else if (
  1910 + schema.originWidget === 'relSelector' &&
  1911 + ['TABLE', 'EDIT_TABLE'].includes(schema.props?.mode) &&
  1912 + actionMap[key].hasOwnProperty('readOnly')
  1913 + ) {
  1914 + // 关联记录的只读单独处理
  1915 + actionMap[key].isReadOnly = actionMap[key].readOnly;
  1916 + delete actionMap[key].readOnly;
1872 } 1917 }
1873 targetForm.setSchemaByPath(pathMap[key], actionMap[key]); 1918 targetForm.setSchemaByPath(pathMap[key], actionMap[key]);
1874 } 1919 }
@@ -2548,7 +2593,7 @@ const getSubFormSummaries = ( @@ -2548,7 +2593,7 @@ const getSubFormSummaries = (
2548 // subTableSumArr = form?.schema?.properties?.[subTableKey]?.qxProps?.summary || []; 2593 // subTableSumArr = form?.schema?.properties?.[subTableKey]?.qxProps?.summary || [];
2549 // } else if (type === 'rel') { 2594 // } else if (type === 'rel') {
2550 subTableSumArr = 2595 subTableSumArr =
2551 - form.getSchemaByPath(pathMap[subTableKey])?.qxProps?.summary || []; 2596 + form?.getSchemaByPath(pathMap[subTableKey])?.qxProps?.summary || [];
2552 // } 2597 // }
2553 let subTableData: any[] = []; 2598 let subTableData: any[] = [];
2554 // 子表数据 2599 // 子表数据
@@ -2557,7 +2602,7 @@ const getSubFormSummaries = ( @@ -2557,7 +2602,7 @@ const getSubFormSummaries = (
2557 } else if (type === 'rel') { 2602 } else if (type === 'rel') {
2558 // subTableData = form?.formData?.[subTableKey + '_info_'] || []; 2603 // subTableData = form?.formData?.[subTableKey + '_info_'] || [];
2559 subTableData = 2604 subTableData =
2560 - form.getSchemaByPath(pathMap[subTableKey])?.dataForFormula || []; 2605 + form?.getSchemaByPath(pathMap[subTableKey])?.dataForFormula || [];
2561 } 2606 }
2562 2607
2563 // 对子表汇总项实时计算,得出结果 2608 // 对子表汇总项实时计算,得出结果
@@ -2583,10 +2628,10 @@ const getSubFormSummaries = ( @@ -2583,10 +2628,10 @@ const getSubFormSummaries = (
2583 if (sts.fx === 'MAX' || sts.fx === 'MIN') { 2628 if (sts.fx === 'MAX' || sts.fx === 'MIN') {
2584 let widget = ''; 2629 let widget = '';
2585 if (type === 'rel') { 2630 if (type === 'rel') {
2586 - widget = form.getSchemaByPath(pathMap?.[subTableKey])?.items 2631 + widget = form?.getSchemaByPath(pathMap?.[subTableKey])?.items
2587 ?.properties?.[sts.relField]?.widget; 2632 ?.properties?.[sts.relField]?.widget;
2588 } else { 2633 } else {
2589 - widget = form.getSchemaByPath(pathMap?.[sts.relField])?.widget; 2634 + widget = form?.getSchemaByPath(pathMap?.[sts.relField])?.widget;
2590 } 2635 }
2591 if (['qxDatetime', 'createdAt', 'updatedAt'].includes(widget)) { 2636 if (['qxDatetime', 'createdAt', 'updatedAt'].includes(widget)) {
2592 fxSum = fxSum.filter((it: any) => it); // 计算日期的最大最小时,过滤掉空值 2637 fxSum = fxSum.filter((it: any) => it); // 计算日期的最大最小时,过滤掉空值
@@ -2687,7 +2732,18 @@ const getSchemaKeysByWidget = (form: any, widget: string) => { @@ -2687,7 +2732,18 @@ const getSchemaKeysByWidget = (form: any, widget: string) => {
2687 return percentItemKeys; 2732 return percentItemKeys;
2688 }; 2733 };
2689 2734
2690 -const getCurVal = (pathMap: any, values: any, key: string) => { 2735 +export const getCurVal = (
  2736 + pathMap: any,
  2737 + values: any,
  2738 + key: string,
  2739 + form?: any,
  2740 +) => {
  2741 + const _arr = key.split('.');
  2742 + if (_arr.length === 3) {
  2743 + // 关联表的汇总
  2744 + const res = getSubFormSummaries(form, _arr[0], '', 'rel', pathMap);
  2745 + return res[key];
  2746 + }
2691 if (!values.hasOwnProperty(key)) { 2747 if (!values.hasOwnProperty(key)) {
2692 return getValue(values, pathMap[key]); 2748 return getValue(values, pathMap[key]);
2693 } else { 2749 } else {
@@ -2723,6 +2779,7 @@ export const dealFormula = ( @@ -2723,6 +2779,7 @@ export const dealFormula = (
2723 pathMap: any, 2779 pathMap: any,
2724 form: any, 2780 form: any,
2725 keyDownCount: number, 2781 keyDownCount: number,
  2782 + formData: any,
2726 ) => { 2783 ) => {
2727 if (flag !== keyDownCount) { 2784 if (flag !== keyDownCount) {
2728 // flag = _.clone(keyDownCount); 2785 // flag = _.clone(keyDownCount);
@@ -2746,7 +2803,7 @@ export const dealFormula = ( @@ -2746,7 +2803,7 @@ export const dealFormula = (
2746 dateFormat, 2803 dateFormat,
2747 } = calculate; 2804 } = calculate;
2748 // 子表数据 2805 // 子表数据
2749 - const allValues = form.getValues(); 2806 + const allValues = formData;
2750 const subTableData: any[] = 2807 const subTableData: any[] =
2751 allValues?.[subForm?.subFormKey] || 2808 allValues?.[subForm?.subFormKey] ||
2752 form.formData?.[subForm?.subFormKey] || 2809 form.formData?.[subForm?.subFormKey] ||
@@ -2898,7 +2955,7 @@ export const dealFormula = ( @@ -2898,7 +2955,7 @@ export const dealFormula = (
2898 } else { 2955 } else {
2899 const _depsVal: any = handleNullType(depsVal, nullType); 2956 const _depsVal: any = handleNullType(depsVal, nullType);
2900 if (_depsVal === 'EMPTY' || _depsVal.includes('EMPTY')) { 2957 if (_depsVal === 'EMPTY' || _depsVal.includes('EMPTY')) {
2901 - return form.setValueByPath(schemaKeyRel, ''); 2958 + return form.setValueByPath(schemaKeyRel, null);
2902 } 2959 }
2903 if (formula) { 2960 if (formula) {
2904 // @ts-ignore 2961 // @ts-ignore
@@ -2910,8 +2967,8 @@ export const dealFormula = ( @@ -2910,8 +2967,8 @@ export const dealFormula = (
2910 } 2967 }
2911 2968
2912 if (typeof formulaRes !== 'object') { 2969 if (typeof formulaRes !== 'object') {
2913 - if (isNaN(formulaRes)) {  
2914 - formulaRes = 0; 2970 + if (isNaN(formulaRes) || formulaRes === Infinity) {
  2971 + formulaRes = null;
2915 } 2972 }
2916 // if (typeof formulaRes === 'number') { 2973 // if (typeof formulaRes === 'number') {
2917 // console.log(formulaRes, precision) 2974 // console.log(formulaRes, precision)
@@ -128,11 +128,30 @@ type ListViewCoreProps = { @@ -128,11 +128,30 @@ type ListViewCoreProps = {
128 initSelectedIds?: string[]; 128 initSelectedIds?: string[];
129 }; 129 };
130 130
131 -const useTableScrollY = (deps: string[]) => { 131 +const getRows = (columns: any[]) => {
  132 + let rows = 1;
  133 + const _columns = columns.filter(item => (item.key || item.dataIndex).indexOf('_merge_field') === 0);
  134 + _columns.forEach(item => {
  135 + if (item.children?.length) {
  136 + if (rows === 1) rows = 2;
  137 + item.children.forEach((it: any) => {
  138 + if ((it.key || it.dataIndex).indexOf('_merge_field') === 0 && it.children?.length) {
  139 + rows = 3;
  140 + }
  141 + })
  142 + }
  143 + })
  144 + return rows
  145 +}
  146 +
  147 +const useTableScrollY = (deps: any[]) => {
  148 + const size = deps?.[0]?.size;
  149 + const itemHeaderHeight = size === 'middle' ? 48 : size === 'default' ? 56 : 40;
  150 + const headerRows = getRows(deps?.[0]?.columns || []);
132 const TABLE_VIEW_LIST = 'qx-view-list'; 151 const TABLE_VIEW_LIST = 'qx-view-list';
133 const PAGINATION_HEIGHT_CLASS_NAME = 'ant-pagination'; 152 const PAGINATION_HEIGHT_CLASS_NAME = 'ant-pagination';
134 const TOOLBAR_NAME = 'qx-view-container__toolbar'; 153 const TOOLBAR_NAME = 'qx-view-container__toolbar';
135 - const tableHeader = 55; 154 + const tableHeader = itemHeaderHeight * headerRows;
136 const paginationDefaultHeight = 32; 155 const paginationDefaultHeight = 32;
137 const paginationDefaultMargin = 32; 156 const paginationDefaultMargin = 32;
138 const tableViewListDefaultHeight = 400; 157 const tableViewListDefaultHeight = 400;
@@ -140,7 +159,7 @@ const useTableScrollY = (deps: string[]) => { @@ -140,7 +159,7 @@ const useTableScrollY = (deps: string[]) => {
140 159
141 const $ = (selectors: string) => document.querySelector<HTMLElement>(selectors); 160 const $ = (selectors: string) => document.querySelector<HTMLElement>(selectors);
142 161
143 - const defaultScrollY = useMemo(() => document.body.clientHeight, []); 162 + const defaultScrollY = useMemo(() => document.body.clientHeight, [tableHeader]);
144 163
145 const [scrollY, setScrollY] = useState<number>(defaultScrollY ?? 200); 164 const [scrollY, setScrollY] = useState<number>(defaultScrollY ?? 200);
146 165
@@ -203,7 +222,7 @@ const useTableScrollY = (deps: string[]) => { @@ -203,7 +222,7 @@ const useTableScrollY = (deps: string[]) => {
203 return () => { 222 return () => {
204 removeObserver(); 223 removeObserver();
205 }; 224 };
206 - }, []); 225 + }, [tableHeader]);
207 226
208 useEffect(() => { 227 useEffect(() => {
209 if (deps) { 228 if (deps) {
@@ -331,6 +350,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({ @@ -331,6 +350,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({
331 const [relationAside, setRelationAside] = useState<any>(); 350 const [relationAside, setRelationAside] = useState<any>();
332 const [relationFun, setRelationFun] = useState<any>(); 351 const [relationFun, setRelationFun] = useState<any>();
333 const [relationApp, setRelationApp] = useState<any>(); 352 const [relationApp, setRelationApp] = useState<any>();
  353 + const [relationView, setRelationView] = useState<any>();
334 const [childFun, setChildFun] = useState<boolean>(false); 354 const [childFun, setChildFun] = useState<boolean>(false);
335 const [relationkeys, setRelationkeys] = useState<any>([]); 355 const [relationkeys, setRelationkeys] = useState<any>([]);
336 const [selectRelModalOpen, setSelectRelModalOpen] = useState(false); 356 const [selectRelModalOpen, setSelectRelModalOpen] = useState(false);
@@ -359,6 +379,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({ @@ -359,6 +379,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({
359 if (info) { 379 if (info) {
360 setRelationFun(info.extract?.code); 380 setRelationFun(info.extract?.code);
361 setRelationApp(info.extract?.appCode); 381 setRelationApp(info.extract?.appCode);
  382 + setRelationView(info.extract?.viewCode);
362 } 383 }
363 if (_flag) { 384 if (_flag) {
364 return; 385 return;
@@ -709,7 +730,12 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({ @@ -709,7 +730,12 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({
709 setLoading(false); 730 setLoading(false);
710 }; 731 };
711 732
712 - const relationView = async (data: any, _appCode: string, _funCode: string, _viewCode: string) => { 733 + const relationSetting = async (
  734 + data: any,
  735 + _appCode: string,
  736 + _funCode: string,
  737 + _viewCode: string,
  738 + ) => {
713 const params = { 739 const params = {
714 viewCode: _viewCode || (query && query.viewCode), 740 viewCode: _viewCode || (query && query.viewCode),
715 viewType: 'RELATION', 741 viewType: 'RELATION',
@@ -884,7 +910,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({ @@ -884,7 +910,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({
884 return; 910 return;
885 } else if (data.hasOwnProperty('relation')) { 911 } else if (data.hasOwnProperty('relation')) {
886 setViewType('RELATION'); 912 setViewType('RELATION');
887 - await relationView(data, appCode, funCode, viewCode || (query && query.viewCode)); 913 + await relationSetting(data, appCode, funCode, viewCode || (query && query.viewCode));
888 return; 914 return;
889 } 915 }
890 setViewType('list'); 916 setViewType('list');
@@ -1961,7 +1987,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({ @@ -1961,7 +1987,7 @@ export const ListViewCore: React.FC<ListViewCoreProps> = ({
1961 {props.mode !== 'selector' ? ( 1987 {props.mode !== 'selector' ? (
1962 <RuntimeFormDrawer 1988 <RuntimeFormDrawer
1963 appCode={childFun ? relationApp : appCode} 1989 appCode={childFun ? relationApp : appCode}
1964 - viewCode={viewCode} 1990 + viewCode={childFun ? relationView : viewCode}
1965 funCode={childFun ? relationFun : funCode} 1991 funCode={childFun ? relationFun : funCode}
1966 dRef={drawerRef} 1992 dRef={drawerRef}
1967 type={currDataItemCtrl.type || 'add'} 1993 type={currDataItemCtrl.type || 'add'}
@@ -2314,6 +2340,7 @@ const PageList: React.FC = () => { @@ -2314,6 +2340,7 @@ const PageList: React.FC = () => {
2314 return msg; 2340 return msg;
2315 } 2341 }
2316 }; 2342 };
  2343 +
2317 return views.length ? ( 2344 return views.length ? (
2318 <div 2345 <div
2319 className="app-view-cont" 2346 className="app-view-cont"
@@ -2391,4 +2418,3 @@ const PageList: React.FC = () => { @@ -2391,4 +2418,3 @@ const PageList: React.FC = () => {
2391 }; 2418 };
2392 2419
2393 export default PageList; 2420 export default PageList;
2394 -  
1 -import { handleWindowOpen } from '@/src/utils'; 1 +import { handleWindowOpen } from '@/utils';
2 import _ from 'lodash'; 2 import _ from 'lodash';
3 3
4 const TARGET_MAP = { 4 const TARGET_MAP = {