@bit-sun/business-component 2.4.31-alpha.9 → 2.4.32

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.
Files changed (210) hide show
  1. package/.editorconfig +16 -16
  2. package/.fatherrc.ts +5 -5
  3. package/.gitlab-ci.yml +179 -179
  4. package/.prettierignore +7 -7
  5. package/.prettierrc +11 -11
  6. package/.umirc.ts +74 -74
  7. package/README.md +27 -27
  8. package/dist/index.d.ts +0 -1
  9. package/dist/index.esm.js +950 -1044
  10. package/dist/index.js +954 -1051
  11. package/dist/utils/auth.d.ts +0 -1
  12. package/docs/index.md +21 -21
  13. package/lib/assets/drag.svg +17 -17
  14. package/lib/assets/exportFail.svg +37 -37
  15. package/lib/assets/exportProcessing.svg +28 -28
  16. package/lib/assets/exportSuccess.svg +34 -34
  17. package/lib/assets/label_icon_bottom.svg +25 -25
  18. package/lib/assets/upExport.svg +22 -22
  19. package/package.json +80 -83
  20. package/src/assets/32.svg +27 -27
  21. package/src/assets/addIcon.svg +17 -17
  22. package/src/assets/allfunc.svg +27 -27
  23. package/src/assets/arrowRight.svg +24 -24
  24. package/src/assets/btn-delete.svg +29 -29
  25. package/src/assets/btn-edit.svg +19 -19
  26. package/src/assets/btn-more.svg +17 -17
  27. package/src/assets/btn-submit.svg +19 -19
  28. package/src/assets/caidan.svg +11 -11
  29. package/src/assets/close.svg +26 -26
  30. package/src/assets/drag.svg +17 -17
  31. package/src/assets/exportFail.svg +37 -37
  32. package/src/assets/exportProcessing.svg +28 -28
  33. package/src/assets/exportSuccess.svg +34 -34
  34. package/src/assets/fixed-left-active.svg +11 -11
  35. package/src/assets/fixed-left.svg +15 -15
  36. package/src/assets/fixed-right-active.svg +11 -11
  37. package/src/assets/fixed-right.svg +15 -15
  38. package/src/assets/guanbi.svg +15 -15
  39. package/src/assets/icon-quanping.svg +15 -15
  40. package/src/assets/icon-shezhi.svg +17 -17
  41. package/src/assets/label_icon_bottom.svg +25 -25
  42. package/src/assets/list-no-img.svg +21 -21
  43. package/src/assets/morentouxiang-32.svg +23 -23
  44. package/src/assets/scanning.svg +24 -24
  45. package/src/assets/upExport.svg +22 -22
  46. package/src/common/ENUM.ts +41 -41
  47. package/src/components/Business/AddSelectBusiness/index.md +162 -398
  48. package/src/components/Business/AddSelectBusiness/index.tsx +1062 -1099
  49. package/src/components/Business/BsLayouts/Components/AllFunc/drawContent.tsx +112 -112
  50. package/src/components/Business/BsLayouts/Components/AllFunc/index.less +153 -153
  51. package/src/components/Business/BsLayouts/Components/AllFunc/index.tsx +70 -70
  52. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/index.less +90 -90
  53. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/index.tsx +37 -37
  54. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/leftTree.tsx +242 -242
  55. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/rightTree.tsx +384 -384
  56. package/src/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/DrawContent.tsx +285 -285
  57. package/src/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/customMenuHeader.tsx +74 -74
  58. package/src/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/drawContent.less +170 -170
  59. package/src/components/Business/BsLayouts/Components/CustomerMenu/index.less +64 -64
  60. package/src/components/Business/BsLayouts/Components/CustomerMenu/index.tsx +153 -153
  61. package/src/components/Business/BsLayouts/Components/GlobalHeader/index.less +72 -72
  62. package/src/components/Business/BsLayouts/Components/GlobalHeader/index.tsx +158 -157
  63. package/src/components/Business/BsLayouts/Components/RightContent/LoginModal.tsx +85 -85
  64. package/src/components/Business/BsLayouts/Components/RightContent/home.less +218 -218
  65. package/src/components/Business/BsLayouts/Components/RightContent/index.tsx +155 -155
  66. package/src/components/Business/BsLayouts/Components/SearchFunc/index.less +160 -160
  67. package/src/components/Business/BsLayouts/Components/SearchFunc/index.tsx +75 -75
  68. package/src/components/Business/BsLayouts/index.less +79 -79
  69. package/src/components/Business/BsLayouts/index.tsx +1484 -1572
  70. package/src/components/Business/BsLayouts/service.ts +10 -10
  71. package/src/components/Business/BsLayouts/utils.tsx +203 -205
  72. package/src/components/Business/BsSulaQueryTable/SearchItemSetting.tsx +566 -566
  73. package/src/components/Business/BsSulaQueryTable/index.less +221 -221
  74. package/src/components/Business/BsSulaQueryTable/index.tsx +606 -560
  75. package/src/components/Business/BsSulaQueryTable/setting.tsx +854 -854
  76. package/src/components/Business/BsSulaQueryTable/utils.less +65 -65
  77. package/src/components/Business/BsSulaQueryTable/utils.tsx +690 -690
  78. package/src/components/Business/CommodityEntry/index.md +70 -84
  79. package/src/components/Business/CommodityEntry/index.tsx +81 -82
  80. package/src/components/Business/CommonAlert/index.tsx +23 -23
  81. package/src/components/Business/CommonGuideWrapper/index.less +111 -111
  82. package/src/components/Business/CommonGuideWrapper/index.md +39 -39
  83. package/src/components/Business/CommonGuideWrapper/index.tsx +83 -83
  84. package/src/components/Business/DetailPageWrapper/index.less +79 -79
  85. package/src/components/Business/DetailPageWrapper/index.tsx +315 -316
  86. package/src/components/Business/DetailPageWrapper/utils.tsx +164 -164
  87. package/src/components/Business/HomePageWrapper/index.less +33 -33
  88. package/src/components/Business/HomePageWrapper/index.md +45 -45
  89. package/src/components/Business/HomePageWrapper/index.tsx +162 -162
  90. package/src/components/Business/JsonQueryTable/components/FieldsModifyModal.tsx +824 -824
  91. package/src/components/Business/JsonQueryTable/components/FieldsSettingsTable.tsx +205 -205
  92. package/src/components/Business/JsonQueryTable/components/Formula.tsx +206 -206
  93. package/src/components/Business/JsonQueryTable/components/MaintainOptions.tsx +127 -127
  94. package/src/components/Business/JsonQueryTable/configButton/index.js +20 -20
  95. package/src/components/Business/JsonQueryTable/configTree/component/compactArrayView.js +25 -25
  96. package/src/components/Business/JsonQueryTable/configTree/component/compactObjectView.js +30 -30
  97. package/src/components/Business/JsonQueryTable/configTree/index.js +82 -82
  98. package/src/components/Business/JsonQueryTable/configTree/index.less +44 -44
  99. package/src/components/Business/JsonQueryTable/configTree/parser/highlight.js +57 -57
  100. package/src/components/Business/JsonQueryTable/configTree/parser/index.js +124 -124
  101. package/src/components/Business/JsonQueryTable/configTree/render/iconRender.js +29 -29
  102. package/src/components/Business/JsonQueryTable/configTree/render/nameRender.js +22 -22
  103. package/src/components/Business/JsonQueryTable/configTree/treeNode.js +116 -116
  104. package/src/components/Business/JsonQueryTable/drawer/index.tsx +12 -12
  105. package/src/components/Business/JsonQueryTable/function.ts +62 -62
  106. package/src/components/Business/JsonQueryTable/index.less +16 -16
  107. package/src/components/Business/JsonQueryTable/index.md +328 -328
  108. package/src/components/Business/JsonQueryTable/index.tsx +537 -537
  109. package/src/components/Business/JsonQueryTable/jsonEditor/index.js +346 -346
  110. package/src/components/Business/JsonQueryTable/jsonEditor/index.less +22 -22
  111. package/src/components/Business/JsonQueryTable/jsonEditor/lint/basicType.js +147 -147
  112. package/src/components/Business/JsonQueryTable/jsonEditor/lint/index.js +389 -389
  113. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/actions.js +118 -118
  114. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/dependency.js +22 -22
  115. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/index.js +21 -21
  116. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/request.js +65 -65
  117. package/src/components/Business/JsonQueryTable/static.ts +450 -450
  118. package/src/components/Business/SearchSelect/BusinessUtils.tsx +2120 -2120
  119. package/src/components/Business/SearchSelect/common.ts +134 -134
  120. package/src/components/Business/SearchSelect/index.md +1503 -1512
  121. package/src/components/Business/SearchSelect/index.tsx +55 -55
  122. package/src/components/Business/SearchSelect/utils.ts +101 -101
  123. package/src/components/Business/StateFlow/index.less +130 -130
  124. package/src/components/Business/StateFlow/index.md +60 -60
  125. package/src/components/Business/StateFlow/index.tsx +29 -29
  126. package/src/components/Business/TreeSearchSelect/index.md +185 -185
  127. package/src/components/Business/TreeSearchSelect/index.tsx +33 -33
  128. package/src/components/Business/TreeSearchSelect/utils.ts +104 -104
  129. package/src/components/Business/columnSettingTable/columnSetting.tsx +766 -766
  130. package/src/components/Business/columnSettingTable/index.less +247 -247
  131. package/src/components/Business/columnSettingTable/index.md +357 -357
  132. package/src/components/Business/columnSettingTable/index.tsx +235 -235
  133. package/src/components/Business/columnSettingTable/sulaSettingTable.tsx +243 -243
  134. package/src/components/Business/columnSettingTable/utils.tsx +71 -71
  135. package/src/components/Business/moreTreeTable/FixedScrollBar.tsx +87 -87
  136. package/src/components/Business/moreTreeTable/hooks/useSticky.ts +21 -21
  137. package/src/components/Business/moreTreeTable/index.less +99 -99
  138. package/src/components/Business/moreTreeTable/index.md +448 -448
  139. package/src/components/Business/moreTreeTable/index.tsx +387 -387
  140. package/src/components/Business/moreTreeTable/utils.ts +126 -126
  141. package/src/components/Functional/AddSelect/helps.ts +80 -80
  142. package/src/components/Functional/AddSelect/index.less +367 -367
  143. package/src/components/Functional/AddSelect/index.md +155 -155
  144. package/src/components/Functional/AddSelect/index.tsx +1171 -1011
  145. package/src/components/Functional/BillEntry/index.less +371 -371
  146. package/src/components/Functional/BillEntry/index.md +39 -39
  147. package/src/components/Functional/BillEntry/index.tsx +773 -773
  148. package/src/components/Functional/BsAntdSula/BsCascader/index.md +62 -62
  149. package/src/components/Functional/BsAntdSula/BsCascader/index.tsx +178 -178
  150. package/src/components/Functional/BsAntdSula/index.ts +2 -2
  151. package/src/components/Functional/DataImport/index.less +63 -63
  152. package/src/components/Functional/DataImport/index.md +44 -44
  153. package/src/components/Functional/DataImport/index.tsx +696 -701
  154. package/src/components/Functional/DataValidation/index.less +63 -63
  155. package/src/components/Functional/DataValidation/index.md +39 -52
  156. package/src/components/Functional/DataValidation/index.tsx +688 -701
  157. package/src/components/Functional/EllipsisTooltip/index.d.ts +5 -5
  158. package/src/components/Functional/EllipsisTooltip/index.js +36 -36
  159. package/src/components/Functional/EllipsisTooltip/index.md +30 -30
  160. package/src/components/Functional/ExportFunctions/ExportIcon/index.md +37 -37
  161. package/src/components/Functional/ExportFunctions/ExportIcon/index.tsx +60 -60
  162. package/src/components/Functional/QueryMutipleInput/index.less +37 -37
  163. package/src/components/Functional/QueryMutipleInput/index.md +33 -33
  164. package/src/components/Functional/QueryMutipleInput/index.tsx +128 -128
  165. package/src/components/Functional/SearchSelect/index.less +115 -115
  166. package/src/components/Functional/SearchSelect/index.md +141 -141
  167. package/src/components/Functional/SearchSelect/index.tsx +897 -896
  168. package/src/components/Functional/SearchSelect/utils.ts +3 -3
  169. package/src/components/Functional/TreeSearchSelect/index.md +47 -47
  170. package/src/components/Functional/TreeSearchSelect/index.tsx +204 -204
  171. package/src/components/Solution/RuleComponent/Formula.tsx +335 -335
  172. package/src/components/Solution/RuleComponent/InnerSelect.tsx +62 -62
  173. package/src/components/Solution/RuleComponent/index.d.ts +29 -29
  174. package/src/components/Solution/RuleComponent/index.js +2103 -2103
  175. package/src/components/Solution/RuleComponent/index.less +229 -229
  176. package/src/components/Solution/RuleComponent/renderSpecificAction.js +99 -99
  177. package/src/components/Solution/RuleComponent/ruleFiled.js +2293 -2293
  178. package/src/components/Solution/RuleComponent/services.ts +13 -13
  179. package/src/components/Solution/RuleComponent/util.js +143 -143
  180. package/src/components/Solution/RuleSetter/RuleInstance.tsx +6 -6
  181. package/src/components/Solution/RuleSetter/baseRule.tsx +368 -368
  182. package/src/components/Solution/RuleSetter/function.ts +336 -336
  183. package/src/components/Solution/RuleSetter/index.less +221 -221
  184. package/src/components/Solution/RuleSetter/index.tsx +208 -208
  185. package/src/components/Solution/RuleSetter/service.js +276 -276
  186. package/src/index.ts +40 -41
  187. package/src/plugin/TableColumnSetting/index.less +247 -247
  188. package/src/plugin/TableColumnSetting/index.md +50 -50
  189. package/src/plugin/TableColumnSetting/index.tsx +725 -725
  190. package/src/plugin/TableColumnSetting/utils.ts +19 -19
  191. package/src/styles/bsDefault.less +1912 -1912
  192. package/src/utils/CheckOneUser/index.md +39 -39
  193. package/src/utils/CheckOneUser/index.ts +51 -51
  194. package/src/utils/CustomLoginInfo.ts +55 -55
  195. package/src/utils/LocalstorageUtils.ts +128 -128
  196. package/src/utils/TableUtils.tsx +18 -18
  197. package/src/utils/auth.ts +32 -38
  198. package/src/utils/checkUtils.ts +39 -39
  199. package/src/utils/enumConfig.ts +16 -16
  200. package/src/utils/getFormMode.js +12 -12
  201. package/src/utils/index.ts +12 -12
  202. package/src/utils/requestUtils.ts +166 -166
  203. package/src/utils/serialize.js +7 -7
  204. package/src/utils/utils.ts +195 -195
  205. package/tsconfig.json +29 -29
  206. package/typings.d.ts +4 -4
  207. package/dist/components/Functional/AccessWrapper/index.d.ts +0 -5
  208. package/dist/components/Functional/AuthButton/index.d.ts +0 -3
  209. package/src/components/Functional/AccessWrapper/index.tsx +0 -34
  210. package/src/components/Functional/AuthButton/index.tsx +0 -15
