@bit-sun/business-component 4.2.0-alpha.6.8 → 4.2.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Business/AddSelectBusiness/index.d.ts +3 -4
- package/dist/components/Business/BsLayouts/Components/AllFunc/drawContent.d.ts +1 -2
- package/dist/components/Business/BsLayouts/Components/ChooseStore/index.d.ts +1 -2
- package/dist/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/index.d.ts +1 -1
- package/dist/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/leftTree.d.ts +1 -1
- package/dist/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/rightTree.d.ts +2 -2
- package/dist/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/DrawContent.d.ts +1 -2
- package/dist/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/customMenuHeader.d.ts +1 -2
- package/dist/components/Business/BsLayouts/Components/CustomerMenu/index.d.ts +1 -1
- package/dist/components/Business/BsLayouts/Components/GlobalHeader/index.d.ts +1 -2
- package/dist/components/Business/BsLayouts/Components/RightContent/LoginModal.d.ts +1 -2
- package/dist/components/Business/BsLayouts/index.d.ts +1 -1
- package/dist/components/Business/BsSulaQueryTable/SearchItemSetting.d.ts +5 -5
- package/dist/components/Business/BsSulaQueryTable/index.d.ts +1 -2
- package/dist/components/Business/BsSulaQueryTable/setting.d.ts +6 -6
- package/dist/components/Business/BsSulaQueryTable/utils.d.ts +14 -15
- package/dist/components/Business/CommodityEntry/index.d.ts +1 -2
- package/dist/components/Business/CommonAlert/index.d.ts +1 -2
- package/dist/components/Business/CommonGuideWrapper/index.d.ts +3 -3
- package/dist/components/Business/DetailPageWrapper/index.d.ts +12 -12
- package/dist/components/Business/HomePageWrapper/index.d.ts +1 -2
- package/dist/components/Business/ItemPropertySelector/index.d.ts +1 -2
- package/dist/components/Business/JsonQueryTable/components/FieldsModifyModal.d.ts +1 -2
- package/dist/components/Business/JsonQueryTable/components/FieldsSettingsTable.d.ts +1 -2
- package/dist/components/Business/JsonQueryTable/components/Formula.d.ts +1 -2
- package/dist/components/Business/JsonQueryTable/components/MaintainOptions.d.ts +1 -2
- package/dist/components/Business/JsonQueryTable/drawer/index.d.ts +1 -2
- package/dist/components/Business/PropertyModal/index.d.ts +1 -2
- package/dist/components/Business/PropertyModal/propertyGroup.d.ts +1 -1
- package/dist/components/Business/SearchSelect/index.d.ts +1 -1
- package/dist/components/Business/StateFlow/index.d.ts +1 -2
- package/dist/components/Business/TreeSearchSelect/index.d.ts +1 -1
- package/dist/components/Business/columnSettingTable/columnSetting.d.ts +6 -6
- package/dist/components/Business/columnSettingTable/components/TableSumComponent.d.ts +1 -2
- package/dist/components/Business/columnSettingTable/index.d.ts +3 -3
- package/dist/components/Business/columnSettingTable/sulaSettingTable.d.ts +3 -3
- package/dist/components/Business/columnSettingTable/utils.d.ts +1 -2
- package/dist/components/Business/moreTreeTable/FixedScrollBar.d.ts +1 -1
- package/dist/components/Common/ParagraphCopier/index.d.ts +1 -1
- package/dist/components/Common/Section/index.d.ts +1 -1
- package/dist/components/Functional/AddSelect/index.d.ts +1 -2
- package/dist/components/Functional/AuthButton/index.d.ts +1 -2
- package/dist/components/Functional/DataImport/index.d.ts +3 -3
- package/dist/components/Functional/DataValidation/index.d.ts +5 -5
- package/dist/components/Functional/ExportFunctions/ExportIcon/index.d.ts +1 -2
- package/dist/components/Functional/QueryMutipleInput/index.d.ts +1 -2
- package/dist/components/Functional/QueryMutipleSelect/index.d.ts +1 -2
- package/dist/components/Functional/SearchSelect/index.d.ts +1 -1
- package/dist/components/Functional/SearchSelect/utils.d.ts +2 -3
- package/dist/components/Functional/TreeSearchSelect/index.d.ts +1 -2
- package/dist/components/Solution/RuleComponent/CustomPlugin/CustomSelector/CustomSelectorModal.d.ts +1 -1
- package/dist/components/Solution/RuleComponent/CustomPlugin/CustomSelector/index.d.ts +1 -2
- package/dist/components/Solution/RuleComponent/Formula.d.ts +1 -2
- package/dist/components/Solution/RuleComponent/InnerSelect.d.ts +1 -2
- package/dist/components/Solution/RuleComponent/RenderCompItem.d.ts +1 -2
- package/dist/components/Solution/RuleSetter/RuleInstance.d.ts +1 -2
- package/dist/components/Solution/RuleSetter/baseRule.d.ts +1 -1
- package/dist/components/Solution/RuleSetter/index.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +1383 -1151
- package/dist/index.js +1383 -1150
- package/dist/plugin/TableColumnSetting/index.d.ts +5 -5
- package/dist/utils/TableUtils.d.ts +18 -19
- package/package.json +1 -1
- package/src/components/Business/BsSulaQueryTable/index.md +57 -4
- package/src/components/Business/BsSulaQueryTable/index.tsx +164 -7
- package/src/components/Business/BsSulaQueryTable/setting.tsx +6 -0
- package/src/components/Business/DetailPageWrapper/index.tsx +81 -1
- package/src/components/Business/DetailPageWrapper/readme.md +89 -0
- package/src/components/Business/SearchSelect/BusinessUtils.tsx +45 -12
- package/src/components/Functional/AddSelect/index.tsx +92 -0
- package/src/components/Functional/DataValidation/index.tsx +22 -3
- package/src/components/Functional/SearchSelect/index.tsx +5 -2
- package/src/components/Solution/RuleComponent/RenderCompItem.tsx +9 -1
- package/src/components/Solution/RuleComponent/index.js +1 -0
- package/src/components/Solution/RuleComponent/ruleFiled.js +25 -1
- package/src/index.ts +4 -0
|
@@ -38,14 +38,14 @@ declare class TableColumnSetting extends React.Component<TableColumnSettingProps
|
|
|
38
38
|
} | {
|
|
39
39
|
title: string;
|
|
40
40
|
dataIndex: string;
|
|
41
|
-
render: (text: any, record: any) =>
|
|
41
|
+
render: (text: any, record: any) => JSX.Element;
|
|
42
42
|
className?: undefined;
|
|
43
43
|
width?: undefined;
|
|
44
44
|
} | {
|
|
45
45
|
title: string;
|
|
46
46
|
dataIndex: string;
|
|
47
47
|
className: string;
|
|
48
|
-
render: () =>
|
|
48
|
+
render: () => JSX.Element;
|
|
49
49
|
width?: undefined;
|
|
50
50
|
})[];
|
|
51
51
|
showModal: () => void;
|
|
@@ -53,13 +53,13 @@ declare class TableColumnSetting extends React.Component<TableColumnSettingProps
|
|
|
53
53
|
handleCancel: (e: React.MouseEvent<HTMLElement>) => void;
|
|
54
54
|
handleTableHeadHidden: (title: string) => void;
|
|
55
55
|
onSortEnd: ({ oldIndex, newIndex }: any) => void;
|
|
56
|
-
DraggableContainer: (props: any) =>
|
|
57
|
-
DraggableBodyRow: ({ className, style, ...restProps }: any) =>
|
|
56
|
+
DraggableContainer: (props: any) => JSX.Element;
|
|
57
|
+
DraggableBodyRow: ({ className, style, ...restProps }: any) => JSX.Element;
|
|
58
58
|
onChange: (e: any, title: any) => void;
|
|
59
59
|
handleReset: () => void;
|
|
60
60
|
handleResetSetting: () => Promise<unknown>;
|
|
61
61
|
onSearch: (e: any) => void;
|
|
62
62
|
onSearchSort: (e: any) => void;
|
|
63
|
-
render():
|
|
63
|
+
render(): JSX.Element;
|
|
64
64
|
}
|
|
65
65
|
export default TableColumnSetting;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import moment from 'moment';
|
|
3
2
|
type mediaListType = {
|
|
4
3
|
type: number;
|
|
@@ -49,24 +48,24 @@ declare const updateGuanDate: (requestParams: any, dateKeyParams?: any) => {
|
|
|
49
48
|
};
|
|
50
49
|
submit: any;
|
|
51
50
|
};
|
|
52
|
-
declare const textIcon: (type: string | number, text?: string) =>
|
|
53
|
-
declare const handleTextDoubleOrId: (textOne: string | undefined, textTwo: string | undefined) =>
|
|
54
|
-
declare const handleTextDouble: (textOne: string | undefined, textTwo: string | undefined) =>
|
|
55
|
-
declare const handleTextOverflow: (text: string | undefined, width?: number) =>
|
|
56
|
-
declare const handleTextLineFeed: (text: string | undefined, width?: number) =>
|
|
57
|
-
declare const handleTextTooltip: (text: any) =>
|
|
58
|
-
declare const handleTextBreakSpaces: (text: any) =>
|
|
59
|
-
declare const handleStatusBadge: (text: any, color: any) =>
|
|
60
|
-
declare const HandleTotalCount: (totalParams: any) =>
|
|
51
|
+
declare const textIcon: (type: string | number, text?: string) => JSX.Element | undefined;
|
|
52
|
+
declare const handleTextDoubleOrId: (textOne: string | undefined, textTwo: string | undefined) => JSX.Element;
|
|
53
|
+
declare const handleTextDouble: (textOne: string | undefined, textTwo: string | undefined) => JSX.Element;
|
|
54
|
+
declare const handleTextOverflow: (text: string | undefined, width?: number) => JSX.Element;
|
|
55
|
+
declare const handleTextLineFeed: (text: string | undefined, width?: number) => JSX.Element;
|
|
56
|
+
declare const handleTextTooltip: (text: any) => JSX.Element;
|
|
57
|
+
declare const handleTextBreakSpaces: (text: any) => JSX.Element;
|
|
58
|
+
declare const handleStatusBadge: (text: any, color: any) => JSX.Element;
|
|
59
|
+
declare const HandleTotalCount: (totalParams: any) => JSX.Element;
|
|
61
60
|
declare const handleCommonTimeRender: (text: any, format?: any) => any;
|
|
62
|
-
declare const handleTooltip: (text: any, timeTrue?: boolean) =>
|
|
63
|
-
declare const handleTooltipHours: (text: any, timeTrue?: boolean) =>
|
|
61
|
+
declare const handleTooltip: (text: any, timeTrue?: boolean) => JSX.Element;
|
|
62
|
+
declare const handleTooltipHours: (text: any, timeTrue?: boolean) => JSX.Element;
|
|
64
63
|
type tableColumnsImageType = {
|
|
65
64
|
width?: number | string;
|
|
66
65
|
height?: number | string;
|
|
67
66
|
[key: string]: any;
|
|
68
67
|
};
|
|
69
|
-
declare const tableColumnsImage: (url?: string, paramsObj?: tableColumnsImageType) =>
|
|
68
|
+
declare const tableColumnsImage: (url?: string, paramsObj?: tableColumnsImageType) => JSX.Element;
|
|
70
69
|
interface ColumnsEditInterfave {
|
|
71
70
|
text?: string;
|
|
72
71
|
record?: any;
|
|
@@ -82,7 +81,7 @@ interface ColumnsEditInterfave {
|
|
|
82
81
|
};
|
|
83
82
|
[key: string]: any;
|
|
84
83
|
}
|
|
85
|
-
declare const ColumnsEdit: (props: ColumnsEditInterfave) =>
|
|
84
|
+
declare const ColumnsEdit: (props: ColumnsEditInterfave) => JSX.Element;
|
|
86
85
|
type UserColumnsType = {
|
|
87
86
|
name: string;
|
|
88
87
|
department?: string;
|
|
@@ -90,13 +89,13 @@ type UserColumnsType = {
|
|
|
90
89
|
company?: string;
|
|
91
90
|
avatar?: string;
|
|
92
91
|
};
|
|
93
|
-
declare const userColumns: (props: UserColumnsType) =>
|
|
94
|
-
declare const userInfoCard: (props: any) =>
|
|
92
|
+
declare const userColumns: (props: UserColumnsType) => JSX.Element;
|
|
93
|
+
declare const userInfoCard: (props: any) => JSX.Element;
|
|
95
94
|
declare const getItemDefaultWidth: (item: any) => number;
|
|
96
|
-
declare const sulaTableRenderTooltip: ({ text }: any) =>
|
|
95
|
+
declare const sulaTableRenderTooltip: ({ text }: any) => JSX.Element;
|
|
97
96
|
declare const renderNumberText: ({ text }: any) => any;
|
|
98
97
|
declare const renderFixed2: (text: any) => any;
|
|
99
|
-
declare const handleTextWarpCustom: (text: any, style?: {}) =>
|
|
98
|
+
declare const handleTextWarpCustom: (text: any, style?: {}) => JSX.Element;
|
|
100
99
|
declare const calculateValidPeriod: (start: any, end: any) => string;
|
|
101
|
-
declare const handleTextWarp: (text: any) =>
|
|
100
|
+
declare const handleTextWarp: (text: any) => JSX.Element;
|
|
102
101
|
export { getSkuImg, updateGuanDate, textIcon, handleTextDoubleOrId, handleTextDouble, handleTextOverflow, handleTextLineFeed, handleTextTooltip, handleTextBreakSpaces, handleStatusBadge, HandleTotalCount, handleTooltip, handleCommonTimeRender, handleTooltipHours, tableColumnsImage, ColumnsEdit, userColumns, userInfoCard, getItemDefaultWidth, renderNumberText, sulaTableRenderTooltip, renderFixed2, handleTextWarpCustom, handleTextWarp, calculateValidPeriod };
|
package/package.json
CHANGED
|
@@ -16,11 +16,32 @@ order: 1
|
|
|
16
16
|
### BsSulaQueryTable
|
|
17
17
|
|
|
18
18
|
```tsx
|
|
19
|
-
import React, { useState } from 'react';
|
|
20
|
-
import { Tabs } from 'antd';
|
|
19
|
+
import React, { useState, useEffect } from 'react';
|
|
20
|
+
import { Tabs, Button } from 'antd';
|
|
21
21
|
import { BsSulaQueryTable } from '../../../index.ts';
|
|
22
22
|
|
|
23
23
|
export default () => {
|
|
24
|
+
const [rows, setRows] = useState([]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
window.__POWERED_BY_WUJIE__ = true;
|
|
28
|
+
const flowConfig = [
|
|
29
|
+
{
|
|
30
|
+
tradeType: 180,
|
|
31
|
+
controlButtons: ['DRP_Sale_Order_edit'],
|
|
32
|
+
config: [
|
|
33
|
+
{ fromStatus: 1, buttons: ['DRP_Sale_Order_edit'] },
|
|
34
|
+
{ fromStatus: 25, buttons: [] },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
localStorage.setItem('BUSINESS_FLOW_BUTTONS', JSON.stringify(flowConfig));
|
|
39
|
+
const authCodes = [
|
|
40
|
+
'User_ApplicationList_add',
|
|
41
|
+
'DRP_Sale_Order_edit',
|
|
42
|
+
];
|
|
43
|
+
localStorage.setItem('menuAuth_mainProject', JSON.stringify(authCodes));
|
|
44
|
+
}, []);
|
|
24
45
|
const config = {
|
|
25
46
|
needPageHeader: false,
|
|
26
47
|
remoteDataSource: {
|
|
@@ -38,7 +59,8 @@ export default () => {
|
|
|
38
59
|
return {
|
|
39
60
|
...item,
|
|
40
61
|
id: `${index}`,
|
|
41
|
-
orderStatus: index ===
|
|
62
|
+
orderStatus: index % 2 === 0 ? 1 : 25,
|
|
63
|
+
saleInfo: { tradeStatus: index % 2 === 0 ? 1 : 25 },
|
|
42
64
|
name: `${item.name.first} ${item.name.last}`,
|
|
43
65
|
};
|
|
44
66
|
}),
|
|
@@ -73,6 +95,14 @@ export default () => {
|
|
|
73
95
|
},
|
|
74
96
|
action: ['refreshTable'],
|
|
75
97
|
},
|
|
98
|
+
{
|
|
99
|
+
type: 'button',
|
|
100
|
+
code: 'User_ApplicationList_delete',
|
|
101
|
+
props: {
|
|
102
|
+
children: '删除',
|
|
103
|
+
},
|
|
104
|
+
action: ['refreshTable'],
|
|
105
|
+
},
|
|
76
106
|
],
|
|
77
107
|
fields: [
|
|
78
108
|
{
|
|
@@ -191,6 +221,28 @@ export default () => {
|
|
|
191
221
|
key: 'email3',
|
|
192
222
|
title: '邮箱3',
|
|
193
223
|
},
|
|
224
|
+
{
|
|
225
|
+
key: 'operate',
|
|
226
|
+
title: '操作',
|
|
227
|
+
isPermissionColumn: true,
|
|
228
|
+
fixed: 'right',
|
|
229
|
+
render: [
|
|
230
|
+
{
|
|
231
|
+
type: 'link',
|
|
232
|
+
props: {
|
|
233
|
+
children: '编辑',
|
|
234
|
+
type: 'primary',
|
|
235
|
+
},
|
|
236
|
+
visible: '#{record.saleInfo.tradeStatus == 1}',
|
|
237
|
+
code: 'DRP_Sale_Order_edit',
|
|
238
|
+
action: {
|
|
239
|
+
type: 'route',
|
|
240
|
+
path: '/sales-management/sales-order/edit/#{record.id}',
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
],
|
|
245
|
+
},
|
|
194
246
|
],
|
|
195
247
|
rowSelection: {
|
|
196
248
|
onChange: (rowKey: any, rows: any) => {
|
|
@@ -199,6 +251,8 @@ export default () => {
|
|
|
199
251
|
},
|
|
200
252
|
},
|
|
201
253
|
rowKey: 'id',
|
|
254
|
+
tradeType: 180,
|
|
255
|
+
statusFieldPath: 'saleInfo.tradeStatus',
|
|
202
256
|
tableProps: {
|
|
203
257
|
initialPaging: {
|
|
204
258
|
pagination: {
|
|
@@ -216,4 +270,3 @@ export default () => {
|
|
|
216
270
|
);
|
|
217
271
|
};
|
|
218
272
|
```
|
|
219
|
-
|
|
@@ -607,10 +607,24 @@ export default (props: any) => {
|
|
|
607
607
|
...value?.tableProps || {}
|
|
608
608
|
};
|
|
609
609
|
|
|
610
|
-
// @ts-ignore
|
|
611
610
|
if (tableProps?.initialPaging?.pagination) {
|
|
612
|
-
// @ts-ignore
|
|
613
611
|
tableProps.initialPaging.pagination.showSizeChanger = true;
|
|
612
|
+
|
|
613
|
+
// 分页大小改变时,更新本地存储
|
|
614
|
+
const onShowSizeChange = (current: number, size: number) => {
|
|
615
|
+
let allPaginationData = JSON.parse(localStorage.getItem('paginationData') || "{}");
|
|
616
|
+
allPaginationData[bsTableCode] = size;
|
|
617
|
+
localStorage.setItem('paginationData', JSON.stringify(allPaginationData || {}));
|
|
618
|
+
};
|
|
619
|
+
tableProps.initialPaging.pagination.onShowSizeChange = onShowSizeChange;
|
|
620
|
+
|
|
621
|
+
// 从本地存储中获取分页大小
|
|
622
|
+
const pageSize = JSON.parse(localStorage.getItem('paginationData') || "{}")[bsTableCode];
|
|
623
|
+
if (pageSize) {
|
|
624
|
+
tableProps.initialPaging.pagination.pageSize = pageSize;
|
|
625
|
+
tableProps.pageSize = pageSize;
|
|
626
|
+
tableProps.defaultPageSize = pageSize;
|
|
627
|
+
}
|
|
614
628
|
}
|
|
615
629
|
return tableProps;
|
|
616
630
|
};
|
|
@@ -735,9 +749,103 @@ export default (props: any) => {
|
|
|
735
749
|
if (value.rowSelection) {
|
|
736
750
|
value.rowSelection.columnWidth = 50;
|
|
737
751
|
}
|
|
752
|
+
if (typeof props.tradeType !== 'number') {
|
|
753
|
+
return {
|
|
754
|
+
...value,
|
|
755
|
+
actionsRender,
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
try {
|
|
759
|
+
const raw = JSON.parse(localStorage.getItem('BUSINESS_FLOW_BUTTONS') || '[]');
|
|
760
|
+
const entry = raw.find((i: any) => i?.tradeType === props.tradeType);
|
|
761
|
+
if (entry) {
|
|
762
|
+
const ctrlSet = new Set((entry?.controlButtons || []).filter(Boolean));
|
|
763
|
+
const allowedTopSet: any = new Set();
|
|
764
|
+
(entry?.config || []).forEach((c: any) => {
|
|
765
|
+
(c?.buttons || []).filter(Boolean).forEach((b: any) => {
|
|
766
|
+
if (!ctrlSet.size || ctrlSet.has(b)) allowedTopSet.add(b);
|
|
767
|
+
});
|
|
768
|
+
});
|
|
769
|
+
console.debug('[FlowCtrl:top]', { ctrlSize: ctrlSet.size, allowedTopSize: allowedTopSet.size });
|
|
770
|
+
actionsRender = actionsRender.filter((ui: any) => {
|
|
771
|
+
const code = ui?.code;
|
|
772
|
+
if (!code) return true;
|
|
773
|
+
if (ctrlSet.size && !ctrlSet.has(code)) return true; // 非流程控制按钮不处理
|
|
774
|
+
const keep = allowedTopSet.has(code);
|
|
775
|
+
if (code) console.debug('[FlowCtrl:top-element]', { code, keep });
|
|
776
|
+
return keep;
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
} catch (e) {}
|
|
780
|
+
let remoteDataSource = value?.remoteDataSource;
|
|
781
|
+
if (remoteDataSource) {
|
|
782
|
+
let ctrlSet: any = new Set();
|
|
783
|
+
let btnStatusMap: any = new Map();
|
|
784
|
+
try {
|
|
785
|
+
const raw = JSON.parse(localStorage.getItem('BUSINESS_FLOW_BUTTONS') || '[]');
|
|
786
|
+
const entry = raw.find((i: any) => i?.tradeType === props.tradeType);
|
|
787
|
+
if (entry) {
|
|
788
|
+
ctrlSet = new Set((entry?.controlButtons || []).filter(Boolean));
|
|
789
|
+
(entry?.config || []).forEach((c: any) => {
|
|
790
|
+
(c?.buttons || []).filter(Boolean).forEach((b: any) => {
|
|
791
|
+
if (!ctrlSet.size || ctrlSet.has(b)) {
|
|
792
|
+
const set = btnStatusMap.get(b) || new Set();
|
|
793
|
+
set.add(c?.fromStatus);
|
|
794
|
+
btnStatusMap.set(b, set);
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
} catch (e) {}
|
|
800
|
+
const getByPath = (obj: any, path: string) => {
|
|
801
|
+
if (!obj || !path) return undefined;
|
|
802
|
+
const parts = path.split('.');
|
|
803
|
+
let cur = obj;
|
|
804
|
+
for (let i = 0; i < parts.length; i++) {
|
|
805
|
+
cur = cur?.[parts[i]];
|
|
806
|
+
if (cur === undefined) return undefined;
|
|
807
|
+
}
|
|
808
|
+
return cur;
|
|
809
|
+
};
|
|
810
|
+
const statusPath = props?.statusFieldPath;
|
|
811
|
+
const augment = (result: any) => {
|
|
812
|
+
if (!btnStatusMap || btnStatusMap.size === 0) return result;
|
|
813
|
+
if (result && Array.isArray(result.list)) {
|
|
814
|
+
result.list = result.list.map((rec: any) => {
|
|
815
|
+
const status = statusPath ? getByPath(rec, statusPath) : (rec?.status ?? rec?.orderStatus ?? rec?.flowStatus ?? rec?.tradeStatus ?? rec?.currentStatus);
|
|
816
|
+
const map: any = {};
|
|
817
|
+
btnStatusMap.forEach((set: any, code: string) => {
|
|
818
|
+
map[code] = set.has(status) ? true : undefined;
|
|
819
|
+
});
|
|
820
|
+
return { ...rec, __flowAllowedMap: map };
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
return result;
|
|
824
|
+
};
|
|
825
|
+
if (Array.isArray(remoteDataSource.converter)) {
|
|
826
|
+
const stages = remoteDataSource.converter;
|
|
827
|
+
const pipeline = (args: any) => {
|
|
828
|
+
let res = args;
|
|
829
|
+
for (let i = 0; i < stages.length; i++) {
|
|
830
|
+
res = stages[i](res);
|
|
831
|
+
}
|
|
832
|
+
res = augment(res);
|
|
833
|
+
return res;
|
|
834
|
+
};
|
|
835
|
+
remoteDataSource = { ...remoteDataSource, converter: pipeline };
|
|
836
|
+
} else if (typeof remoteDataSource.converter === 'function') {
|
|
837
|
+
const orig = remoteDataSource.converter;
|
|
838
|
+
const wrap = (args: any) => {
|
|
839
|
+
const res = orig(args);
|
|
840
|
+
return augment(res);
|
|
841
|
+
};
|
|
842
|
+
remoteDataSource = { ...remoteDataSource, converter: wrap };
|
|
843
|
+
}
|
|
844
|
+
}
|
|
738
845
|
return {
|
|
739
846
|
...value,
|
|
740
847
|
actionsRender,
|
|
848
|
+
remoteDataSource,
|
|
741
849
|
};
|
|
742
850
|
};
|
|
743
851
|
|
|
@@ -773,11 +881,59 @@ export default (props: any) => {
|
|
|
773
881
|
// 优化一下 减少复杂度
|
|
774
882
|
const titleMap = toMapByKey(value.columns, 'title');
|
|
775
883
|
// 加上排序
|
|
776
|
-
const
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
884
|
+
const hasFlowEntry = (typeof props.tradeType === 'number') && (() => {
|
|
885
|
+
try {
|
|
886
|
+
const raw = JSON.parse(localStorage.getItem('BUSINESS_FLOW_BUTTONS') || '[]');
|
|
887
|
+
return !!raw.find((i: any) => i?.tradeType === props.tradeType);
|
|
888
|
+
} catch (e) { return false; }
|
|
889
|
+
})();
|
|
890
|
+
const hasControlRange = (typeof props.tradeType === 'number') && (() => {
|
|
891
|
+
try {
|
|
892
|
+
const raw = JSON.parse(localStorage.getItem('BUSINESS_FLOW_BUTTONS') || '[]');
|
|
893
|
+
const entry = raw.find((i: any) => i?.tradeType === props.tradeType);
|
|
894
|
+
if (!entry) return false;
|
|
895
|
+
const ctrlSet = new Set((entry?.controlButtons || []).filter(Boolean));
|
|
896
|
+
return ctrlSet.size > 0;
|
|
897
|
+
} catch (e) { return false; }
|
|
898
|
+
})();
|
|
899
|
+
const toExpr = (v: any) => {
|
|
900
|
+
if (typeof v === 'string') return v.replace(/^#\{|\}$/g, '');
|
|
901
|
+
if (v === undefined) return 'true';
|
|
902
|
+
return v ? 'true' : 'false';
|
|
903
|
+
};
|
|
904
|
+
// 读取当前 tradeType 的控制范围,用于只在控制按钮上追加流程表达式
|
|
905
|
+
let ctrlSet: any = new Set();
|
|
906
|
+
if (hasFlowEntry) {
|
|
907
|
+
try {
|
|
908
|
+
const raw = JSON.parse(localStorage.getItem('BUSINESS_FLOW_BUTTONS') || '[]');
|
|
909
|
+
const entry = raw.find((i: any) => i?.tradeType === props.tradeType);
|
|
910
|
+
if (entry) ctrlSet = new Set((entry?.controlButtons || []).filter(Boolean));
|
|
911
|
+
} catch (e) {}
|
|
912
|
+
}
|
|
913
|
+
const augmentPermissionRender = (arr: any[], set: Set<string>) => {
|
|
914
|
+
return arr.map((el: any) => {
|
|
915
|
+
const code = el?.code;
|
|
916
|
+
if (!code) return el;
|
|
917
|
+
// 非控制范围按钮不追加流程控制,保持原 visible
|
|
918
|
+
if (!set || set.size === 0 || !set.has(code)) return el;
|
|
919
|
+
const base = toExpr(el.visible);
|
|
920
|
+
const flow = `record.__flowAllowedMap['${code}'] == true`;
|
|
921
|
+
return { ...el, visible: `#{(${base}) && (${flow})}` };
|
|
922
|
+
});
|
|
923
|
+
};
|
|
924
|
+
const cols = showColumn.map((i) => {
|
|
925
|
+
const orig = titleMap[renderToString(i.title)] || {};
|
|
926
|
+
const origRender = orig.render;
|
|
927
|
+
const isPerm = orig.isPermissionColumn;
|
|
928
|
+
const newRender = (Array.isArray(origRender) && isPerm && hasFlowEntry && hasControlRange)
|
|
929
|
+
? augmentPermissionRender(origRender, ctrlSet)
|
|
930
|
+
: origRender;
|
|
931
|
+
return {
|
|
932
|
+
...i,
|
|
933
|
+
isPermissionColumn: isPerm,
|
|
934
|
+
render: newRender,
|
|
935
|
+
};
|
|
936
|
+
});
|
|
781
937
|
cols.forEach((i) => handleBssulaColumnsSpecialParams(i));
|
|
782
938
|
return cols;
|
|
783
939
|
};
|
|
@@ -967,6 +1123,7 @@ export default (props: any) => {
|
|
|
967
1123
|
{/* 列设置弹出框表格 */}
|
|
968
1124
|
<SortableTable
|
|
969
1125
|
ref={sortTableRef}
|
|
1126
|
+
disableColumnFixed={props.tableProps?.isVirtualTable}
|
|
970
1127
|
setShowColumns={setResizeShowColumns}
|
|
971
1128
|
showColumn={showColumn}
|
|
972
1129
|
setInitialTableInfo={setInitialTableInfo}
|
|
@@ -288,6 +288,9 @@ class SortableTable extends React.Component {
|
|
|
288
288
|
title: '列首',
|
|
289
289
|
dataIndex: 'fixedLeft',
|
|
290
290
|
render: (text, record) => {
|
|
291
|
+
if(this.props.disableColumnFixed) {
|
|
292
|
+
return null
|
|
293
|
+
}
|
|
291
294
|
return (
|
|
292
295
|
<span
|
|
293
296
|
onClick={() => {
|
|
@@ -375,6 +378,9 @@ class SortableTable extends React.Component {
|
|
|
375
378
|
title: '列尾',
|
|
376
379
|
dataIndex: 'fixedRight',
|
|
377
380
|
render: (text, record) => {
|
|
381
|
+
if(this.props.disableColumnFixed) {
|
|
382
|
+
return null
|
|
383
|
+
}
|
|
378
384
|
return (
|
|
379
385
|
<span
|
|
380
386
|
onClick={() => {
|
|
@@ -78,6 +78,8 @@ const DetailWrapper = React.memo(
|
|
|
78
78
|
pathToRegexp,
|
|
79
79
|
backHistoryPath,
|
|
80
80
|
onBack,
|
|
81
|
+
tradeType,
|
|
82
|
+
fromStatus,
|
|
81
83
|
}: any) => {
|
|
82
84
|
const [isFullScreen, setIsFnllScreen]: any = useState(false);
|
|
83
85
|
const [breadcrumbArr, setBreadCrumbArr]: any = useState([]);
|
|
@@ -195,6 +197,34 @@ const DetailWrapper = React.memo(
|
|
|
195
197
|
}
|
|
196
198
|
};
|
|
197
199
|
|
|
200
|
+
const getFlowButtons = () => {
|
|
201
|
+
try {
|
|
202
|
+
return JSON.parse(localStorage.getItem('BUSINESS_FLOW_BUTTONS') || '[]');
|
|
203
|
+
} catch (e) { return []; }
|
|
204
|
+
};
|
|
205
|
+
const matchByRule = (ui: any, flow: any, ctx: any) => {
|
|
206
|
+
if (flow.tradeType !== ctx.tradeType) return false;
|
|
207
|
+
if (typeof ctx.status === 'number' && flow.fromStatus !== ctx.status) return false;
|
|
208
|
+
const uiCode = ui.code || ui.buttonCode || ui?.props?.code || ui?.props?.buttonCode;
|
|
209
|
+
if (!uiCode || !flow.buttonCode) return false;
|
|
210
|
+
return uiCode === flow.buttonCode;
|
|
211
|
+
};
|
|
212
|
+
const filterByFlowRules = (list: Array<any>, ctx: any) => {
|
|
213
|
+
const flowList = getFlowButtons();
|
|
214
|
+
if (!flowList?.length || typeof ctx.tradeType !== 'number') return list;
|
|
215
|
+
const entry = flowList.find((i: any) => i?.tradeType === ctx.tradeType);
|
|
216
|
+
if (!entry) return list;
|
|
217
|
+
const ctrlSet = new Set((entry?.controlButtons || []).filter(Boolean));
|
|
218
|
+
const statButtons = (entry?.config || []).find((c: any) => c?.fromStatus === ctx.status)?.buttons || [];
|
|
219
|
+
const allowedSet = new Set((statButtons || []).filter(Boolean).filter((b: any) => ctrlSet.size ? ctrlSet.has(b) : true));
|
|
220
|
+
return list.filter((ui) => {
|
|
221
|
+
const uiCode = ui.code || ui.buttonCode || ui?.props?.code || ui?.props?.buttonCode;
|
|
222
|
+
if (!uiCode) return true;
|
|
223
|
+
if (ctrlSet.size && !ctrlSet.has(uiCode)) return true; // 非流程控制按钮不处理
|
|
224
|
+
return allowedSet.has(uiCode);
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
|
|
198
228
|
const renderPageActionList = (actionLists: Array<actionItem>) => {
|
|
199
229
|
const authButton = localStorage.getItem(getMenuAuthDataKey())
|
|
200
230
|
? JSON.parse(localStorage.getItem(getMenuAuthDataKey()) as string)
|
|
@@ -202,9 +232,13 @@ const DetailWrapper = React.memo(
|
|
|
202
232
|
let visibleActions = actionLists.filter(
|
|
203
233
|
(action) =>
|
|
204
234
|
((action.visible && action.visible !== 'false') || judgeIsEmpty(action.visible)) &&
|
|
205
|
-
(!shouldUseAuth() || (judgeIsEmpty(action.code) || authButton.
|
|
235
|
+
(!shouldUseAuth() || (judgeIsEmpty(action.code) || authButton.some((item: any) => item === action.code))),
|
|
206
236
|
);
|
|
207
237
|
|
|
238
|
+
if (typeof tradeType === 'number') {
|
|
239
|
+
visibleActions = filterByFlowRules(visibleActions, { tradeType, status: fromStatus });
|
|
240
|
+
}
|
|
241
|
+
|
|
208
242
|
const renderButton = (item: actionItem, type?: any) => {
|
|
209
243
|
return (
|
|
210
244
|
<Button
|
|
@@ -348,3 +382,49 @@ const DetailWrapper = React.memo(
|
|
|
348
382
|
return true;
|
|
349
383
|
},
|
|
350
384
|
);
|
|
385
|
+
|
|
386
|
+
export const processDetailButtonsVisible = (buttons: any[], params: any) => {
|
|
387
|
+
const { tradeType, fromStatus } = params || {};
|
|
388
|
+
const getFlowButtons = () => {
|
|
389
|
+
try {
|
|
390
|
+
return JSON.parse(localStorage.getItem('BUSINESS_FLOW_BUTTONS') || '[]');
|
|
391
|
+
} catch (e) { return []; }
|
|
392
|
+
};
|
|
393
|
+
const evalVisible = (v: any, ctx: any) => {
|
|
394
|
+
if (typeof v === 'string') {
|
|
395
|
+
const expr = v.replace(/^#\{|\}$/g, '');
|
|
396
|
+
try {
|
|
397
|
+
const keys = Object.keys(ctx || {});
|
|
398
|
+
const vals = keys.map((k) => ctx[k]);
|
|
399
|
+
// eslint-disable-next-line no-new-func
|
|
400
|
+
return Function(...keys, `return (${expr});`)(...vals);
|
|
401
|
+
} catch (e) { return true; }
|
|
402
|
+
}
|
|
403
|
+
if (v === undefined) return true;
|
|
404
|
+
return !!v;
|
|
405
|
+
};
|
|
406
|
+
let ctrlSet: any = new Set();
|
|
407
|
+
let allowedSet: any = new Set();
|
|
408
|
+
if (typeof tradeType === 'number') {
|
|
409
|
+
const flowList = getFlowButtons();
|
|
410
|
+
const entry = flowList.find((i: any) => i?.tradeType === tradeType);
|
|
411
|
+
if (entry) {
|
|
412
|
+
ctrlSet = new Set((entry?.controlButtons || []).filter(Boolean));
|
|
413
|
+
const statButtons = (entry?.config || []).find((c: any) => c?.fromStatus === fromStatus)?.buttons || [];
|
|
414
|
+
allowedSet = new Set((statButtons || []).filter(Boolean).filter((b: any) => ctrlSet.size ? ctrlSet.has(b) : true));
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
const processed = (buttons || []).map((btn: any) => {
|
|
418
|
+
const visBase = evalVisible(btn?.visible, params);
|
|
419
|
+
let vis = visBase;
|
|
420
|
+
if (typeof tradeType === 'number' && ctrlSet && allowedSet && btn?.code) {
|
|
421
|
+
if (ctrlSet.size === 0 || !ctrlSet.has(btn.code)) {
|
|
422
|
+
vis = visBase;
|
|
423
|
+
} else {
|
|
424
|
+
vis = visBase && allowedSet.has(btn.code);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return { ...btn, visible: vis };
|
|
428
|
+
});
|
|
429
|
+
return processed;
|
|
430
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# DetailPageWrapper 按钮过滤测试
|
|
2
|
+
|
|
3
|
+
演示目标:验证详情页在仅传入 `tradeType` 与 `fromStatus` 时,按钮按本地基础数据源与资源 `code` 精确匹配过滤、并叠加权限过滤是否生效。
|
|
4
|
+
|
|
5
|
+
## 使用步骤
|
|
6
|
+
|
|
7
|
+
1. 初始化本地数据源与权限
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import React, { useEffect } from 'react';
|
|
11
|
+
import DetailPageWrapper from './index.tsx';
|
|
12
|
+
|
|
13
|
+
export default () => {
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
// 开启权限过滤演示
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
window.__POWERED_BY_WUJIE__ = true;
|
|
18
|
+
|
|
19
|
+
// 流程基础数据源(新结构示例)
|
|
20
|
+
const flowConfig = [
|
|
21
|
+
{
|
|
22
|
+
tradeType: 180,
|
|
23
|
+
controlButtons: ['Detail_Submit','Detail_Audit','Detail_ReAudit'],
|
|
24
|
+
config: [
|
|
25
|
+
{ fromStatus: 1, buttons: ['Detail_Submit'] },
|
|
26
|
+
{ fromStatus: 25, buttons: ['Detail_Audit'] },
|
|
27
|
+
{ fromStatus: 26, buttons: ['Detail_ReAudit'] },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
localStorage.setItem('BUSINESS_FLOW_BUTTONS', JSON.stringify(flowConfig));
|
|
32
|
+
|
|
33
|
+
// 菜单按钮授权(仅示例)
|
|
34
|
+
const authCodes = ['Detail_Submit', 'Detail_Audit', 'Detail_ReAudit'];
|
|
35
|
+
localStorage.setItem('menuAuth_mainProject', JSON.stringify(authCodes));
|
|
36
|
+
}, []);
|
|
37
|
+
|
|
38
|
+
const actionList = [
|
|
39
|
+
{
|
|
40
|
+
name: '提交',
|
|
41
|
+
code: 'Detail_Submit',
|
|
42
|
+
type: 'button',
|
|
43
|
+
action: () => console.log('提交'),
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: '审核',
|
|
47
|
+
code: 'Detail_Audit',
|
|
48
|
+
type: 'button',
|
|
49
|
+
action: () => console.log('审核'),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: '反审核',
|
|
53
|
+
code: 'Detail_ReAudit',
|
|
54
|
+
type: 'button',
|
|
55
|
+
action: () => console.log('反审核'),
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<DetailPageWrapper
|
|
61
|
+
title="详情页演示"
|
|
62
|
+
actionList={actionList}
|
|
63
|
+
tradeType={180}
|
|
64
|
+
fromStatus={1}
|
|
65
|
+
>
|
|
66
|
+
<div style={{ padding: 16 }}>这里是详情内容区域</div>
|
|
67
|
+
</DetailPageWrapper>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
2. 切换 `fromStatus` 验证按钮显示
|
|
73
|
+
|
|
74
|
+
- `fromStatus=1`:显示 `Detail_Submit`
|
|
75
|
+
- `fromStatus=25`:显示 `Detail_Audit`
|
|
76
|
+
- `fromStatus=26`:显示 `Detail_ReAudit`
|
|
77
|
+
|
|
78
|
+
3. 权限过滤验证
|
|
79
|
+
|
|
80
|
+
- 从 `localStorage.menuAuth_mainProject` 移除某个 `code`,对应按钮不会显示
|
|
81
|
+
|
|
82
|
+
## 说明
|
|
83
|
+
|
|
84
|
+
- 详情页按钮显示条件:
|
|
85
|
+
- 资源 `code` 与 `BUSINESS_FLOW_BUTTONS.buttonCode` 完全一致
|
|
86
|
+
- `tradeType` 匹配
|
|
87
|
+
- `fromStatus` 匹配
|
|
88
|
+
- 权限启用且授权通过
|
|
89
|
+
- 其余属性(`routes`、`pathToRegexp` 等)非必需,可按页面实际需要补充。
|