@@ -1,1572 +1,1484 @@
1
- // @ts-nocheck
2
- import type {
3
- MenuDataItem,
4
- BasicLayoutProps as ProLayoutProps,
5
- Settings,
6
- } from '@ant-design/pro-layout';
7
- import ProLayout from '@ant-design/pro-layout';
8
- import React, { useState, createRef, useRef } from 'react';
9
- import {
10
- Tabs,
11
- Dropdown,
12
- Menu,
13
- } from 'antd';
14
- import {
15
- Link,
16
- useIntl,
17
- history,
18
- useModel,
19
- } from 'umi';
20
- import {
21
- DashOutlined,
22
- MenuUnfoldOutlined,
23
- CaretLeftOutlined,
24
- HomeOutlined,
25
- DoubleLeftOutlined,
26
- DoubleRightOutlined,
27
- } from '@ant-design/icons';
28
- import SearchFunc from './Components/SearchFunc';
29
- import { debounce } from 'lodash';
30
-
31
- import AllFunc from './Components/AllFunc';
32
- import {
33
- getBreadcrumbNameMap,
34
- ergodicMenuRoutes,
35
- matchPath,
36
- encodeUrlQuery,
37
- } from './utils';
38
- import moment from 'moment';
39
- import GlobalHeaderCom from './Components/GlobalHeader';
40
- import CustomerMenu from './Components/CustomerMenu';
41
- import CustomerMenuHeader from './Components/CustomerMenu/globalMenu/customMenuHeader';
42
- import './index.less';
43
- import { DndProvider, useDrag, useDrop } from 'react-dnd';
44
- import { HTML5Backend } from 'react-dnd-html5-backend';
45
- import ENUM from '@/utils/enumConfig';
46
- import { memoizeOneFormatter } from '@/utils/utils';
47
- import Item from 'antd/lib/list/Item';
48
- import { getLimitMenuDataKey, shouldUseAuth } from '@/utils';
49
- import NoFoundPage from '@/components/Functional/AccessWrapper';
50
-
51
- const { TabPane } = Tabs;
52
-
53
- export const RouterContext = React.createContext({});
54
-
55
- export type BasicLayoutProps = {
56
- breadcrumbNameMap: Record<string, MenuDataItem>;
57
- route: ProLayoutProps['route'] & {
58
- authority: string[];
59
- };
60
- settings: Settings;
61
- } & ProLayoutProps;
62
-
63
- export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
64
- breadcrumbNameMap: Record<string, MenuDataItem>;
65
- };
66
-
67
- const getId = (str) => {
68
- // 找到最后一个 / 的位置
69
- var lastSlashIndex = str.lastIndexOf("/");
70
-
71
- // 如果找到了 /,则返回它后面的部分
72
- if (lastSlashIndex !== -1) {
73
- return str.substring(lastSlashIndex + 1);
74
- } else {
75
- // 如果没有找到 /,则返回整个字符串
76
- return null;
77
- }
78
- }
79
-
80
- // 获取权限菜单path&通用单据id
81
- const getAuthMenuPathAndDocsId = (pathToRegexp) => {
82
- const limitedMenuData = localStorage.getItem(getLimitMenuDataKey()) ? JSON.parse(localStorage.getItem(getLimitMenuDataKey())) : [];
83
- const menuKeys = [];
84
- const docsId = [];
85
- const getLimitedMenuKeys = (data) => {
86
- data.forEach((item) => {
87
- if (item.children && item.children.length > 0) {
88
- getLimitedMenuKeys(item.children);
89
- } else {
90
- const originPath = item.path.replace(/^\/\w+\//, '/');
91
- menuKeys.push(originPath);
92
- if (pathToRegexp('/operation-and-maintenance-center/configuration-management/all-general-documents-specific/:id').test(originPath)) {
93
- getId(originPath) && docsId.push(getId(originPath))
94
- }
95
- }
96
- });
97
- };
98
- try {
99
- getLimitedMenuKeys(limitedMenuData);
100
- } catch(e) {}
101
- return {menuKeys, docsId};
102
- }
103
-
104
- const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
105
- menuList.map((item) => {
106
- return {
107
- ...item,
108
- children: item.children ? menuDataRender(item.children) : undefined,
109
- };
110
- });
111
-
112
- let UN_LISTTEN_DRP;
113
- let routerArray = [];
114
- let authMenuPathList = [];
115
- let docsId = [];
116
- let lastTwoRouterArray = [1, 2];
117
-
118
- let draggerTabKeys = [];
119
-
120
- const type = 'DraggableTabNode';
121
- const DraggableTabNode = ({ index, children, moveNode }) => {
122
- const ref = useRef(null);
123
- const [{ isOver, dropClassName }, drop] = useDrop({
124
- accept: type,
125
- collect: (monitor) => {
126
- const { index: dragIndex } = monitor.getItem() || {};
127
-
128
- if (dragIndex === index) {
129
- return {};
130
- }
131
-
132
- return {
133
- isOver: monitor.isOver(),
134
- dropClassName: 'dropping',
135
- };
136
- },
137
- drop: (item) => {
138
- moveNode(item.index, index);
139
- },
140
- });
141
- const [, drag] = useDrag({
142
- type,
143
- item: {
144
- index,
145
- },
146
- collect: (monitor) => ({
147
- isDragging: monitor.isDragging(),
148
- }),
149
- });
150
- drop(drag(ref));
151
- return (
152
- <div
153
- ref={ref}
154
- style={{
155
- marginRight: 24,
156
- }}
157
- className={isOver ? dropClassName : ''}
158
- >
159
- {children}
160
- </div>
161
- );
162
- };
163
-
164
- const DraggableTabs = (props) => {
165
- const { children, changeListenRouterState } = props;
166
- const [order, setOrder] = useState([]);
167
-
168
- const moveTabNode = (dragKey, hoverKey) => {
169
- const newOrder = order.slice();
170
- React.Children.forEach(children, (c) => {
171
- if (c.key && newOrder.indexOf(c.key) === -1) {
172
- newOrder.push(c.key);
173
- }
174
- });
175
- const dragIndex = newOrder.indexOf(dragKey);
176
- const hoverIndex = newOrder.indexOf(hoverKey);
177
- newOrder.splice(dragIndex, 1);
178
- newOrder.splice(hoverIndex, 0, dragKey);
179
- changeListenRouterState(dragIndex, hoverIndex);
180
- setOrder(newOrder);
181
- };
182
-
183
- const renderTabBar = (tabBarProps, DefaultTabBar) => (
184
- <DefaultTabBar {...tabBarProps}>
185
- {(node) => (
186
- <DraggableTabNode
187
- key={node.key}
188
- index={node.key}
189
- moveNode={moveTabNode}
190
- >
191
- {node}
192
- </DraggableTabNode>
193
- )}
194
- </DefaultTabBar>
195
- );
196
-
197
- const tabs = [];
198
- React.Children.forEach(children, (c) => {
199
- tabs.push(c);
200
- });
201
- const orderTabs = tabs.slice().sort((a, b) => {
202
- const orderA = order.indexOf(a.key);
203
- const orderB = order.indexOf(b.key);
204
-
205
- if (orderA !== -1 && orderB !== -1) {
206
- return orderA - orderB;
207
- }
208
-
209
- if (orderA !== -1) {
210
- return -1;
211
- }
212
-
213
- if (orderB !== -1) {
214
- return 1;
215
- }
216
-
217
- const ia = tabs.indexOf(a);
218
- const ib = tabs.indexOf(b);
219
- return ia - ib;
220
- });
221
- return (
222
- <DndProvider backend={HTML5Backend}>
223
- <Tabs renderTabBar={renderTabBar} {...props}>
224
- {orderTabs}
225
- </Tabs>
226
- </DndProvider>
227
- );
228
- };
229
-
230
- const ItemMenu = (props) => {
231
- const {
232
- info: { key },
233
- operateFun,
234
- listenRouterState,
235
- } = props;
236
- let index = listenRouterState.findIndex((item) => item.key === key);
237
-
238
- const menu = (
239
- <Menu>
240
- <Menu.Item key="0" style={{ fontSize: '12px', textAlign: 'center' }}>
241
- <a
242
- onClick={(e) => {
243
- e.stopPropagation();
244
- operateFun(key, 'self');
245
- }}
246
- >
247
- 关闭当前标签
248
- </a>
249
- </Menu.Item>
250
- <Menu.Item
251
- disabled={index === 0}
252
- key="1"
253
- style={{ fontSize: '12px', textAlign: 'center' }}
254
- >
255
- <a
256
- onClick={(e) => {
257
- e.stopPropagation();
258
- operateFun(key, 'left');
259
- }}
260
- >
261
- 关闭其左侧标签
262
- </a>
263
- </Menu.Item>
264
- <Menu.Item
265
- disabled={index === listenRouterState.length - 1}
266
- key="2"
267
- style={{ fontSize: '12px', textAlign: 'center' }}
268
- >
269
- <a
270
- onClick={(e) => {
271
- e.stopPropagation();
272
- operateFun(key, 'right');
273
- }}
274
- >
275
- 关闭其右侧标签
276
- </a>
277
- </Menu.Item>
278
- <Menu.Item
279
- disabled={index === listenRouterState.length - 1}
280
- key="3"
281
- style={{ fontSize: '12px', textAlign: 'center' }}
282
- >
283
- <a
284
- onClick={(e) => {
285
- e.stopPropagation();
286
- operateFun(key, 'other');
287
- }}
288
- >
289
- 关闭其他标签
290
- </a>
291
- </Menu.Item>
292
- <Menu.Item
293
- disabled={index === listenRouterState.length - 1}
294
- key="4"
295
- style={{ fontSize: '12px', textAlign: 'center' }}
296
- >
297
- <a
298
- onClick={(e) => {
299
- e.stopPropagation();
300
- operateFun(key, 'all');
301
- }}
302
- >
303
- 关闭全部标签
304
- </a>
305
- </Menu.Item>
306
- </Menu>
307
- );
308
- return (
309
- <Dropdown overlay={menu} trigger={['hover']}>
310
- <a
311
- className="ant-dropdown-link"
312
- onClick={(e) => {
313
- e.preventDefault();
314
- e.stopPropagation();
315
- }}
316
- >
317
- <img style={{ marginRight: '-12px' }} src="./biaoqian-icon.svg" />
318
- </a>
319
- </Dropdown>
320
- );
321
- };
322
-
323
- class BasicLayout extends React.PureComponent {
324
- allFunc: any = createRef('');
325
- customerMenuRef: any = createRef('');
326
- actionRef: any = createRef<{
327
- reload: () => void;
328
- }>();
329
- constructor(props) {
330
- super(props);
331
- authMenuPathList = getAuthMenuPathAndDocsId(props.pathToRegexp)?.menuKeys || [];
332
- docsId = getAuthMenuPathAndDocsId(props.pathToRegexp)?.docsId || [];
333
- routerArray = this.updateTree(props.route.routes, authMenuPathList);
334
- const homeRouter = routerArray.filter(
335
- (itemroute) => itemroute.key === '/',
336
- )[0];
337
- const breadcrumbNameMap = getBreadcrumbNameMap(
338
- memoizeOneFormatter(props.route.routes, ''),
339
- );
340
- const hideMenuArray = ergodicMenuRoutes(props.route.routes);
341
-
342
- this.state = {
343
- listenRouterState: [
344
- { ...homeRouter, key: '/', tab: '欢迎', closable: false },
345
- ],
346
- listenRouterKey: ['/'],
347
- activeKey: '/',
348
- homeRouter,
349
- customerMatchs: [],
350
- breadcrumbNameMap,
351
- hideMenuArray,
352
- keyWord: '',
353
- collapse: false,
354
- drawerLeftParams: {
355
- visible: false,
356
- width: 690,
357
- title: '搜索',
358
- onClose: () => {
359
- this.setState({
360
- drawerLeftParams: {
361
- ...this.state.drawerLeftParams,
362
- visible: false,
363
- },
364
- });
365
- },
366
- },
367
- currentSubMenuData: [],
368
- showSubMenu: false,
369
- isSlider: false,
370
- };
371
- }
372
-
373
- componentDidMount() {
374
- const {
375
- history,
376
- location,
377
- itemPath,
378
- pathToRegexp,
379
- } = this.props;
380
-
381
- let istParent = 0;
382
-
383
- var self = this;
384
-
385
- // window.top != window &&
386
- // window.addEventListener('message', function (e) {
387
- // istParent = 1;
388
- // if (localStorage.getItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK)) {
389
- // localStorage.removeItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK);
390
- // } else {
391
- // localStorage.setItem('isTabChange', true);
392
- // }
393
-
394
- // if (typeof e.data === 'string') {
395
- // let newKey = encodeUrlQuery(e.data.replace(/^\/\w+\//, '/'));
396
- // history.push(newKey);
397
- // } else {
398
- // const info = e.data;
399
- // if (info.type === 'remove') {
400
- // self.tabActions['remove'](info.key.replace(/^\/\w+\//, '/'));
401
- // }
402
- // }
403
- // });
404
-
405
- window.$wujie?.bus.$on("main-route-change", function (appname, info) {
406
- if (appname === itemPath) {
407
- if (localStorage.getItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK)) {
408
- localStorage.removeItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK);
409
- } else {
410
- localStorage.setItem('isTabChange', true);
411
- }
412
- istParent = 1;
413
- if (info.type === 'main') {
414
- let newPath = encodeUrlQuery(info.path);
415
- history.push(newPath)
416
- }
417
- if (info.type === 'remove') {
418
- self.tabActions['remove'](info.path);
419
- }
420
- }
421
- });
422
-
423
- UN_LISTTEN_DRP = history.listen((route) => {
424
- // if ((window as any).__POWERED_BY_QIANKUN__) {
425
- // if (window.location.href.indexOf(`/${itemPath}`) === -1) return;
426
- // }
427
- if (route.pathname.startsWith(`/${itemPath}/`)) return;
428
- const {
429
- listenRouterState,
430
- listenRouterKey,
431
- customerMatchs,
432
- hideMenuArray,
433
- } = this.state;
434
- let newListenRouterState = [...listenRouterState];
435
- let newListenRouterKey = [...listenRouterKey];
436
-
437
- /**
438
- * 根据给定的路由数组和当前路由信息,筛选出与当前路由匹配的路由项。
439
- *
440
- * @param routerArray 路由数组,包含多个路由项,每个路由项有一个键(key)。
441
- * @param route 当前的路由信息,包含路径(pathname)等信息。
442
- * @param docsId 通用单据ID的数组,用于进一步筛选路由。
443
- * @returns 返回与当前路由匹配的第一个路由项,如果没有匹配项则返回undefined。
444
- */
445
- let replaceRouter = routerArray.filter((itemRoute) => {
446
- // 单独处理通用单据预览
447
- if (window.top !== window && !window.__POWERED_BY_WUJIE__ && route.pathname?.includes('all-general-documents')) {
448
- return pathToRegexp(itemRoute.key || '').test(route.pathname);
449
- }
450
- // 当路由路径包含'all-general-documents'时,按通用单据处理
451
- if (route.pathname?.includes('all-general-documents') && shouldUseAuth()) {
452
- // 检查路由路径是否匹配路由项的键,并且路径中包含至少一个通用单据ID
453
- return pathToRegexp(itemRoute.key || '').test(route.pathname) && docsId.some(item => route.pathname.includes(item));
454
- }
455
- // 对于不包含'all-general-documents'的路径,只检查路由路径是否匹配路由项的键
456
- return pathToRegexp(itemRoute.key || '').test(route.pathname);
457
- })[0];
458
-
459
- let currentKey = '';
460
-
461
- if (replaceRouter && replaceRouter.isOnlyOnePage) {
462
- // 处理中英文和特殊字符
463
- currentKey = decodeURIComponent(route.pathname);
464
- } else {
465
- currentKey = decodeURIComponent(
466
- route.pathname + this.parseQueryString(route.search),
467
- );
468
- }
469
-
470
- if (!istParent) {
471
- if (route.pathname === '/') return;
472
- window.$wujie?.bus.$emit('sub-route-change', itemPath, currentKey);
473
- // window.parent.postMessage(`/parent/${itemPath}${currentKey}`, '*');
474
- }
475
-
476
- // 防止出错
477
- if (listenRouterKey.length !== listenRouterState.length) {
478
- listenRouterState.forEach((item, index) => {
479
- listenRouterKey[index] = item.key;
480
- });
481
- }
482
-
483
- if (!listenRouterKey.includes(currentKey)) {
484
-
485
- if (!replaceRouter) {
486
- replaceRouter = {
487
- content: currentKey,
488
- key: currentKey,
489
- name:'404',
490
- tab: '404',
491
- isNotFound: true,
492
- }
493
-
494
- newListenRouterState = [
495
- ...newListenRouterState,
496
- {
497
- ...replaceRouter,
498
- },
499
- ];
500
- newListenRouterKey = [...listenRouterKey, currentKey];
501
- } else {
502
- const match = matchPath(route.pathname, { path: replaceRouter.key }, pathToRegexp);
503
- newListenRouterState = [
504
- ...newListenRouterState,
505
- {
506
- ...replaceRouter,
507
- query: route.query,
508
- match: match,
509
- key: currentKey,
510
- tab: this.getPageTitle(route.pathname) + '',
511
- },
512
- ];
513
- newListenRouterKey = [...listenRouterKey, currentKey];
514
- }
515
- }
516
-
517
- // 处理hideMenu页面自动关闭
518
- lastTwoRouterArray.push(route.pathname);
519
- lastTwoRouterArray.shift();
520
- if (
521
- !localStorage.getItem('isTabChange') &&
522
- !localStorage.getItem('isMenuClick')
523
- ) {
524
- if (
525
- lastTwoRouterArray[0] &&
526
- typeof lastTwoRouterArray[0] === 'string'
527
- ) {
528
- let needRemoveKeyArray = hideMenuArray.filter((itemRoute) =>
529
- pathToRegexp(itemRoute.path || '').test(lastTwoRouterArray[0]),
530
- );
531
- // lastTwoRouterArray[0] != lastTwoRouterArray[1] 该判断条件用于判断是否是tab删除操作,如果是tab页删除操作,删除的是不是最后一个打开的tab页,执行history.push会导致错误的将最后打开的那个tab页也删除掉
532
- if (
533
- needRemoveKeyArray.length &&
534
- lastTwoRouterArray[0] != lastTwoRouterArray[1] && !route.state?.thisHideInMenuDoNotClose
535
- ) {
536
- newListenRouterState = newListenRouterState.filter((item) => {
537
- const [pathname] = item.key ? item.key.split('?') : [];
538
- return pathname && pathname !== lastTwoRouterArray[0];
539
- });
540
- newListenRouterKey = newListenRouterKey.filter((item) => {
541
- const [pathname] = item ? item.split('?') : [];
542
- return pathname && pathname !== lastTwoRouterArray[0];
543
- });
544
- }
545
- }
546
- // refs?.tableRef?.current?.refreshTable();
547
- } else {
548
- setTimeout(() => {
549
- // 处理页面刷新两面
550
- localStorage.removeItem('isTabChange');
551
- localStorage.removeItem('isMenuClick');
552
- }, 0);
553
- }
554
- this.setState(
555
- {
556
- //路由监听函数最后执行setState,避免处理hideMenu类型页面自动关闭的逻辑块内获取不到最新state的listenRouterState和listenRouterKey
557
- activeKey: currentKey,
558
- listenRouterState: newListenRouterState,
559
- listenRouterKey: newListenRouterKey,
560
- },
561
- () => {
562
- this.checkisNavSlide();
563
- },
564
- );
565
-
566
- istParent = 0;
567
- });
568
-
569
- if ( localStorage.getItem('mainRoutePath') && localStorage.getItem('mainRoutePath')?.startsWith(`/${itemPath}/`)) {
570
- istParent = 1;
571
- history.push(localStorage.getItem('mainRoutePath').replace(/^\/\w+\//, '/'))
572
- } else if (localStorage.getItem('firstPage') && localStorage.getItem('firstPage')?.startsWith(`#/${itemPath}/`)) {
573
- // 暂时保留,兼容老版本
574
- istParent = 1;
575
- history.push(
576
- localStorage
577
- .getItem('firstPage')
578
- ?.slice(1)
579
- .replace(/^\/\w+\//, '/'),
580
- );
581
- } else {
582
- history.push(location);
583
- }
584
- }
585
-
586
- componentWillUnmount() {
587
- // eslint-disable-next-line no-unused-expressions
588
- UN_LISTTEN_DRP && UN_LISTTEN_DRP();
589
- }
590
-
591
- parseQueryString = (queryString) => {
592
- if (!queryString) {
593
- return '';
594
- }
595
-
596
- if (queryString.indexOf('?') < 0) {
597
- return `?${queryString}`;
598
- }
599
-
600
- return queryString;
601
- };
602
-
603
- updateTree = (Tree, authMenuKeys = []) => {
604
- const treeData = Tree;
605
- const treeList = [];
606
-
607
-
608
-
609
- // 是否为权限菜单路径
610
- const getLimitedMenuPath = (node) => {
611
- return authMenuKeys.some(item => (node.path || '').includes(item));
612
- }
613
-
614
- // 是否为通用单据菜单路径
615
- const getGenerateDocs = (node) => {
616
- return (node.path || '').includes('all-general-documents');
617
- }
618
-
619
- // 递归获取树列表
620
- const getTreeList = (data) => {
621
- data.forEach((node) => {
622
- if (node.routes && node.routes.length > 0) {
623
- getTreeList(node.routes);
624
- return;
625
- }
626
- // todo:暂时处理非wujie环境不做404管控
627
- if (!window.__POWERED_BY_WUJIE__) {
628
- treeList.push({
629
- tab: node.locale,
630
- key: node.path,
631
- locale: node.locale,
632
- closable: true,
633
- content: node.component,
634
- name: node.name,
635
- hideInMenu: node.hideInMenu,
636
- isOnlyOnePage: node.isOnlyOnePage,
637
- });
638
- return;
639
- }
640
- if (node.path === '/' || getLimitedMenuPath(node) || getGenerateDocs(node)) {
641
- treeList.push({
642
- tab: node.locale,
643
- key: node.path,
644
- locale: node.locale,
645
- closable: true,
646
- content: node.component,
647
- name: node.name,
648
- hideInMenu: node.hideInMenu,
649
- isOnlyOnePage: node.isOnlyOnePage,
650
- });
651
- }
652
- });
653
- };
654
- getTreeList(treeData);
655
- return treeList;
656
- };
657
-
658
- getDictionarySource = (dicCode: string, needConvertInterger = false) => {
659
- const { dictionaryData } = this.props;
660
-
661
- let dicData = {};
662
-
663
- if (!dictionaryData) {
664
- let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
665
- ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
666
- : {};
667
- dicData = storageDic[dicCode];
668
- } else {
669
- dicData = dictionaryData[dicCode];
670
- }
671
- // if (!dicData || !dicData.length) {
672
- // throw new Error(`当前没有${dicCode}字典值`);
673
- // }
674
-
675
- try {
676
- if (needConvertInterger) {
677
- dicData = dicData.map((item: { text: string; value: string }) => ({
678
- ...item,
679
- value: parseFloat(item.value),
680
- }));
681
- }
682
- } catch (e) { }
683
-
684
- return dicData;
685
- };
686
-
687
- getDictionaryTextByValue = (dicCode: string, value: string) => {
688
- let dicData = [];
689
- let dictionaryData: any;
690
- if (!dictionaryData) {
691
- let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
692
- ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
693
- : {};
694
- dicData = storageDic[dicCode];
695
- } else {
696
- dicData = dictionaryData[dicCode];
697
- }
698
-
699
- if (!dicData || !dicData.length) {
700
- // throw new Error(`当前没有${dicCode}字典值`);
701
- }
702
-
703
- if (value === undefined) return '- -';
704
-
705
- const dicItemArray = dicData?.filter(
706
- (item: { value: string }) => item.value === value.toString(),
707
- );
708
-
709
- if (!dicItemArray?.length) {
710
- // throw new Error(`当前${dicCode}字典值合没有${value}的数据`)
711
- return value;
712
- }
713
-
714
- return dicItemArray[0].text;
715
- };
716
-
717
- timeFormat = (timeStr, format, notNeedConvertTimeZone) => {
718
- if (!timeStr) return '- -';
719
-
720
- if (notNeedConvertTimeZone) {
721
- return moment(timeStr).format(format);
722
- }
723
-
724
- return moment(timeStr).add(8, 'hours').format(format) || '- -';
725
- };
726
-
727
- onChange = (key) => {
728
- if (key !== this.state.activeKey) {
729
- this.setState({
730
- activeKey: key,
731
- });
732
- localStorage.setItem('isTabChange', '1');
733
- let newKey = encodeUrlQuery(key);
734
- history.push(newKey);
735
- }
736
- };
737
-
738
- getPageTitle = (pathname) => {
739
- const { formatMessage } = this.props;
740
- const { breadcrumbNameMap } = this.state;
741
- const currRouterData = this.matchParamsPath(pathname, breadcrumbNameMap);
742
-
743
- if (!currRouterData) {
744
- return '';
745
- }
746
- const pageName = formatMessage({
747
- id: currRouterData.locale || currRouterData.name,
748
- defaultMessage: currRouterData.name,
749
- });
750
-
751
- return `${pageName}`;
752
- };
753
-
754
- matchParamsPath = (pathname, breadcrumbNameMap) => {
755
- const { pathToRegexp } = this.props;
756
- const pathKey = Object.keys(breadcrumbNameMap).find((key) =>
757
- pathToRegexp(key).test(pathname),
758
- );
759
- return breadcrumbNameMap[pathKey];
760
- };
761
-
762
- onEdit = (
763
- targetKey: React.MouseEvent | React.KeyboardEvent | string,
764
- action: string,
765
- ) => {
766
- this.tabActions[action](targetKey);
767
- };
768
-
769
- tabActions: any = {
770
- remove: (targetKey: string) => {
771
- const { listenRouterState, activeKey, customerMatchs, listenRouterKey } =
772
- this.state;
773
-
774
- let lastIndex: number = 0;
775
- let newActiveKey: string | undefined = activeKey;
776
- let newListenRouterState = [];
777
- let newListenRouterKey = [];
778
-
779
- if (targetKey === activeKey) {
780
- listenRouterState.forEach((pane, i) => {
781
- if (pane.key === targetKey) {
782
- lastIndex = i - 1;
783
- }
784
- });
785
-
786
- newListenRouterState = listenRouterState.filter(
787
- (item) => item.key !== targetKey,
788
- );
789
- newListenRouterKey = listenRouterKey.filter(
790
- (item) => item !== targetKey,
791
- );
792
-
793
- if (lastIndex < 0) {
794
- lastIndex = 0;
795
- }
796
-
797
- newActiveKey = newListenRouterState[lastIndex].key;
798
- } else {
799
- newListenRouterState = listenRouterState.filter(
800
- (item) => item.key !== targetKey,
801
- );
802
- newListenRouterKey = listenRouterKey.filter(
803
- (item) => item !== targetKey,
804
- );
805
- }
806
-
807
- this.setState(
808
- {
809
- activeKey: newActiveKey,
810
- listenRouterState: newListenRouterState,
811
- listenRouterKey: newListenRouterKey,
812
- },
813
- () => {
814
- let newKey = encodeUrlQuery(newActiveKey);
815
- history.push({
816
- pathname: newKey,
817
- });
818
- this.checkisNavSlide();
819
- },
820
- );
821
- },
822
- };
823
-
824
- updateState = (newListenRouterState, newListenRouterKey, cb) => {
825
- this.setState(
826
- {
827
- listenRouterState: newListenRouterState,
828
- listenRouterKey: newListenRouterKey,
829
- },
830
- () => {
831
- this.checkisNavSlide();
832
- if (cb) cb();
833
- },
834
- );
835
- };
836
-
837
- handleClose = () => {
838
- this.setState({
839
- drawerLeftParams: {
840
- ...this.state.drawerLeftParams,
841
- visible: false,
842
- },
843
- isCollapse: true,
844
- });
845
- this.allFunc.current?.close?.();
846
- this.customerMenuRef.current?.close?.();
847
- };
848
-
849
- handleMenuClick = (item: any) => {
850
- if (item.children || !item.component) return;
851
- let newKey = encodeUrlQuery(item.path);
852
- history.push({
853
- pathname: newKey,
854
- });
855
- this.setShowMenu(false);
856
- };
857
-
858
- getMenuDom = (menuData) => {
859
- return menuData.map((item) => (
860
- <div>
861
- <div
862
- onClick={() => {
863
- this.handleMenuClick(item);
864
- }}
865
- className={`${'menu_item'} ${item.children || !item.component ? '' : 'link_style'
866
- }`}
867
- style={{
868
- fontWeight: item.children || !item.component ? 'bolder' : '400',
869
- paddingLeft: '10px',
870
- marginTop: item.children || !item.component ? '5px' : '0px',
871
- fontSize: item.children || !item.component ? '14px' : '12px',
872
- }}
873
- >
874
- {item.name}
875
- </div>
876
- {!!item.children &&
877
- !!item.children.length &&
878
- this.getMenuDom(item.children)}
879
- </div>
880
- ));
881
- };
882
-
883
- setShowMenu = debounce((isShow) => {
884
- this.setState({
885
- showSubMenu: isShow,
886
- });
887
- }, 500);
888
-
889
- //设置tabs标签左右滚动
890
- setTabNavTransLate = (num) => {
891
- let globalTabsNav = document
892
- .getElementById('globalTabs')
893
- ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
894
- let globalTabsNavWrap = document
895
- .getElementById('globalTabs')
896
- ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
897
- let wrapWidth = globalTabsNavWrap.offsetWidth; //tabsNav父节点宽度
898
- let navListWidth = globalTabsNav.offsetWidth; //tabsNav总宽度
899
- if (navListWidth - wrapWidth <= 0) return;
900
- let maxTransX = navListWidth - wrapWidth; // 允许移动最大宽度
901
- let transXStr = document.defaultView?.getComputedStyle(
902
- globalTabsNav,
903
- null,
904
- ).transform;
905
- let transx = transXStr?.split(',')[4]; //当前translateX的值
906
-
907
- let targetTransX = Math.abs(Number(transx)) + num;
908
- if (targetTransX <= 0) targetTransX = 0;
909
- if (targetTransX >= Number(maxTransX)) targetTransX = Number(maxTransX);
910
- globalTabsNav.style.transform = 'translateX(-' + targetTransX + 'px)';
911
- };
912
-
913
- checkisNavSlide = () => {
914
- if (window.top != window) return;
915
- //监听tabs页签总长度判断是否可点击滑动
916
- let globalTabsNav = document
917
- .getElementById('globalTabs')
918
- ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
919
- let globalTabsNavWrap = document
920
- .getElementById('globalTabs')
921
- ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
922
- let wrapWidth = globalTabsNavWrap?.offsetWidth; //tabsNav父节点宽度
923
- let navListWidth = globalTabsNav?.offsetWidth; //tabsNav总宽度
924
- if (navListWidth - wrapWidth <= 0) {
925
- this.setState({
926
- isSlider: false,
927
- });
928
- return;
929
- }
930
- this.setState({
931
- isSlider: true,
932
- });
933
- };
934
-
935
- changeListenRouterState = (dragIndex: number, hoverIndex: number) => {
936
- const { listenRouterState, listenRouterKey } = this.state;
937
- let dragItem = listenRouterState[dragIndex];
938
- let dragKeyItem = listenRouterKey[dragIndex];
939
-
940
- listenRouterState.splice(dragIndex, 1);
941
- listenRouterState.splice(hoverIndex, 0, dragItem);
942
-
943
- listenRouterKey.splice(dragIndex, 1);
944
- listenRouterKey.splice(hoverIndex, 0, dragKeyItem);
945
- };
946
-
947
- operateFun = (key, type) => {
948
- const { listenRouterState, activeKey, listenRouterKey } = this.state;
949
- let deleteKey = '';
950
- let newlistenRouterState = [];
951
- let newlistenRouterKey = [];
952
- let newActiveKey = '';
953
- let deleteIndex = 0;
954
- if (type === 'self') {
955
- deleteIndex = listenRouterState.findIndex((item) => item.key === key);
956
- deleteKey = key;
957
- if (deleteIndex > 0) {
958
- newActiveKey = listenRouterState[deleteIndex - 1].key;
959
- } else {
960
- newActiveKey = listenRouterState[1].key;
961
- }
962
- newlistenRouterState = listenRouterState.filter((d) => d.key !== key);
963
- newlistenRouterKey = listenRouterKey.filter((d) => d !== key);
964
- this.updateState(newlistenRouterState, newlistenRouterKey, () => {
965
- if (deleteKey === activeKey) {
966
- let newKey = encodeUrlQuery(newActiveKey);
967
- history.push({
968
- pathname: newKey,
969
- });
970
- }
971
- });
972
- }
973
- if (type === 'left') {
974
- const index = listenRouterState.findIndex((item) => item.key === key);
975
- newlistenRouterState = listenRouterState.filter(
976
- (d: any, i: number) => i >= index || d.key === '/',
977
- );
978
- newlistenRouterKey = listenRouterKey.filter(
979
- (d: any, i: number) => i >= index || d === '/',
980
- );
981
- this.updateState(newlistenRouterState, newlistenRouterKey, () => {
982
- if (newlistenRouterKey.find((item) => item === activeKey)) {
983
- return;
984
- } else {
985
- let newKey = encodeUrlQuery(key);
986
- history.push({
987
- pathname: newKey,
988
- });
989
- }
990
- });
991
- }
992
- if (type === 'right') {
993
- const index = listenRouterState.findIndex((item) => item.key === key);
994
- newlistenRouterState = listenRouterState.filter(
995
- (d: any, i: number) => i <= index || d.key === '/',
996
- );
997
- newlistenRouterKey = listenRouterKey.filter(
998
- (d: any, i: number) => i <= index || d === '/',
999
- );
1000
- this.updateState(
1001
- listenRouterState.filter(
1002
- (d: any, i: number) => i <= index || d.key === '/',
1003
- ),
1004
- listenRouterKey.filter((d: any, i: number) => i <= index || d === '/'),
1005
- () => {
1006
- if (newlistenRouterKey.find((item) => item === activeKey)) {
1007
- return;
1008
- } else {
1009
- let newKey = encodeUrlQuery(key);
1010
- history.push({
1011
- pathname: newKey,
1012
- });
1013
- }
1014
- },
1015
- );
1016
- }
1017
- if (type === 'all') {
1018
- this.updateState(
1019
- listenRouterState.filter((item) => item.key === '/'),
1020
- listenRouterKey.filter((item) => item === '/'),
1021
- () => {
1022
- history.push({
1023
- pathname: '/',
1024
- });
1025
- },
1026
- );
1027
- }
1028
- if (type === 'other') {
1029
- this.updateState(
1030
- listenRouterState.filter(
1031
- (item) => item.key === key || item.key === '/',
1032
- ),
1033
- listenRouterKey.filter((item) => item === key || item === '/'),
1034
- () => {
1035
- if (key !== activeKey) {
1036
- let newKey = encodeUrlQuery(key);
1037
- history.push({
1038
- pathname: newKey,
1039
- });
1040
- }
1041
- },
1042
- );
1043
- }
1044
- };
1045
-
1046
- render() {
1047
- const {
1048
- listenRouterState,
1049
- activeKey,
1050
- listenRouterKey,
1051
- drawerLeftParams,
1052
- collapse,
1053
- currentSubMenuData,
1054
- showSubMenu,
1055
- currentSubPath,
1056
- } = this.state;
1057
- const { originRoutes, itemPath, defaultSettings, transparentProps={} } = this.props;
1058
- const TabTitle: React.FC<{}> = ({ item, index, updateState }) => {
1059
- return (
1060
- <div className="tab_title_content">
1061
- {item.tab}
1062
- {item.key !== '/' && (
1063
- <ItemMenu
1064
- info={item}
1065
- operateFun={this.operateFun}
1066
- listenRouterState={listenRouterState}
1067
- />
1068
- )}
1069
- </div>
1070
- );
1071
- };
1072
-
1073
- // 左侧菜单 route
1074
- const dataShowRoute = this.props.routes.find(
1075
- (route) => route.path === '/homePage/data-show',
1076
- ); // 添加数据大屏
1077
- const { route, ...restPrpos } = this.props;
1078
- const exist = route.routes.find(
1079
- (route) => route.path === '/homePage/data-show',
1080
- );
1081
- if (dataShowRoute && !exist) {
1082
- route.routes.splice(1, 0, dataShowRoute);
1083
- }
1084
-
1085
- const menu = (
1086
- <Menu>
1087
- <Menu.Item
1088
- key="0"
1089
- style={{
1090
- background: '#FFFFFF',
1091
- color: '#848484',
1092
- fontSize: '12px',
1093
- textAlign: 'center',
1094
- }}
1095
- >
1096
- <div>已打开的页签数: {listenRouterState.length}</div>
1097
- </Menu.Item>
1098
- <Menu.Item key="1" style={{ fontSize: '12px', textAlign: 'center' }}>
1099
- <a
1100
- onClick={() => {
1101
- // 关闭全部
1102
- this.updateState(
1103
- [
1104
- {
1105
- ...this.state.homeRouter,
1106
- key: '/',
1107
- tab: '欢迎',
1108
- closable: false,
1109
- },
1110
- ],
1111
- ['/'],
1112
- () => {
1113
- history.push('/');
1114
- },
1115
- );
1116
- }}
1117
- >
1118
- 关闭全部标签
1119
- </a>
1120
- </Menu.Item>
1121
- <Menu.Item key="2" style={{ fontSize: '12px', textAlign: 'center' }}>
1122
- <a
1123
- onClick={() => {
1124
- if (activeKey === '/') return;
1125
- const index = listenRouterState.findIndex(
1126
- (item) => item.key === activeKey,
1127
- );
1128
- let newActiveKey = '';
1129
- if (index > 0) {
1130
- newActiveKey = listenRouterState[index - 1].key;
1131
- } else {
1132
- newActiveKey = listenRouterState[1].key;
1133
- }
1134
- this.updateState(
1135
- listenRouterState.filter((d) => d.key !== activeKey),
1136
- listenRouterKey.filter((d) => d !== activeKey),
1137
- () => {
1138
- let newKey = encodeUrlQuery(newActiveKey);
1139
- history.push({
1140
- pathname: newKey,
1141
- });
1142
- },
1143
- );
1144
- }}
1145
- >
1146
- 关闭当前标签
1147
- </a>
1148
- </Menu.Item>
1149
- <Menu.Item key="3" style={{ fontSize: '12px', textAlign: 'center' }}>
1150
- <a
1151
- onClick={() => {
1152
- const index = listenRouterState.findIndex(
1153
- (item) => item.key === activeKey,
1154
- );
1155
- // let deleteKey = listenRouterState[index - 1]?.key;
1156
- // if (deleteKey === '/') {
1157
- // message.warning('首页不可关闭。');
1158
- // return;
1159
- // }
1160
-
1161
- this.updateState(
1162
- listenRouterState.filter(
1163
- (d: any, i: number) => i >= index || d.key === '/',
1164
- ),
1165
- listenRouterKey.filter(
1166
- (d: any, i: number) => i >= index || d === '/',
1167
- ),
1168
- );
1169
- }}
1170
- >
1171
- 关闭其左侧标签
1172
- </a>
1173
- </Menu.Item>
1174
- <Menu.Item key="4" style={{ fontSize: '12px', textAlign: 'center' }}>
1175
- <a
1176
- onClick={() => {
1177
- let index = listenRouterState.findIndex(
1178
- (item) => item.key === activeKey,
1179
- );
1180
- this.updateState(
1181
- listenRouterState.filter(
1182
- (d: any, i: number) => i <= index || d.key === '/',
1183
- ),
1184
- listenRouterKey.filter(
1185
- (d: any, i: number) => i <= index || d === '/',
1186
- ),
1187
- );
1188
- }}
1189
- >
1190
- 关闭其右侧标签
1191
- </a>
1192
- </Menu.Item>
1193
- </Menu>
1194
- );
1195
-
1196
- const filterByMenuDate = (
1197
- data: MenuDataItem[],
1198
- keyWord: string,
1199
- ): MenuDataItem[] =>
1200
- data
1201
- .map((item) => {
1202
- if (item.name && item.name.includes(keyWord)) {
1203
- return {
1204
- ...item,
1205
- };
1206
- }
1207
- return undefined;
1208
- })
1209
- .filter((item) => item) as MenuDataItem[];
1210
-
1211
- let weiqianduanProps = {};
1212
- let isWeiqianduan = false;
1213
-
1214
- if (window.top != window) {
1215
- isWeiqianduan = true;
1216
- weiqianduanProps = {
1217
- headerRender: false,
1218
- footerRender: false,
1219
- menuRender: false,
1220
- menuHeaderRender: false,
1221
- menuExtraRender: false,
1222
- };
1223
- }
1224
-
1225
- const OperationsSlot: Record<PositionType, React.ReactNode> = {
1226
- left: (
1227
- <div className={'tab_left_operate'}>
1228
- <div
1229
- onClick={() => {
1230
- history.push({
1231
- pathname: '/',
1232
- });
1233
- }}
1234
- >
1235
- <HomeOutlined />
1236
- </div>
1237
- <div
1238
- style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1239
- onClick={() => {
1240
- this.setTabNavTransLate(-100);
1241
- }}
1242
- >
1243
- <DoubleLeftOutlined />
1244
- </div>
1245
- </div>
1246
- ),
1247
- right: (
1248
- <div
1249
- style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1250
- className={'tab_right_operate'}
1251
- onClick={() => {
1252
- this.setTabNavTransLate(100);
1253
- }}
1254
- >
1255
- <DoubleRightOutlined />
1256
- </div>
1257
- ),
1258
- };
1259
-
1260
- return (
1261
- <ProLayout
1262
- actionRef={this.actionRef}
1263
- onMenuHeaderClick={() => history.push('/')}
1264
- menuHeaderRender={({ }) => (
1265
- <CustomerMenuHeader
1266
- originRoutes={originRoutes}
1267
- itemPath={itemPath}
1268
- handleClose={this.handleClose}
1269
- collapsed={collapse}
1270
- />
1271
- )}
1272
- menuExtraRender={() => {
1273
- if (!collapse) {
1274
- return (
1275
- <div>
1276
- <CustomerMenu
1277
- originRoutes={originRoutes}
1278
- itemPath={itemPath}
1279
- ref={this.customerMenuRef}
1280
- actionRef={this.actionRef}
1281
- handleClose={this.handleClose}
1282
- isCollapse={this.state.collapse}
1283
- />
1284
- </div>
1285
- );
1286
- }
1287
- return (
1288
- <div className="collapse_icon_close">
1289
- <span
1290
- className="collapse_icon"
1291
- onClick={() => {
1292
- this.setState({
1293
- collapse: !collapse,
1294
- });
1295
- }}
1296
- >
1297
- <MenuUnfoldOutlined />
1298
- </span>
1299
- </div>
1300
- );
1301
- }}
1302
- menuProps={{
1303
- onClick: () => {
1304
- localStorage.setItem('isMenuClick', 'true');
1305
- },
1306
- }}
1307
- collapsed={collapse}
1308
- onCollapse={(boo: boolean) => {
1309
- this.setState({
1310
- collapse: boo,
1311
- });
1312
- }}
1313
- menuItemRender={(menuItemProps, defaultDom) => {
1314
- if (menuItemProps?.path === '/') {
1315
- return (
1316
- <>
1317
- <div className="one_menu_wrap">
1318
- <Link
1319
- onClick={() => {
1320
- localStorage.setItem('isMenuClick', 'true');
1321
- }}
1322
- to={menuItemProps.path}
1323
- >
1324
- {defaultDom}
1325
- </Link>
1326
- </div>
1327
- </>
1328
- );
1329
- }
1330
- return (
1331
- <Link
1332
- onClick={() => {
1333
- localStorage.setItem('isMenuClick', 'true');
1334
- }}
1335
- to={menuItemProps.path}
1336
- >
1337
- {defaultDom}
1338
- </Link>
1339
- );
1340
- }}
1341
- subMenuItemRender={(menuItemProps, defaultDom) => {
1342
- return (
1343
- <div
1344
- style={{
1345
- height: '40px',
1346
- lineHeight: '40px',
1347
- position: 'relative',
1348
- overflow: 'hidden',
1349
- textOverflow: 'ellipsis',
1350
- whiteSpace: 'nowrap',
1351
- boxSizing: 'border-box',
1352
- paddingRight: '10px',
1353
- }}
1354
- onMouseEnter={() => {
1355
- if (
1356
- menuItemProps.pro_layout_parentKeys &&
1357
- menuItemProps.pro_layout_parentKeys.length
1358
- )
1359
- return;
1360
- this.setState({
1361
- currentSubMenuData: menuItemProps.children,
1362
- currentSubPath: menuItemProps.path,
1363
- });
1364
- this.setShowMenu(true);
1365
- }}
1366
- onMouseLeave={() => {
1367
- this.setShowMenu(false);
1368
- }}
1369
- >
1370
- {defaultDom}
1371
- {showSubMenu &&
1372
- currentSubPath === menuItemProps.path &&
1373
- !collapse && (
1374
- <CaretLeftOutlined
1375
- style={{ position: 'absolute', top: '14px', right: '-4px' }}
1376
- />
1377
- )}
1378
- </div>
1379
- );
1380
- }}
1381
- collapsedButtonRender={() => {
1382
- return (
1383
- <div
1384
- onClick={(e) => {
1385
- e.stopPropagation();
1386
- }}
1387
- className="banquan"
1388
- >
1389
- {''}
1390
- </div>
1391
- );
1392
- }}
1393
- postMenuData={(menus) => {
1394
- return [...filterByMenuDate(menus || [], this.state.keyWord)];
1395
- }}
1396
- links={[
1397
- !this.state.collapse ? (
1398
- <AllFunc
1399
- ref={this.allFunc}
1400
- itemPath={itemPath}
1401
- handleClose={this.handleClose}
1402
- isCollapse={this.state.collapse}
1403
- />
1404
- ) : (
1405
- ''
1406
- ),
1407
- ]}
1408
- onPageChange={() => {
1409
- const { location } = history;
1410
- // 如果没有登录,重定向到 login
1411
- if (
1412
- !localStorage.getItem(ENUM.BROWSER_CACHE.USER_INFO) &&
1413
- location.pathname !== '/user/login'
1414
- ) {
1415
- history.push('/user/login');
1416
- }
1417
- }}
1418
- headerRender={(props) => <GlobalHeaderCom {...props} />}
1419
- menu={{
1420
- request: async () => {
1421
- return JSON.parse(
1422
- localStorage.getItem(`customerMenu_${itemPath}_front`) || '[]',
1423
- );
1424
- },
1425
- type: 'group',
1426
- }}
1427
- route={route}
1428
- {...restPrpos}
1429
- {...defaultSettings}
1430
- {...weiqianduanProps}
1431
- >
1432
- <div id="globalTabsContent" className="globalTabs">
1433
- <DraggableTabs
1434
- activeKey={activeKey}
1435
- id="globalTabs"
1436
- onChange={this.onChange}
1437
- // tabBarExtraContent={operations}
1438
- type="editable-card"
1439
- tabBarStyle={{
1440
- background: '#f3f3f3',
1441
- height: '28px',
1442
- marginRight: 0,
1443
- fontSize: '12px',
1444
- color: '#2C2F2E70',
1445
- marginBottom: '-2px',
1446
- position: 'fixed',
1447
- top: 50,
1448
- zIndex: 10,
1449
- width: collapse ? 'calc(100% - 75px)' : 'calc(100% - 167px)',
1450
- display: isWeiqianduan ? 'none' : 'flex',
1451
- }}
1452
- tabPosition="top"
1453
- tabBarGutter={8}
1454
- onEdit={this.onEdit}
1455
- tabBarExtraContent={OperationsSlot}
1456
- animated={false}
1457
- hideAdd
1458
- >
1459
- {listenRouterState.map((item, index) => (
1460
- <TabPane
1461
- tab={
1462
- <TabTitle
1463
- item={item}
1464
- index={index}
1465
- updateState={this.updateState}
1466
- />
1467
- }
1468
- style={{ marginTop: isWeiqianduan ? 0 : 30 }}
1469
- key={item.key}
1470
- closable={item.key !== '/'}
1471
- closeIcon={<img src="./biaoqian-guanbi-icon.svg" />}
1472
- >
1473
- <WrapperComponent
1474
- item={item}
1475
- routerProps={this.props}
1476
- getDictionarySource={this.getDictionarySource}
1477
- getDictionaryTextByValue={this.getDictionaryTextByValue}
1478
- timeFormat={this.timeFormat}
1479
- transparentProps={transparentProps}
1480
- />
1481
- </TabPane>
1482
- ))}
1483
- </DraggableTabs>
1484
- <div
1485
- className="globalTabsOper"
1486
- style={{
1487
- position: 'fixed',
1488
- top: '50px',
1489
- zIndex: 10,
1490
- background: '#fff',
1491
- display: isWeiqianduan ? 'none' : 'block',
1492
- borderLeft: '1px solid #E4E4E4',
1493
- }}
1494
- >
1495
- <Dropdown overlay={menu} trigger={['click']}>
1496
- <a
1497
- className="ant-dropdown-link"
1498
- onClick={(e) => e.preventDefault()}
1499
- >
1500
- <DashOutlined />
1501
- </a>
1502
- </Dropdown>
1503
- </div>
1504
- <SearchFunc itemPath={itemPath} {...drawerLeftParams}></SearchFunc>
1505
- <div
1506
- onMouseEnter={() => {
1507
- this.setShowMenu(true);
1508
- }}
1509
- onMouseLeave={() => {
1510
- this.setShowMenu(false);
1511
- }}
1512
- className={'sub_menu_content'}
1513
- style={{ display: showSubMenu && !collapse ? 'block' : 'none' }}
1514
- >
1515
- {this.getMenuDom(currentSubMenuData)}
1516
- </div>
1517
- </div>
1518
- </ProLayout>
1519
- );
1520
- }
1521
- }
1522
-
1523
- class WrapperComponent extends React.Component {
1524
- constructor(props) {
1525
- super(props);
1526
- }
1527
-
1528
- shouldComponentUpdate(nextProps) {
1529
- if (window.__POWERED_BY_WUJIE__ && nextProps?.item?.key?.indexOf('edit-template-template') > -1) { // 适配wujie环境主应用下渲染打印编辑器
1530
- return true
1531
- }
1532
- return false;
1533
- }
1534
- render() {
1535
- const {
1536
- item,
1537
- routerProps,
1538
- getDictionarySource,
1539
- getDictionaryTextByValue,
1540
- timeFormat,
1541
- transparentProps,
1542
- } = this.props;
1543
- return (
1544
- <>
1545
- {item.isNotFound ? ( <NoFoundPage />) :
1546
- React.createElement(item.content, {
1547
- getDictionarySource: getDictionarySource,
1548
- getDictionaryTextByValue: getDictionaryTextByValue,
1549
- timeFormat: timeFormat,
1550
- ...routerProps,
1551
- ...transparentProps,
1552
- match: item.match,
1553
- })}
1554
- </>
1555
- );
1556
- }
1557
- }
1558
-
1559
- export default (props) => {
1560
- const { initialState = {} } = useModel('@@initialState');
1561
-
1562
- const { dictionaryData } = initialState;
1563
- const intl = useIntl();
1564
- const { formatMessage } = intl;
1565
- return (
1566
- <BasicLayout
1567
- {...props}
1568
- dictionaryData={dictionaryData}
1569
- formatMessage={formatMessage}
1570
- />
1571
- );
1572
- };
1
+ // @ts-nocheck
2
+ import type {
3
+ MenuDataItem,
4
+ BasicLayoutProps as ProLayoutProps,
5
+ Settings,
6
+ } from '@ant-design/pro-layout';
7
+ import ProLayout from '@ant-design/pro-layout';
8
+ import React, { useState, createRef, useRef } from 'react';
9
+ import {
10
+ Tabs,
11
+ Dropdown,
12
+ Menu,
13
+ } from 'antd';
14
+ import {
15
+ Link,
16
+ useIntl,
17
+ history,
18
+ useModel,
19
+ } from 'umi';
20
+ import {
21
+ DashOutlined,
22
+ MenuUnfoldOutlined,
23
+ CaretLeftOutlined,
24
+ HomeOutlined,
25
+ DoubleLeftOutlined,
26
+ DoubleRightOutlined,
27
+ } from '@ant-design/icons';
28
+ import SearchFunc from './Components/SearchFunc';
29
+ import { debounce } from 'lodash';
30
+
31
+ import AllFunc from './Components/AllFunc';
32
+ import {
33
+ getBreadcrumbNameMap,
34
+ ergodicMenuRoutes,
35
+ matchPath,
36
+ encodeUrlQuery,
37
+ } from './utils';
38
+ import moment from 'moment';
39
+ import GlobalHeaderCom from './Components/GlobalHeader';
40
+ import CustomerMenu from './Components/CustomerMenu';
41
+ import CustomerMenuHeader from './Components/CustomerMenu/globalMenu/customMenuHeader';
42
+ import './index.less';
43
+ import { DndProvider, useDrag, useDrop } from 'react-dnd';
44
+ import { HTML5Backend } from 'react-dnd-html5-backend';
45
+ import ENUM from '@/utils/enumConfig';
46
+ import { memoizeOneFormatter } from '@/utils/utils';
47
+ import Item from 'antd/lib/list/Item';
48
+
49
+ const { TabPane } = Tabs;
50
+
51
+ export const RouterContext = React.createContext({});
52
+
53
+ export type BasicLayoutProps = {
54
+ breadcrumbNameMap: Record<string, MenuDataItem>;
55
+ route: ProLayoutProps['route'] & {
56
+ authority: string[];
57
+ };
58
+ settings: Settings;
59
+ } & ProLayoutProps;
60
+
61
+ export type BasicLayoutContext = { [K in 'location']: BasicLayoutProps[K] } & {
62
+ breadcrumbNameMap: Record<string, MenuDataItem>;
63
+ };
64
+
65
+ const menuDataRender = (menuList: MenuDataItem[]): MenuDataItem[] =>
66
+ menuList.map((item) => {
67
+ return {
68
+ ...item,
69
+ children: item.children ? menuDataRender(item.children) : undefined,
70
+ };
71
+ });
72
+
73
+ let UN_LISTTEN_DRP;
74
+ let routerArray = [];
75
+ let lastTwoRouterArray = [1, 2];
76
+
77
+ let draggerTabKeys = [];
78
+
79
+ const type = 'DraggableTabNode';
80
+ const DraggableTabNode = ({ index, children, moveNode }) => {
81
+ const ref = useRef(null);
82
+ const [{ isOver, dropClassName }, drop] = useDrop({
83
+ accept: type,
84
+ collect: (monitor) => {
85
+ const { index: dragIndex } = monitor.getItem() || {};
86
+
87
+ if (dragIndex === index) {
88
+ return {};
89
+ }
90
+
91
+ return {
92
+ isOver: monitor.isOver(),
93
+ dropClassName: 'dropping',
94
+ };
95
+ },
96
+ drop: (item) => {
97
+ moveNode(item.index, index);
98
+ },
99
+ });
100
+ const [, drag] = useDrag({
101
+ type,
102
+ item: {
103
+ index,
104
+ },
105
+ collect: (monitor) => ({
106
+ isDragging: monitor.isDragging(),
107
+ }),
108
+ });
109
+ drop(drag(ref));
110
+ return (
111
+ <div
112
+ ref={ref}
113
+ style={{
114
+ marginRight: 24,
115
+ }}
116
+ className={isOver ? dropClassName : ''}
117
+ >
118
+ {children}
119
+ </div>
120
+ );
121
+ };
122
+
123
+ const DraggableTabs = (props) => {
124
+ const { children, changeListenRouterState } = props;
125
+ const [order, setOrder] = useState([]);
126
+
127
+ const moveTabNode = (dragKey, hoverKey) => {
128
+ const newOrder = order.slice();
129
+ React.Children.forEach(children, (c) => {
130
+ if (c.key && newOrder.indexOf(c.key) === -1) {
131
+ newOrder.push(c.key);
132
+ }
133
+ });
134
+ const dragIndex = newOrder.indexOf(dragKey);
135
+ const hoverIndex = newOrder.indexOf(hoverKey);
136
+ newOrder.splice(dragIndex, 1);
137
+ newOrder.splice(hoverIndex, 0, dragKey);
138
+ changeListenRouterState(dragIndex, hoverIndex);
139
+ setOrder(newOrder);
140
+ };
141
+
142
+ const renderTabBar = (tabBarProps, DefaultTabBar) => (
143
+ <DefaultTabBar {...tabBarProps}>
144
+ {(node) => (
145
+ <DraggableTabNode
146
+ key={node.key}
147
+ index={node.key}
148
+ moveNode={moveTabNode}
149
+ >
150
+ {node}
151
+ </DraggableTabNode>
152
+ )}
153
+ </DefaultTabBar>
154
+ );
155
+
156
+ const tabs = [];
157
+ React.Children.forEach(children, (c) => {
158
+ tabs.push(c);
159
+ });
160
+ const orderTabs = tabs.slice().sort((a, b) => {
161
+ const orderA = order.indexOf(a.key);
162
+ const orderB = order.indexOf(b.key);
163
+
164
+ if (orderA !== -1 && orderB !== -1) {
165
+ return orderA - orderB;
166
+ }
167
+
168
+ if (orderA !== -1) {
169
+ return -1;
170
+ }
171
+
172
+ if (orderB !== -1) {
173
+ return 1;
174
+ }
175
+
176
+ const ia = tabs.indexOf(a);
177
+ const ib = tabs.indexOf(b);
178
+ return ia - ib;
179
+ });
180
+ return (
181
+ <DndProvider backend={HTML5Backend}>
182
+ <Tabs renderTabBar={renderTabBar} {...props}>
183
+ {orderTabs}
184
+ </Tabs>
185
+ </DndProvider>
186
+ );
187
+ };
188
+
189
+ const ItemMenu = (props) => {
190
+ const {
191
+ info: { key },
192
+ operateFun,
193
+ listenRouterState,
194
+ } = props;
195
+ let index = listenRouterState.findIndex((item) => item.key === key);
196
+
197
+ const menu = (
198
+ <Menu>
199
+ <Menu.Item key="0" style={{ fontSize: '12px', textAlign: 'center' }}>
200
+ <a
201
+ onClick={(e) => {
202
+ e.stopPropagation();
203
+ operateFun(key, 'self');
204
+ }}
205
+ >
206
+ 关闭当前标签
207
+ </a>
208
+ </Menu.Item>
209
+ <Menu.Item
210
+ disabled={index === 0}
211
+ key="1"
212
+ style={{ fontSize: '12px', textAlign: 'center' }}
213
+ >
214
+ <a
215
+ onClick={(e) => {
216
+ e.stopPropagation();
217
+ operateFun(key, 'left');
218
+ }}
219
+ >
220
+ 关闭其左侧标签
221
+ </a>
222
+ </Menu.Item>
223
+ <Menu.Item
224
+ disabled={index === listenRouterState.length - 1}
225
+ key="2"
226
+ style={{ fontSize: '12px', textAlign: 'center' }}
227
+ >
228
+ <a
229
+ onClick={(e) => {
230
+ e.stopPropagation();
231
+ operateFun(key, 'right');
232
+ }}
233
+ >
234
+ 关闭其右侧标签
235
+ </a>
236
+ </Menu.Item>
237
+ <Menu.Item
238
+ disabled={index === listenRouterState.length - 1}
239
+ key="3"
240
+ style={{ fontSize: '12px', textAlign: 'center' }}
241
+ >
242
+ <a
243
+ onClick={(e) => {
244
+ e.stopPropagation();
245
+ operateFun(key, 'other');
246
+ }}
247
+ >
248
+ 关闭其他标签
249
+ </a>
250
+ </Menu.Item>
251
+ <Menu.Item
252
+ disabled={index === listenRouterState.length - 1}
253
+ key="4"
254
+ style={{ fontSize: '12px', textAlign: 'center' }}
255
+ >
256
+ <a
257
+ onClick={(e) => {
258
+ e.stopPropagation();
259
+ operateFun(key, 'all');
260
+ }}
261
+ >
262
+ 关闭全部标签
263
+ </a>
264
+ </Menu.Item>
265
+ </Menu>
266
+ );
267
+ return (
268
+ <Dropdown overlay={menu} trigger={['hover']}>
269
+ <a
270
+ className="ant-dropdown-link"
271
+ onClick={(e) => {
272
+ e.preventDefault();
273
+ e.stopPropagation();
274
+ }}
275
+ >
276
+ <img style={{ marginRight: '-12px' }} src="./biaoqian-icon.svg" />
277
+ </a>
278
+ </Dropdown>
279
+ );
280
+ };
281
+
282
+ class BasicLayout extends React.PureComponent {
283
+ allFunc: any = createRef('');
284
+ customerMenuRef: any = createRef('');
285
+ actionRef: any = createRef<{
286
+ reload: () => void;
287
+ }>();
288
+ constructor(props) {
289
+ super(props);
290
+ routerArray = this.updateTree(props.route.routes);
291
+ const homeRouter = routerArray.filter(
292
+ (itemroute) => itemroute.key === '/',
293
+ )[0];
294
+ const breadcrumbNameMap = getBreadcrumbNameMap(
295
+ memoizeOneFormatter(props.route.routes, ''),
296
+ );
297
+ const hideMenuArray = ergodicMenuRoutes(props.route.routes);
298
+
299
+ this.state = {
300
+ listenRouterState: [
301
+ { ...homeRouter, key: '/', tab: '欢迎', closable: false },
302
+ ],
303
+ listenRouterKey: ['/'],
304
+ activeKey: '/',
305
+ homeRouter,
306
+ customerMatchs: [],
307
+ breadcrumbNameMap,
308
+ hideMenuArray,
309
+ keyWord: '',
310
+ collapse: false,
311
+ drawerLeftParams: {
312
+ visible: false,
313
+ width: 690,
314
+ title: '搜索',
315
+ onClose: () => {
316
+ this.setState({
317
+ drawerLeftParams: {
318
+ ...this.state.drawerLeftParams,
319
+ visible: false,
320
+ },
321
+ });
322
+ },
323
+ },
324
+ currentSubMenuData: [],
325
+ showSubMenu: false,
326
+ isSlider: false,
327
+ };
328
+ }
329
+
330
+ componentDidMount() {
331
+ const {
332
+ history,
333
+ location,
334
+ itemPath,
335
+ pathToRegexp,
336
+ } = this.props;
337
+
338
+ let istParent = 0;
339
+
340
+ var self = this;
341
+
342
+ // window.top != window &&
343
+ // window.addEventListener('message', function (e) {
344
+ // istParent = 1;
345
+ // if (localStorage.getItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK)) {
346
+ // localStorage.removeItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK);
347
+ // } else {
348
+ // localStorage.setItem('isTabChange', true);
349
+ // }
350
+
351
+ // if (typeof e.data === 'string') {
352
+ // let newKey = encodeUrlQuery(e.data.replace(/^\/\w+\//, '/'));
353
+ // history.push(newKey);
354
+ // } else {
355
+ // const info = e.data;
356
+ // if (info.type === 'remove') {
357
+ // self.tabActions['remove'](info.key.replace(/^\/\w+\//, '/'));
358
+ // }
359
+ // }
360
+ // });
361
+
362
+ window.$wujie?.bus.$on("main-route-change", function (appname, info) {
363
+ if (appname === itemPath) {
364
+ if (localStorage.getItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK)) {
365
+ localStorage.removeItem(ENUM.BROWSER_CACHE.CHILD_APP_BACK);
366
+ } else {
367
+ localStorage.setItem('isTabChange', true);
368
+ }
369
+ istParent = 1;
370
+ if (info.type === 'main') {
371
+ let newPath = encodeUrlQuery(info.path);
372
+ history.push(newPath)
373
+ }
374
+ if (info.type === 'remove') {
375
+ self.tabActions['remove'](info.path);
376
+ }
377
+ }
378
+ });
379
+
380
+ UN_LISTTEN_DRP = history.listen((route) => {
381
+ // if ((window as any).__POWERED_BY_QIANKUN__) {
382
+ // if (window.location.href.indexOf(`/${itemPath}`) === -1) return;
383
+ // }
384
+ if (route.pathname.startsWith(`/${itemPath}/`)) return;
385
+ const {
386
+ listenRouterState,
387
+ listenRouterKey,
388
+ customerMatchs,
389
+ hideMenuArray,
390
+ } = this.state;
391
+ let newListenRouterState = [...listenRouterState];
392
+ let newListenRouterKey = [...listenRouterKey];
393
+
394
+ let replaceRouter = routerArray.filter((itemRoute) =>
395
+ pathToRegexp(itemRoute.key || '').test(route.pathname),
396
+ )[0];
397
+
398
+ let currentKey = '';
399
+
400
+ if (replaceRouter && replaceRouter.isOnlyOnePage) {
401
+ // 处理中英文和特殊字符
402
+ currentKey = decodeURIComponent(route.pathname);
403
+ } else {
404
+ currentKey = decodeURIComponent(
405
+ route.pathname + this.parseQueryString(route.search),
406
+ );
407
+ }
408
+
409
+ if (!istParent) {
410
+ if (route.pathname === '/') return;
411
+ window.$wujie?.bus.$emit('sub-route-change', itemPath, currentKey);
412
+ // window.parent.postMessage(`/parent/${itemPath}${currentKey}`, '*');
413
+ }
414
+
415
+ // 防止出错
416
+ if (listenRouterKey.length !== listenRouterState.length) {
417
+ listenRouterState.forEach((item, index) => {
418
+ listenRouterKey[index] = item.key;
419
+ });
420
+ }
421
+
422
+ if (!listenRouterKey.includes(currentKey)) {
423
+ if (!replaceRouter) {
424
+ replaceRouter = routerArray.filter(
425
+ (itemroute) => itemroute.key === '/404',
426
+ )?.[0];
427
+
428
+ this.setState(
429
+ {
430
+ listenRouterState: [
431
+ ...listenRouterState,
432
+ { ...replaceRouter, key: currentKey, tab: '404' },
433
+ ],
434
+ activeKey: currentKey,
435
+ listenRouterKey: [...listenRouterKey, currentKey],
436
+ },
437
+ () => {
438
+ this.checkisNavSlide();
439
+ },
440
+ );
441
+ } else {
442
+ const match = matchPath(route.pathname, { path: replaceRouter.key }, pathToRegexp);
443
+ newListenRouterState = [
444
+ ...newListenRouterState,
445
+ {
446
+ ...replaceRouter,
447
+ query: route.query,
448
+ match: match,
449
+ key: currentKey,
450
+ tab: this.getPageTitle(route.pathname) + '',
451
+ },
452
+ ];
453
+ newListenRouterKey = [...listenRouterKey, currentKey];
454
+ }
455
+ }
456
+
457
+ // 处理hideMenu页面自动关闭
458
+ lastTwoRouterArray.push(route.pathname);
459
+ lastTwoRouterArray.shift();
460
+ if (
461
+ !localStorage.getItem('isTabChange') &&
462
+ !localStorage.getItem('isMenuClick')
463
+ ) {
464
+ if (
465
+ lastTwoRouterArray[0] &&
466
+ typeof lastTwoRouterArray[0] === 'string'
467
+ ) {
468
+ let needRemoveKeyArray = hideMenuArray.filter((itemRoute) =>
469
+ pathToRegexp(itemRoute.path || '').test(lastTwoRouterArray[0]),
470
+ );
471
+ // lastTwoRouterArray[0] != lastTwoRouterArray[1] 该判断条件用于判断是否是tab删除操作,如果是tab页删除操作,删除的是不是最后一个打开的tab页,执行history.push会导致错误的将最后打开的那个tab页也删除掉
472
+ if (
473
+ needRemoveKeyArray.length &&
474
+ lastTwoRouterArray[0] != lastTwoRouterArray[1] && !route.state?.thisHideInMenuDoNotClose
475
+ ) {
476
+ newListenRouterState = newListenRouterState.filter((item) => {
477
+ const [pathname] = item.key ? item.key.split('?') : [];
478
+ return pathname && pathname !== lastTwoRouterArray[0];
479
+ });
480
+ newListenRouterKey = newListenRouterKey.filter((item) => {
481
+ const [pathname] = item ? item.split('?') : [];
482
+ return pathname && pathname !== lastTwoRouterArray[0];
483
+ });
484
+ }
485
+ }
486
+ // refs?.tableRef?.current?.refreshTable();
487
+ } else {
488
+ setTimeout(() => {
489
+ // 处理页面刷新两面
490
+ localStorage.removeItem('isTabChange');
491
+ localStorage.removeItem('isMenuClick');
492
+ }, 0);
493
+ }
494
+ this.setState(
495
+ {
496
+ //路由监听函数最后执行setState,避免处理hideMenu类型页面自动关闭的逻辑块内获取不到最新state的listenRouterState和listenRouterKey
497
+ activeKey: currentKey,
498
+ listenRouterState: newListenRouterState,
499
+ listenRouterKey: newListenRouterKey,
500
+ },
501
+ () => {
502
+ this.checkisNavSlide();
503
+ },
504
+ );
505
+
506
+ istParent = 0;
507
+ });
508
+
509
+ if ( localStorage.getItem('mainRoutePath') && localStorage.getItem('mainRoutePath')?.startsWith(`/${itemPath}/`)) {
510
+ istParent = 1;
511
+ history.push(localStorage.getItem('mainRoutePath').replace(/^\/\w+\//, '/'))
512
+ } else if (localStorage.getItem('firstPage') && localStorage.getItem('firstPage')?.startsWith(`#/${itemPath}/`)) {
513
+ // 暂时保留,兼容老版本
514
+ istParent = 1;
515
+ history.push(
516
+ localStorage
517
+ .getItem('firstPage')
518
+ ?.slice(1)
519
+ .replace(/^\/\w+\//, '/'),
520
+ );
521
+ } else {
522
+ history.push(location);
523
+ }
524
+ }
525
+
526
+ componentWillUnmount() {
527
+ // eslint-disable-next-line no-unused-expressions
528
+ UN_LISTTEN_DRP && UN_LISTTEN_DRP();
529
+ }
530
+
531
+ parseQueryString = (queryString) => {
532
+ if (!queryString) {
533
+ return '';
534
+ }
535
+
536
+ if (queryString.indexOf('?') < 0) {
537
+ return `?${queryString}`;
538
+ }
539
+
540
+ return queryString;
541
+ };
542
+
543
+ updateTree = (Tree) => {
544
+ const treeData = Tree;
545
+ const treeList = [];
546
+ // 递归获取树列表
547
+ const getTreeList = (data) => {
548
+ data.forEach((node) => {
549
+ if (node.routes && node.routes.length > 0) {
550
+ getTreeList(node.routes);
551
+ } else {
552
+ treeList.push({
553
+ tab: node.locale,
554
+ key: node.path,
555
+ locale: node.locale,
556
+ closable: true,
557
+ content: node.component,
558
+ name: node.name,
559
+ hideInMenu: node.hideInMenu,
560
+ isOnlyOnePage: node.isOnlyOnePage,
561
+ });
562
+ }
563
+ });
564
+ };
565
+ getTreeList(treeData);
566
+ return treeList;
567
+ };
568
+
569
+ getDictionarySource = (dicCode: string, needConvertInterger = false) => {
570
+ const { dictionaryData } = this.props;
571
+
572
+ let dicData = {};
573
+
574
+ if (!dictionaryData) {
575
+ let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
576
+ ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
577
+ : {};
578
+ dicData = storageDic[dicCode];
579
+ } else {
580
+ dicData = dictionaryData[dicCode];
581
+ }
582
+ // if (!dicData || !dicData.length) {
583
+ // throw new Error(`当前没有${dicCode}字典值`);
584
+ // }
585
+
586
+ try {
587
+ if (needConvertInterger) {
588
+ dicData = dicData.map((item: { text: string; value: string }) => ({
589
+ ...item,
590
+ value: parseFloat(item.value),
591
+ }));
592
+ }
593
+ } catch (e) { }
594
+
595
+ return dicData;
596
+ };
597
+
598
+ getDictionaryTextByValue = (dicCode: string, value: string) => {
599
+ let dicData = [];
600
+ let dictionaryData: any;
601
+ if (!dictionaryData) {
602
+ let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
603
+ ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
604
+ : {};
605
+ dicData = storageDic[dicCode];
606
+ } else {
607
+ dicData = dictionaryData[dicCode];
608
+ }
609
+
610
+ if (!dicData || !dicData.length) {
611
+ // throw new Error(`当前没有${dicCode}字典值`);
612
+ }
613
+
614
+ if (value === undefined) return '- -';
615
+
616
+ const dicItemArray = dicData?.filter(
617
+ (item: { value: string }) => item.value === value.toString(),
618
+ );
619
+
620
+ if (!dicItemArray?.length) {
621
+ // throw new Error(`当前${dicCode}字典值合没有${value}的数据`)
622
+ return value;
623
+ }
624
+
625
+ return dicItemArray[0].text;
626
+ };
627
+
628
+ timeFormat = (timeStr, format, notNeedConvertTimeZone) => {
629
+ if (!timeStr) return '- -';
630
+
631
+ if (notNeedConvertTimeZone) {
632
+ return moment(timeStr).format(format);
633
+ }
634
+
635
+ return moment(timeStr).add(8, 'hours').format(format) || '- -';
636
+ };
637
+
638
+ onChange = (key) => {
639
+ // console.log('onChange');
640
+ if (key !== this.state.activeKey) {
641
+ this.setState({
642
+ activeKey: key,
643
+ });
644
+ localStorage.setItem('isTabChange', '1');
645
+ let newKey = encodeUrlQuery(key);
646
+ history.push(newKey);
647
+ }
648
+ };
649
+
650
+ getPageTitle = (pathname) => {
651
+ const { formatMessage } = this.props;
652
+ const { breadcrumbNameMap } = this.state;
653
+ const currRouterData = this.matchParamsPath(pathname, breadcrumbNameMap);
654
+
655
+ if (!currRouterData) {
656
+ return '';
657
+ }
658
+ const pageName = formatMessage({
659
+ id: currRouterData.locale || currRouterData.name,
660
+ defaultMessage: currRouterData.name,
661
+ });
662
+
663
+ return `${pageName}`;
664
+ };
665
+
666
+ matchParamsPath = (pathname, breadcrumbNameMap) => {
667
+ const { pathToRegexp } = this.props;
668
+ const pathKey = Object.keys(breadcrumbNameMap).find((key) =>
669
+ pathToRegexp(key).test(pathname),
670
+ );
671
+ return breadcrumbNameMap[pathKey];
672
+ };
673
+
674
+ onEdit = (
675
+ targetKey: React.MouseEvent | React.KeyboardEvent | string,
676
+ action: string,
677
+ ) => {
678
+ this.tabActions[action](targetKey);
679
+ };
680
+
681
+ tabActions: any = {
682
+ remove: (targetKey: string) => {
683
+ const { listenRouterState, activeKey, customerMatchs, listenRouterKey } =
684
+ this.state;
685
+
686
+ let lastIndex: number = 0;
687
+ let newActiveKey: string | undefined = activeKey;
688
+ let newListenRouterState = [];
689
+ let newListenRouterKey = [];
690
+
691
+ if (targetKey === activeKey) {
692
+ listenRouterState.forEach((pane, i) => {
693
+ if (pane.key === targetKey) {
694
+ lastIndex = i - 1;
695
+ }
696
+ });
697
+
698
+ newListenRouterState = listenRouterState.filter(
699
+ (item) => item.key !== targetKey,
700
+ );
701
+ newListenRouterKey = listenRouterKey.filter(
702
+ (item) => item !== targetKey,
703
+ );
704
+
705
+ if (lastIndex < 0) {
706
+ lastIndex = 0;
707
+ }
708
+
709
+ newActiveKey = newListenRouterState[lastIndex].key;
710
+ } else {
711
+ newListenRouterState = listenRouterState.filter(
712
+ (item) => item.key !== targetKey,
713
+ );
714
+ newListenRouterKey = listenRouterKey.filter(
715
+ (item) => item !== targetKey,
716
+ );
717
+ }
718
+
719
+ this.setState(
720
+ {
721
+ activeKey: newActiveKey,
722
+ listenRouterState: newListenRouterState,
723
+ listenRouterKey: newListenRouterKey,
724
+ },
725
+ () => {
726
+ let newKey = encodeUrlQuery(newActiveKey);
727
+ history.push({
728
+ pathname: newKey,
729
+ });
730
+ this.checkisNavSlide();
731
+ },
732
+ );
733
+ },
734
+ };
735
+
736
+ updateState = (newListenRouterState, newListenRouterKey, cb) => {
737
+ this.setState(
738
+ {
739
+ listenRouterState: newListenRouterState,
740
+ listenRouterKey: newListenRouterKey,
741
+ },
742
+ () => {
743
+ this.checkisNavSlide();
744
+ if (cb) cb();
745
+ },
746
+ );
747
+ };
748
+
749
+ handleClose = () => {
750
+ this.setState({
751
+ drawerLeftParams: {
752
+ ...this.state.drawerLeftParams,
753
+ visible: false,
754
+ },
755
+ isCollapse: true,
756
+ });
757
+ this.allFunc.current?.close?.();
758
+ this.customerMenuRef.current?.close?.();
759
+ };
760
+
761
+ handleMenuClick = (item: any) => {
762
+ if (item.children || !item.component) return;
763
+ let newKey = encodeUrlQuery(item.path);
764
+ history.push({
765
+ pathname: newKey,
766
+ });
767
+ this.setShowMenu(false);
768
+ };
769
+
770
+ getMenuDom = (menuData) => {
771
+ return menuData.map((item) => (
772
+ <div>
773
+ <div
774
+ onClick={() => {
775
+ this.handleMenuClick(item);
776
+ }}
777
+ className={`${'menu_item'} ${item.children || !item.component ? '' : 'link_style'
778
+ }`}
779
+ style={{
780
+ fontWeight: item.children || !item.component ? 'bolder' : '400',
781
+ paddingLeft: '10px',
782
+ marginTop: item.children || !item.component ? '5px' : '0px',
783
+ fontSize: item.children || !item.component ? '14px' : '12px',
784
+ }}
785
+ >
786
+ {item.name}
787
+ </div>
788
+ {!!item.children &&
789
+ !!item.children.length &&
790
+ this.getMenuDom(item.children)}
791
+ </div>
792
+ ));
793
+ };
794
+
795
+ setShowMenu = debounce((isShow) => {
796
+ this.setState({
797
+ showSubMenu: isShow,
798
+ });
799
+ }, 500);
800
+
801
+ //设置tabs标签左右滚动
802
+ setTabNavTransLate = (num) => {
803
+ let globalTabsNav = document
804
+ .getElementById('globalTabs')
805
+ ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
806
+ let globalTabsNavWrap = document
807
+ .getElementById('globalTabs')
808
+ ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
809
+ let wrapWidth = globalTabsNavWrap.offsetWidth; //tabsNav父节点宽度
810
+ let navListWidth = globalTabsNav.offsetWidth; //tabsNav总宽度
811
+ if (navListWidth - wrapWidth <= 0) return;
812
+ let maxTransX = navListWidth - wrapWidth; // 允许移动最大宽度
813
+ let transXStr = document.defaultView?.getComputedStyle(
814
+ globalTabsNav,
815
+ null,
816
+ ).transform;
817
+ let transx = transXStr?.split(',')[4]; //当前translateX的值
818
+
819
+ let targetTransX = Math.abs(Number(transx)) + num;
820
+ if (targetTransX <= 0) targetTransX = 0;
821
+ if (targetTransX >= Number(maxTransX)) targetTransX = Number(maxTransX);
822
+ globalTabsNav.style.transform = 'translateX(-' + targetTransX + 'px)';
823
+ };
824
+
825
+ checkisNavSlide = () => {
826
+ if (window.top != window) return;
827
+ //监听tabs页签总长度判断是否可点击滑动
828
+ let globalTabsNav = document
829
+ .getElementById('globalTabs')
830
+ ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
831
+ let globalTabsNavWrap = document
832
+ .getElementById('globalTabs')
833
+ ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
834
+ let wrapWidth = globalTabsNavWrap?.offsetWidth; //tabsNav父节点宽度
835
+ let navListWidth = globalTabsNav?.offsetWidth; //tabsNav总宽度
836
+ if (navListWidth - wrapWidth <= 0) {
837
+ this.setState({
838
+ isSlider: false,
839
+ });
840
+ return;
841
+ }
842
+ this.setState({
843
+ isSlider: true,
844
+ });
845
+ };
846
+
847
+ changeListenRouterState = (dragIndex: number, hoverIndex: number) => {
848
+ const { listenRouterState, listenRouterKey } = this.state;
849
+ let dragItem = listenRouterState[dragIndex];
850
+ let dragKeyItem = listenRouterKey[dragIndex];
851
+
852
+ listenRouterState.splice(dragIndex, 1);
853
+ listenRouterState.splice(hoverIndex, 0, dragItem);
854
+
855
+ listenRouterKey.splice(dragIndex, 1);
856
+ listenRouterKey.splice(hoverIndex, 0, dragKeyItem);
857
+ };
858
+
859
+ operateFun = (key, type) => {
860
+ const { listenRouterState, activeKey, listenRouterKey } = this.state;
861
+ let deleteKey = '';
862
+ let newlistenRouterState = [];
863
+ let newlistenRouterKey = [];
864
+ let newActiveKey = '';
865
+ let deleteIndex = 0;
866
+ if (type === 'self') {
867
+ deleteIndex = listenRouterState.findIndex((item) => item.key === key);
868
+ deleteKey = key;
869
+ if (deleteIndex > 0) {
870
+ newActiveKey = listenRouterState[deleteIndex - 1].key;
871
+ } else {
872
+ newActiveKey = listenRouterState[1].key;
873
+ }
874
+ newlistenRouterState = listenRouterState.filter((d) => d.key !== key);
875
+ newlistenRouterKey = listenRouterKey.filter((d) => d !== key);
876
+ this.updateState(newlistenRouterState, newlistenRouterKey, () => {
877
+ if (deleteKey === activeKey) {
878
+ let newKey = encodeUrlQuery(newActiveKey);
879
+ history.push({
880
+ pathname: newKey,
881
+ });
882
+ }
883
+ });
884
+ }
885
+ if (type === 'left') {
886
+ const index = listenRouterState.findIndex((item) => item.key === key);
887
+ newlistenRouterState = listenRouterState.filter(
888
+ (d: any, i: number) => i >= index || d.key === '/',
889
+ );
890
+ newlistenRouterKey = listenRouterKey.filter(
891
+ (d: any, i: number) => i >= index || d === '/',
892
+ );
893
+ this.updateState(newlistenRouterState, newlistenRouterKey, () => {
894
+ if (newlistenRouterKey.find((item) => item === activeKey)) {
895
+ return;
896
+ } else {
897
+ let newKey = encodeUrlQuery(key);
898
+ history.push({
899
+ pathname: newKey,
900
+ });
901
+ }
902
+ });
903
+ }
904
+ if (type === 'right') {
905
+ const index = listenRouterState.findIndex((item) => item.key === key);
906
+ newlistenRouterState = listenRouterState.filter(
907
+ (d: any, i: number) => i <= index || d.key === '/',
908
+ );
909
+ newlistenRouterKey = listenRouterKey.filter(
910
+ (d: any, i: number) => i <= index || d === '/',
911
+ );
912
+ this.updateState(
913
+ listenRouterState.filter(
914
+ (d: any, i: number) => i <= index || d.key === '/',
915
+ ),
916
+ listenRouterKey.filter((d: any, i: number) => i <= index || d === '/'),
917
+ () => {
918
+ if (newlistenRouterKey.find((item) => item === activeKey)) {
919
+ return;
920
+ } else {
921
+ let newKey = encodeUrlQuery(key);
922
+ history.push({
923
+ pathname: newKey,
924
+ });
925
+ }
926
+ },
927
+ );
928
+ }
929
+ if (type === 'all') {
930
+ this.updateState(
931
+ listenRouterState.filter((item) => item.key === '/'),
932
+ listenRouterKey.filter((item) => item === '/'),
933
+ () => {
934
+ history.push({
935
+ pathname: '/',
936
+ });
937
+ },
938
+ );
939
+ }
940
+ if (type === 'other') {
941
+ this.updateState(
942
+ listenRouterState.filter(
943
+ (item) => item.key === key || item.key === '/',
944
+ ),
945
+ listenRouterKey.filter((item) => item === key || item === '/'),
946
+ () => {
947
+ if (key !== activeKey) {
948
+ let newKey = encodeUrlQuery(key);
949
+ history.push({
950
+ pathname: newKey,
951
+ });
952
+ }
953
+ },
954
+ );
955
+ }
956
+ };
957
+
958
+ render() {
959
+ const {
960
+ listenRouterState,
961
+ activeKey,
962
+ listenRouterKey,
963
+ drawerLeftParams,
964
+ collapse,
965
+ currentSubMenuData,
966
+ showSubMenu,
967
+ currentSubPath,
968
+ } = this.state;
969
+ const { originRoutes, itemPath, defaultSettings, transparentProps={} } = this.props;
970
+ const TabTitle: React.FC<{}> = ({ item, index, updateState }) => {
971
+ return (
972
+ <div className="tab_title_content">
973
+ {item.tab}
974
+ {item.key !== '/' && (
975
+ <ItemMenu
976
+ info={item}
977
+ operateFun={this.operateFun}
978
+ listenRouterState={listenRouterState}
979
+ />
980
+ )}
981
+ </div>
982
+ );
983
+ };
984
+
985
+ // 左侧菜单 route
986
+ const dataShowRoute = this.props.routes.find(
987
+ (route) => route.path === '/homePage/data-show',
988
+ ); // 添加数据大屏
989
+ const { route, ...restPrpos } = this.props;
990
+ const exist = route.routes.find(
991
+ (route) => route.path === '/homePage/data-show',
992
+ );
993
+ if (dataShowRoute && !exist) {
994
+ route.routes.splice(1, 0, dataShowRoute);
995
+ }
996
+
997
+ const menu = (
998
+ <Menu>
999
+ <Menu.Item
1000
+ key="0"
1001
+ style={{
1002
+ background: '#FFFFFF',
1003
+ color: '#848484',
1004
+ fontSize: '12px',
1005
+ textAlign: 'center',
1006
+ }}
1007
+ >
1008
+ <div>已打开的页签数: {listenRouterState.length}</div>
1009
+ </Menu.Item>
1010
+ <Menu.Item key="1" style={{ fontSize: '12px', textAlign: 'center' }}>
1011
+ <a
1012
+ onClick={() => {
1013
+ // 关闭全部
1014
+ this.updateState(
1015
+ [
1016
+ {
1017
+ ...this.state.homeRouter,
1018
+ key: '/',
1019
+ tab: '欢迎',
1020
+ closable: false,
1021
+ },
1022
+ ],
1023
+ ['/'],
1024
+ () => {
1025
+ history.push('/');
1026
+ },
1027
+ );
1028
+ }}
1029
+ >
1030
+ 关闭全部标签
1031
+ </a>
1032
+ </Menu.Item>
1033
+ <Menu.Item key="2" style={{ fontSize: '12px', textAlign: 'center' }}>
1034
+ <a
1035
+ onClick={() => {
1036
+ if (activeKey === '/') return;
1037
+ const index = listenRouterState.findIndex(
1038
+ (item) => item.key === activeKey,
1039
+ );
1040
+ let newActiveKey = '';
1041
+ if (index > 0) {
1042
+ newActiveKey = listenRouterState[index - 1].key;
1043
+ } else {
1044
+ newActiveKey = listenRouterState[1].key;
1045
+ }
1046
+ this.updateState(
1047
+ listenRouterState.filter((d) => d.key !== activeKey),
1048
+ listenRouterKey.filter((d) => d !== activeKey),
1049
+ () => {
1050
+ let newKey = encodeUrlQuery(newActiveKey);
1051
+ history.push({
1052
+ pathname: newKey,
1053
+ });
1054
+ },
1055
+ );
1056
+ }}
1057
+ >
1058
+ 关闭当前标签
1059
+ </a>
1060
+ </Menu.Item>
1061
+ <Menu.Item key="3" style={{ fontSize: '12px', textAlign: 'center' }}>
1062
+ <a
1063
+ onClick={() => {
1064
+ const index = listenRouterState.findIndex(
1065
+ (item) => item.key === activeKey,
1066
+ );
1067
+ // let deleteKey = listenRouterState[index - 1]?.key;
1068
+ // if (deleteKey === '/') {
1069
+ // message.warning('首页不可关闭。');
1070
+ // return;
1071
+ // }
1072
+
1073
+ this.updateState(
1074
+ listenRouterState.filter(
1075
+ (d: any, i: number) => i >= index || d.key === '/',
1076
+ ),
1077
+ listenRouterKey.filter(
1078
+ (d: any, i: number) => i >= index || d === '/',
1079
+ ),
1080
+ );
1081
+ }}
1082
+ >
1083
+ 关闭其左侧标签
1084
+ </a>
1085
+ </Menu.Item>
1086
+ <Menu.Item key="4" style={{ fontSize: '12px', textAlign: 'center' }}>
1087
+ <a
1088
+ onClick={() => {
1089
+ let index = listenRouterState.findIndex(
1090
+ (item) => item.key === activeKey,
1091
+ );
1092
+ this.updateState(
1093
+ listenRouterState.filter(
1094
+ (d: any, i: number) => i <= index || d.key === '/',
1095
+ ),
1096
+ listenRouterKey.filter(
1097
+ (d: any, i: number) => i <= index || d === '/',
1098
+ ),
1099
+ );
1100
+ }}
1101
+ >
1102
+ 关闭其右侧标签
1103
+ </a>
1104
+ </Menu.Item>
1105
+ </Menu>
1106
+ );
1107
+
1108
+ const filterByMenuDate = (
1109
+ data: MenuDataItem[],
1110
+ keyWord: string,
1111
+ ): MenuDataItem[] =>
1112
+ data
1113
+ .map((item) => {
1114
+ if (item.name && item.name.includes(keyWord)) {
1115
+ return {
1116
+ ...item,
1117
+ };
1118
+ }
1119
+ return undefined;
1120
+ })
1121
+ .filter((item) => item) as MenuDataItem[];
1122
+
1123
+ let weiqianduanProps = {};
1124
+ let isWeiqianduan = false;
1125
+
1126
+ if (window.top != window) {
1127
+ isWeiqianduan = true;
1128
+ weiqianduanProps = {
1129
+ headerRender: false,
1130
+ footerRender: false,
1131
+ menuRender: false,
1132
+ menuHeaderRender: false,
1133
+ menuExtraRender: false,
1134
+ };
1135
+ }
1136
+
1137
+ const OperationsSlot: Record<PositionType, React.ReactNode> = {
1138
+ left: (
1139
+ <div className={'tab_left_operate'}>
1140
+ <div
1141
+ onClick={() => {
1142
+ history.push({
1143
+ pathname: '/',
1144
+ });
1145
+ }}
1146
+ >
1147
+ <HomeOutlined />
1148
+ </div>
1149
+ <div
1150
+ style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1151
+ onClick={() => {
1152
+ this.setTabNavTransLate(-100);
1153
+ }}
1154
+ >
1155
+ <DoubleLeftOutlined />
1156
+ </div>
1157
+ </div>
1158
+ ),
1159
+ right: (
1160
+ <div
1161
+ style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1162
+ className={'tab_right_operate'}
1163
+ onClick={() => {
1164
+ this.setTabNavTransLate(100);
1165
+ }}
1166
+ >
1167
+ <DoubleRightOutlined />
1168
+ </div>
1169
+ ),
1170
+ };
1171
+
1172
+ return (
1173
+ <ProLayout
1174
+ actionRef={this.actionRef}
1175
+ onMenuHeaderClick={() => history.push('/')}
1176
+ menuHeaderRender={({ }) => (
1177
+ <CustomerMenuHeader
1178
+ originRoutes={originRoutes}
1179
+ itemPath={itemPath}
1180
+ handleClose={this.handleClose}
1181
+ collapsed={collapse}
1182
+ />
1183
+ )}
1184
+ menuExtraRender={() => {
1185
+ if (!collapse) {
1186
+ return (
1187
+ <div>
1188
+ <CustomerMenu
1189
+ originRoutes={originRoutes}
1190
+ itemPath={itemPath}
1191
+ ref={this.customerMenuRef}
1192
+ actionRef={this.actionRef}
1193
+ handleClose={this.handleClose}
1194
+ isCollapse={this.state.collapse}
1195
+ />
1196
+ </div>
1197
+ );
1198
+ }
1199
+ return (
1200
+ <div className="collapse_icon_close">
1201
+ <span
1202
+ className="collapse_icon"
1203
+ onClick={() => {
1204
+ this.setState({
1205
+ collapse: !collapse,
1206
+ });
1207
+ }}
1208
+ >
1209
+ <MenuUnfoldOutlined />
1210
+ </span>
1211
+ </div>
1212
+ );
1213
+ }}
1214
+ menuProps={{
1215
+ onClick: () => {
1216
+ localStorage.setItem('isMenuClick', 'true');
1217
+ },
1218
+ }}
1219
+ collapsed={collapse}
1220
+ onCollapse={(boo: boolean) => {
1221
+ this.setState({
1222
+ collapse: boo,
1223
+ });
1224
+ }}
1225
+ menuItemRender={(menuItemProps, defaultDom) => {
1226
+ if (menuItemProps?.path === '/') {
1227
+ return (
1228
+ <>
1229
+ <div className="one_menu_wrap">
1230
+ <Link
1231
+ onClick={() => {
1232
+ localStorage.setItem('isMenuClick', 'true');
1233
+ }}
1234
+ to={menuItemProps.path}
1235
+ >
1236
+ {defaultDom}
1237
+ </Link>
1238
+ </div>
1239
+ </>
1240
+ );
1241
+ }
1242
+ return (
1243
+ <Link
1244
+ onClick={() => {
1245
+ localStorage.setItem('isMenuClick', 'true');
1246
+ }}
1247
+ to={menuItemProps.path}
1248
+ >
1249
+ {defaultDom}
1250
+ </Link>
1251
+ );
1252
+ }}
1253
+ subMenuItemRender={(menuItemProps, defaultDom) => {
1254
+ return (
1255
+ <div
1256
+ style={{
1257
+ height: '40px',
1258
+ lineHeight: '40px',
1259
+ position: 'relative',
1260
+ overflow: 'hidden',
1261
+ textOverflow: 'ellipsis',
1262
+ whiteSpace: 'nowrap',
1263
+ boxSizing: 'border-box',
1264
+ paddingRight: '10px',
1265
+ }}
1266
+ onMouseEnter={() => {
1267
+ if (
1268
+ menuItemProps.pro_layout_parentKeys &&
1269
+ menuItemProps.pro_layout_parentKeys.length
1270
+ )
1271
+ return;
1272
+ this.setState({
1273
+ currentSubMenuData: menuItemProps.children,
1274
+ currentSubPath: menuItemProps.path,
1275
+ });
1276
+ this.setShowMenu(true);
1277
+ }}
1278
+ onMouseLeave={() => {
1279
+ this.setShowMenu(false);
1280
+ }}
1281
+ >
1282
+ {defaultDom}
1283
+ {showSubMenu &&
1284
+ currentSubPath === menuItemProps.path &&
1285
+ !collapse && (
1286
+ <CaretLeftOutlined
1287
+ style={{ position: 'absolute', top: '14px', right: '-4px' }}
1288
+ />
1289
+ )}
1290
+ </div>
1291
+ );
1292
+ }}
1293
+ collapsedButtonRender={() => {
1294
+ return (
1295
+ <div
1296
+ onClick={(e) => {
1297
+ e.stopPropagation();
1298
+ }}
1299
+ className="banquan"
1300
+ >
1301
+ {''}
1302
+ </div>
1303
+ );
1304
+ }}
1305
+ postMenuData={(menus) => {
1306
+ return [...filterByMenuDate(menus || [], this.state.keyWord)];
1307
+ }}
1308
+ links={[
1309
+ !this.state.collapse ? (
1310
+ <AllFunc
1311
+ ref={this.allFunc}
1312
+ itemPath={itemPath}
1313
+ handleClose={this.handleClose}
1314
+ isCollapse={this.state.collapse}
1315
+ />
1316
+ ) : (
1317
+ ''
1318
+ ),
1319
+ ]}
1320
+ onPageChange={() => {
1321
+ const { location } = history;
1322
+ // 如果没有登录,重定向到 login
1323
+ if (
1324
+ !localStorage.getItem(ENUM.BROWSER_CACHE.USER_INFO) &&
1325
+ location.pathname !== '/user/login'
1326
+ ) {
1327
+ history.push('/user/login');
1328
+ }
1329
+ }}
1330
+ headerRender={(props) => <GlobalHeaderCom {...props} />}
1331
+ menu={{
1332
+ request: async () => {
1333
+ return JSON.parse(
1334
+ localStorage.getItem(`customerMenu_${itemPath}_front`) || '[]',
1335
+ );
1336
+ },
1337
+ type: 'group',
1338
+ }}
1339
+ route={route}
1340
+ {...restPrpos}
1341
+ {...defaultSettings}
1342
+ {...weiqianduanProps}
1343
+ >
1344
+ <div id="globalTabsContent" className="globalTabs">
1345
+ <DraggableTabs
1346
+ activeKey={activeKey}
1347
+ id="globalTabs"
1348
+ onChange={this.onChange}
1349
+ // tabBarExtraContent={operations}
1350
+ type="editable-card"
1351
+ tabBarStyle={{
1352
+ background: '#f3f3f3',
1353
+ height: '28px',
1354
+ marginRight: 0,
1355
+ fontSize: '12px',
1356
+ color: '#2C2F2E70',
1357
+ marginBottom: '-2px',
1358
+ position: 'fixed',
1359
+ top: 50,
1360
+ zIndex: 10,
1361
+ width: collapse ? 'calc(100% - 75px)' : 'calc(100% - 167px)',
1362
+ display: isWeiqianduan ? 'none' : 'flex',
1363
+ }}
1364
+ tabPosition="top"
1365
+ tabBarGutter={8}
1366
+ onEdit={this.onEdit}
1367
+ tabBarExtraContent={OperationsSlot}
1368
+ animated={false}
1369
+ hideAdd
1370
+ >
1371
+ {listenRouterState.map((item, index) => (
1372
+ <TabPane
1373
+ tab={
1374
+ <TabTitle
1375
+ item={item}
1376
+ index={index}
1377
+ updateState={this.updateState}
1378
+ />
1379
+ }
1380
+ style={{ marginTop: isWeiqianduan ? 0 : 30 }}
1381
+ key={item.key}
1382
+ closable={item.key !== '/'}
1383
+ closeIcon={<img src="./biaoqian-guanbi-icon.svg" />}
1384
+ >
1385
+ <WrapperComponent
1386
+ item={item}
1387
+ routerProps={this.props}
1388
+ getDictionarySource={this.getDictionarySource}
1389
+ getDictionaryTextByValue={this.getDictionaryTextByValue}
1390
+ timeFormat={this.timeFormat}
1391
+ transparentProps={transparentProps}
1392
+ />
1393
+ </TabPane>
1394
+ ))}
1395
+ </DraggableTabs>
1396
+ <div
1397
+ className="globalTabsOper"
1398
+ style={{
1399
+ position: 'fixed',
1400
+ top: '50px',
1401
+ zIndex: 10,
1402
+ background: '#fff',
1403
+ display: isWeiqianduan ? 'none' : 'block',
1404
+ borderLeft: '1px solid #E4E4E4',
1405
+ }}
1406
+ >
1407
+ <Dropdown overlay={menu} trigger={['click']}>
1408
+ <a
1409
+ className="ant-dropdown-link"
1410
+ onClick={(e) => e.preventDefault()}
1411
+ >
1412
+ <DashOutlined />
1413
+ </a>
1414
+ </Dropdown>
1415
+ </div>
1416
+ <SearchFunc itemPath={itemPath} {...drawerLeftParams}></SearchFunc>
1417
+ <div
1418
+ onMouseEnter={() => {
1419
+ this.setShowMenu(true);
1420
+ }}
1421
+ onMouseLeave={() => {
1422
+ this.setShowMenu(false);
1423
+ }}
1424
+ className={'sub_menu_content'}
1425
+ style={{ display: showSubMenu && !collapse ? 'block' : 'none' }}
1426
+ >
1427
+ {this.getMenuDom(currentSubMenuData)}
1428
+ </div>
1429
+ </div>
1430
+ </ProLayout>
1431
+ );
1432
+ }
1433
+ }
1434
+
1435
+ class WrapperComponent extends React.Component {
1436
+ constructor(props) {
1437
+ super(props);
1438
+ }
1439
+
1440
+ shouldComponentUpdate(nextProps) {
1441
+ if (window.__POWERED_BY_WUJIE__ && nextProps?.item?.key?.indexOf('edit-template-template') > -1) { // 适配wujie环境主应用下渲染打印编辑器
1442
+ return true
1443
+ }
1444
+ return false;
1445
+ }
1446
+ render() {
1447
+ const {
1448
+ item,
1449
+ routerProps,
1450
+ getDictionarySource,
1451
+ getDictionaryTextByValue,
1452
+ timeFormat,
1453
+ transparentProps,
1454
+ } = this.props;
1455
+ console.log('child wrapper conpent', this.props)
1456
+ return (
1457
+ <>
1458
+ {React.createElement(item.content, {
1459
+ getDictionarySource: getDictionarySource,
1460
+ getDictionaryTextByValue: getDictionaryTextByValue,
1461
+ timeFormat: timeFormat,
1462
+ ...routerProps,
1463
+ ...transparentProps,
1464
+ match: item.match,
1465
+ })}
1466
+ </>
1467
+ );
1468
+ }
1469
+ }
1470
+
1471
+ export default (props) => {
1472
+ const { initialState = {} } = useModel('@@initialState');
1473
+
1474
+ const { dictionaryData } = initialState;
1475
+ const intl = useIntl();
1476
+ const { formatMessage } = intl;
1477
+ return (
1478
+ <BasicLayout
1479
+ {...props}
1480
+ dictionaryData={dictionaryData}
1481
+ formatMessage={formatMessage}
1482
+ />
1483
+ );
1484
+ };