@bit-sun/business-component 3.1.7 → 3.1.8

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 (219) 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.esm.js +191 -151
  9. package/dist/index.js +191 -150
  10. package/dist/utils/utils.d.ts +1 -0
  11. package/docs/index.md +21 -21
  12. package/lib/assets/drag.svg +17 -17
  13. package/lib/assets/exportFail.svg +37 -37
  14. package/lib/assets/exportProcessing.svg +28 -28
  15. package/lib/assets/exportSuccess.svg +34 -34
  16. package/lib/assets/label_icon_bottom.svg +25 -25
  17. package/lib/assets/upExport.svg +22 -22
  18. package/package.json +88 -88
  19. package/src/assets/32.svg +27 -27
  20. package/src/assets/addIcon.svg +17 -17
  21. package/src/assets/allfunc.svg +27 -27
  22. package/src/assets/arrowRight.svg +24 -24
  23. package/src/assets/arrow_top.svg +17 -17
  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 +398 -398
  48. package/src/components/Business/AddSelectBusiness/index.tsx +1116 -1116
  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/ChooseStore/index.tsx +193 -193
  53. package/src/components/Business/BsLayouts/Components/ChooseStore/services.ts +10 -10
  54. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/index.less +90 -90
  55. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/index.tsx +37 -37
  56. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/leftTree.tsx +242 -242
  57. package/src/components/Business/BsLayouts/Components/CustomerMenu/MenuSetting/rightTree.tsx +384 -384
  58. package/src/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/DrawContent.tsx +285 -285
  59. package/src/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/customMenuHeader.tsx +74 -74
  60. package/src/components/Business/BsLayouts/Components/CustomerMenu/globalMenu/drawContent.less +170 -170
  61. package/src/components/Business/BsLayouts/Components/CustomerMenu/index.less +64 -64
  62. package/src/components/Business/BsLayouts/Components/CustomerMenu/index.tsx +153 -153
  63. package/src/components/Business/BsLayouts/Components/GlobalHeader/index.less +72 -72
  64. package/src/components/Business/BsLayouts/Components/GlobalHeader/index.tsx +163 -163
  65. package/src/components/Business/BsLayouts/Components/RightContent/LoginModal.tsx +85 -85
  66. package/src/components/Business/BsLayouts/Components/RightContent/home.less +218 -218
  67. package/src/components/Business/BsLayouts/Components/RightContent/i18n.ts +8 -8
  68. package/src/components/Business/BsLayouts/Components/RightContent/index.tsx +172 -172
  69. package/src/components/Business/BsLayouts/Components/SearchFunc/index.less +160 -160
  70. package/src/components/Business/BsLayouts/Components/SearchFunc/index.tsx +75 -75
  71. package/src/components/Business/BsLayouts/index.less +79 -79
  72. package/src/components/Business/BsLayouts/index.tsx +1606 -1606
  73. package/src/components/Business/BsLayouts/service.ts +10 -10
  74. package/src/components/Business/BsLayouts/utils.tsx +205 -205
  75. package/src/components/Business/BsSulaQueryTable/SearchItemSetting.tsx +566 -566
  76. package/src/components/Business/BsSulaQueryTable/bssulaquerytable.less +5 -5
  77. package/src/components/Business/BsSulaQueryTable/index.less +227 -227
  78. package/src/components/Business/BsSulaQueryTable/index.tsx +765 -772
  79. package/src/components/Business/BsSulaQueryTable/setting.tsx +888 -888
  80. package/src/components/Business/BsSulaQueryTable/utils.less +65 -65
  81. package/src/components/Business/BsSulaQueryTable/utils.tsx +709 -709
  82. package/src/components/Business/CommodityEntry/index.md +84 -84
  83. package/src/components/Business/CommodityEntry/index.tsx +82 -82
  84. package/src/components/Business/CommonAlert/index.tsx +23 -23
  85. package/src/components/Business/CommonGuideWrapper/index.less +121 -121
  86. package/src/components/Business/CommonGuideWrapper/index.md +39 -39
  87. package/src/components/Business/CommonGuideWrapper/index.tsx +94 -94
  88. package/src/components/Business/DetailPageWrapper/index.less +87 -87
  89. package/src/components/Business/DetailPageWrapper/index.tsx +327 -327
  90. package/src/components/Business/DetailPageWrapper/utils.tsx +166 -166
  91. package/src/components/Business/HomePageWrapper/index.less +33 -33
  92. package/src/components/Business/HomePageWrapper/index.md +45 -45
  93. package/src/components/Business/HomePageWrapper/index.tsx +162 -162
  94. package/src/components/Business/JsonQueryTable/components/FieldsModifyModal.tsx +823 -823
  95. package/src/components/Business/JsonQueryTable/components/FieldsSettingsTable.tsx +205 -205
  96. package/src/components/Business/JsonQueryTable/components/Formula.tsx +205 -205
  97. package/src/components/Business/JsonQueryTable/components/MaintainOptions.tsx +127 -127
  98. package/src/components/Business/JsonQueryTable/configButton/index.js +20 -20
  99. package/src/components/Business/JsonQueryTable/configTree/component/compactArrayView.js +25 -25
  100. package/src/components/Business/JsonQueryTable/configTree/component/compactObjectView.js +30 -30
  101. package/src/components/Business/JsonQueryTable/configTree/index.js +82 -82
  102. package/src/components/Business/JsonQueryTable/configTree/index.less +44 -44
  103. package/src/components/Business/JsonQueryTable/configTree/parser/highlight.js +57 -57
  104. package/src/components/Business/JsonQueryTable/configTree/parser/index.js +124 -124
  105. package/src/components/Business/JsonQueryTable/configTree/render/iconRender.js +29 -29
  106. package/src/components/Business/JsonQueryTable/configTree/render/nameRender.js +22 -22
  107. package/src/components/Business/JsonQueryTable/configTree/treeNode.js +116 -116
  108. package/src/components/Business/JsonQueryTable/drawer/index.tsx +12 -12
  109. package/src/components/Business/JsonQueryTable/function.ts +62 -62
  110. package/src/components/Business/JsonQueryTable/index.less +16 -16
  111. package/src/components/Business/JsonQueryTable/index.md +328 -328
  112. package/src/components/Business/JsonQueryTable/index.tsx +534 -534
  113. package/src/components/Business/JsonQueryTable/jsonEditor/index.js +346 -346
  114. package/src/components/Business/JsonQueryTable/jsonEditor/index.less +22 -22
  115. package/src/components/Business/JsonQueryTable/jsonEditor/lint/basicType.js +147 -147
  116. package/src/components/Business/JsonQueryTable/jsonEditor/lint/index.js +389 -389
  117. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/actions.js +118 -118
  118. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/dependency.js +22 -22
  119. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/index.js +21 -21
  120. package/src/components/Business/JsonQueryTable/jsonEditor/suggestions/request.js +65 -65
  121. package/src/components/Business/JsonQueryTable/static.ts +450 -450
  122. package/src/components/Business/SearchSelect/BusinessUtils.tsx +2162 -2162
  123. package/src/components/Business/SearchSelect/common.ts +134 -134
  124. package/src/components/Business/SearchSelect/index.md +1512 -1512
  125. package/src/components/Business/SearchSelect/index.tsx +55 -55
  126. package/src/components/Business/SearchSelect/utils.ts +125 -125
  127. package/src/components/Business/StateFlow/index.less +130 -130
  128. package/src/components/Business/StateFlow/index.md +60 -60
  129. package/src/components/Business/StateFlow/index.tsx +29 -29
  130. package/src/components/Business/TreeSearchSelect/index.md +211 -211
  131. package/src/components/Business/TreeSearchSelect/index.tsx +33 -33
  132. package/src/components/Business/TreeSearchSelect/utils.ts +104 -104
  133. package/src/components/Business/columnSettingTable/columnSetting.tsx +816 -816
  134. package/src/components/Business/columnSettingTable/index.less +253 -253
  135. package/src/components/Business/columnSettingTable/index.md +357 -357
  136. package/src/components/Business/columnSettingTable/index.tsx +225 -226
  137. package/src/components/Business/columnSettingTable/sulaSettingTable.tsx +232 -233
  138. package/src/components/Business/columnSettingTable/utils.tsx +87 -87
  139. package/src/components/Business/moreTreeTable/FixedScrollBar.tsx +87 -87
  140. package/src/components/Business/moreTreeTable/hooks/useSticky.ts +21 -21
  141. package/src/components/Business/moreTreeTable/index.less +99 -99
  142. package/src/components/Business/moreTreeTable/index.md +448 -448
  143. package/src/components/Business/moreTreeTable/index.tsx +387 -387
  144. package/src/components/Business/moreTreeTable/utils.ts +126 -126
  145. package/src/components/Functional/AccessWrapper/index.tsx +33 -33
  146. package/src/components/Functional/AddSelect/helps.ts +81 -81
  147. package/src/components/Functional/AddSelect/index.less +367 -367
  148. package/src/components/Functional/AddSelect/index.md +155 -155
  149. package/src/components/Functional/AddSelect/index.tsx +1064 -1065
  150. package/src/components/Functional/AuthButton/index.tsx +15 -15
  151. package/src/components/Functional/BillEntry/index.less +371 -371
  152. package/src/components/Functional/BillEntry/index.md +39 -39
  153. package/src/components/Functional/BillEntry/index.tsx +771 -772
  154. package/src/components/Functional/BsAntdSula/BsCascader/index.md +62 -62
  155. package/src/components/Functional/BsAntdSula/BsCascader/index.tsx +178 -178
  156. package/src/components/Functional/BsAntdSula/index.ts +2 -2
  157. package/src/components/Functional/DataImport/index.less +63 -63
  158. package/src/components/Functional/DataImport/index.md +44 -44
  159. package/src/components/Functional/DataImport/index.tsx +783 -783
  160. package/src/components/Functional/DataValidation/index.less +63 -63
  161. package/src/components/Functional/DataValidation/index.md +52 -52
  162. package/src/components/Functional/DataValidation/index.tsx +788 -788
  163. package/src/components/Functional/EllipsisTooltip/index.d.ts +5 -5
  164. package/src/components/Functional/EllipsisTooltip/index.js +36 -36
  165. package/src/components/Functional/EllipsisTooltip/index.md +30 -30
  166. package/src/components/Functional/ExportFunctions/ExportIcon/index.md +37 -37
  167. package/src/components/Functional/ExportFunctions/ExportIcon/index.tsx +65 -65
  168. package/src/components/Functional/QueryMutipleInput/index.less +37 -37
  169. package/src/components/Functional/QueryMutipleInput/index.md +33 -33
  170. package/src/components/Functional/QueryMutipleInput/index.tsx +129 -129
  171. package/src/components/Functional/SearchSelect/index.less +121 -121
  172. package/src/components/Functional/SearchSelect/index.md +141 -141
  173. package/src/components/Functional/SearchSelect/index.tsx +1041 -1041
  174. package/src/components/Functional/SearchSelect/utils.ts +3 -3
  175. package/src/components/Functional/TreeSearchSelect/index.md +47 -47
  176. package/src/components/Functional/TreeSearchSelect/index.tsx +224 -224
  177. package/src/components/Solution/RuleComponent/Formula.tsx +335 -335
  178. package/src/components/Solution/RuleComponent/InnerSelect.tsx +62 -62
  179. package/src/components/Solution/RuleComponent/RenderCompItem.tsx +670 -670
  180. package/src/components/Solution/RuleComponent/index.d.ts +29 -29
  181. package/src/components/Solution/RuleComponent/index.js +1601 -1601
  182. package/src/components/Solution/RuleComponent/index.less +247 -247
  183. package/src/components/Solution/RuleComponent/renderSpecificAction.js +99 -99
  184. package/src/components/Solution/RuleComponent/ruleFiled.js +2293 -2293
  185. package/src/components/Solution/RuleComponent/services.ts +13 -13
  186. package/src/components/Solution/RuleComponent/util.js +143 -143
  187. package/src/components/Solution/RuleSetter/RuleInstance.tsx +6 -6
  188. package/src/components/Solution/RuleSetter/baseRule.tsx +394 -394
  189. package/src/components/Solution/RuleSetter/function.ts +437 -437
  190. package/src/components/Solution/RuleSetter/index.less +221 -221
  191. package/src/components/Solution/RuleSetter/index.tsx +208 -208
  192. package/src/components/Solution/RuleSetter/service.js +276 -276
  193. package/src/index.ts +41 -41
  194. package/src/plugin/TableColumnSetting/index.less +247 -247
  195. package/src/plugin/TableColumnSetting/index.md +50 -50
  196. package/src/plugin/TableColumnSetting/index.tsx +725 -725
  197. package/src/plugin/TableColumnSetting/utils.ts +19 -19
  198. package/src/styles/bsDefault.less +1933 -1933
  199. package/src/utils/CheckOneUser/index.md +39 -39
  200. package/src/utils/CheckOneUser/index.ts +51 -51
  201. package/src/utils/CustomLoginInfo.ts +55 -55
  202. package/src/utils/LocalstorageUtils.ts +134 -134
  203. package/src/utils/TableUtils.less +51 -51
  204. package/src/utils/TableUtils.tsx +691 -691
  205. package/src/utils/auth.ts +38 -38
  206. package/src/utils/businessUtils.ts +434 -434
  207. package/src/utils/checkUtils.ts +39 -39
  208. package/src/utils/constant.ts +38 -38
  209. package/src/utils/enumConfig.ts +17 -17
  210. package/src/utils/getFormMode.js +12 -12
  211. package/src/utils/index.ts +19 -19
  212. package/src/utils/request.ts +53 -53
  213. package/src/utils/requestUtils.ts +193 -193
  214. package/src/utils/serialize.js +7 -7
  215. package/src/utils/utils.ts +245 -238
  216. package/src/utils/xlsxUtil.tsx +145 -145
  217. package/tsconfig.json +29 -29
  218. package/typings.d.ts +4 -4
  219. package/.yarnclean +0 -45
@@ -1,1606 +1,1606 @@
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, route?.state);
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
- // -------------------处理页签关闭----------------------------
518
- lastTwoRouterArray.push(route.pathname);
519
- lastTwoRouterArray.shift();
520
-
521
- const {
522
- thisHideInMenuDoNotClose = false,
523
- closePrevPage = false,
524
- updateCurrentPage = false,
525
- } = route?.state || {};
526
-
527
- let needRemoveKey = '';
528
-
529
- // lastTwoRouterArray[0] != lastTwoRouterArray[1] 该判断条件用于判断是否是tab删除操作,如果是tab页删除操作,删除的是不是最后一个打开的tab页,执行history.push会导致错误的将最后打开的那个tab页也删除掉
530
- let notSamePageFlag = lastTwoRouterArray[0] != lastTwoRouterArray[1];
531
-
532
- // 满足包含closePrevPage标识则直接删除上一页
533
- if (closePrevPage) {
534
- needRemoveKey = lastTwoRouterArray[0] && typeof lastTwoRouterArray[0] === 'string' && notSamePageFlag ? lastTwoRouterArray[0] : '';
535
- } else {
536
- // 满足非tabclick或者menuClick的hideInMenu类型菜单自动关闭
537
- const shouldClosePrev = (!localStorage.getItem('isTabChange') && !localStorage.getItem('isMenuClick'));
538
- const needRemoveKeyArray = lastTwoRouterArray[0] && typeof lastTwoRouterArray[0] === 'string' && shouldClosePrev ?
539
- hideMenuArray.filter((itemRoute) =>
540
- pathToRegexp(itemRoute.path || '').test(lastTwoRouterArray[0]),
541
- ) : [];
542
- needRemoveKey = needRemoveKeyArray.length && notSamePageFlag && !thisHideInMenuDoNotClose ? needRemoveKeyArray[0] : '';
543
- }
544
-
545
- if (needRemoveKey) {
546
- newListenRouterState = newListenRouterState.filter((item) => {
547
- const [pathname] = item.key ? item.key.split('?') : [];
548
- return pathname && pathname !== lastTwoRouterArray[0];
549
- });
550
- newListenRouterKey = newListenRouterKey.filter((item) => {
551
- const [pathname] = item ? item.split('?') : [];
552
- return pathname && pathname !== lastTwoRouterArray[0];
553
- });
554
- }
555
-
556
- setTimeout(() => {
557
- // 处理页面刷新两面
558
- localStorage.removeItem('isTabChange');
559
- localStorage.removeItem('isMenuClick');
560
- }, 0);
561
-
562
- // -------------------处理页签关闭 end----------------------------
563
-
564
- this.setState(
565
- {
566
- //路由监听函数最后执行setState,避免处理hideMenu类型页面自动关闭的逻辑块内获取不到最新state的listenRouterState和listenRouterKey
567
- activeKey: currentKey,
568
- listenRouterState: newListenRouterState,
569
- listenRouterKey: newListenRouterKey,
570
- },
571
- () => {
572
- this.checkisNavSlide();
573
- },
574
- );
575
-
576
- istParent = 0;
577
- });
578
-
579
- if (localStorage.getItem('mainRoutePath') && localStorage.getItem('mainRoutePath')?.startsWith(`/${itemPath}/`)) {
580
- istParent = 1;
581
- history.push(localStorage.getItem('mainRoutePath').replace(/^\/\w+\//, '/'))
582
- } else if (localStorage.getItem('firstPage') && localStorage.getItem('firstPage')?.startsWith(`#/${itemPath}/`)) {
583
- // 暂时保留,兼容老版本
584
- istParent = 1;
585
- history.push(
586
- localStorage
587
- .getItem('firstPage')
588
- ?.slice(1)
589
- .replace(/^\/\w+\//, '/'),
590
- );
591
- } else {
592
- history.push(location);
593
- }
594
- }
595
-
596
- componentWillUnmount() {
597
- // eslint-disable-next-line no-unused-expressions
598
- UN_LISTTEN_DRP && UN_LISTTEN_DRP();
599
- }
600
-
601
- parseQueryString = (queryString) => {
602
- if (!queryString) {
603
- return '';
604
- }
605
-
606
- if (queryString.indexOf('?') < 0) {
607
- return `?${queryString}`;
608
- }
609
-
610
- return queryString;
611
- };
612
-
613
- updateTree = (Tree, authMenuKeys = []) => {
614
- const treeData = Tree;
615
- const treeList = [];
616
-
617
-
618
-
619
- // 是否为权限菜单路径
620
- const getLimitedMenuPath = (node) => {
621
- return authMenuKeys.some(item => (node.path || '').includes(item));
622
- }
623
-
624
- // 是否为通用单据菜单路径
625
- const getGenerateDocs = (node) => {
626
- return (node.path || '').includes('all-general-documents');
627
- }
628
-
629
- // 递归获取树列表
630
- const getTreeList = (data) => {
631
- data.forEach((node) => {
632
- if (node.routes && node.routes.length > 0) {
633
- getTreeList(node.routes);
634
- return;
635
- }
636
- // todo:暂时处理非wujie环境不做404管控
637
- if (!window.__POWERED_BY_WUJIE__) {
638
- treeList.push({
639
- tab: node.locale,
640
- key: node.path,
641
- locale: node.locale,
642
- closable: true,
643
- content: node.component,
644
- name: node.name,
645
- hideInMenu: node.hideInMenu,
646
- isOnlyOnePage: node.isOnlyOnePage,
647
- });
648
- return;
649
- }
650
- if (node.path === '/' || getLimitedMenuPath(node) || getGenerateDocs(node) || node.noAuth) {
651
- treeList.push({
652
- tab: node.locale,
653
- key: node.path,
654
- locale: node.locale,
655
- closable: true,
656
- content: node.component,
657
- name: node.name,
658
- hideInMenu: node.hideInMenu,
659
- isOnlyOnePage: node.isOnlyOnePage,
660
- });
661
- }
662
- });
663
- };
664
- getTreeList(treeData);
665
- return treeList;
666
- };
667
-
668
- getDictionarySource = (dicCode: string, needConvertInterger = false) => {
669
- const { dictionaryData } = this.props;
670
-
671
- let dicData = {};
672
-
673
- if (!dictionaryData) {
674
- let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
675
- ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
676
- : {};
677
- dicData = storageDic[dicCode];
678
- } else {
679
- dicData = dictionaryData[dicCode];
680
- }
681
- // if (!dicData || !dicData.length) {
682
- // throw new Error(`当前没有${dicCode}字典值`);
683
- // }
684
-
685
- try {
686
- if (needConvertInterger) {
687
- dicData = dicData.map((item: { text: string; value: string }) => ({
688
- ...item,
689
- value: parseFloat(item.value),
690
- }));
691
- }
692
- } catch (e) { }
693
-
694
- return dicData;
695
- };
696
-
697
- getDictionaryTextByValue = (dicCode: string, value: string) => {
698
- let startPerformance = performance.now();
699
- if (window.dicDataTextValue) {
700
- const dicDataTextValue = window.dicDataTextValue;
701
- let dicData = [];
702
-
703
- dicData = dicDataTextValue[dicCode];
704
-
705
- let endPerformance1 = performance.now();
706
-
707
- console.log("字典方法时间花费1:", endPerformance1 - startPerformance);
708
-
709
- if (value === undefined) return "- -";
710
-
711
- if (!dicData) {
712
- // throw new Error(`当前${dicCode}字典值合没有${value}的数据`)
713
- return value;
714
- }
715
-
716
- let endPerformance = performance.now();
717
-
718
- console.log("字典方法时间花费:", endPerformance - startPerformance);
719
-
720
- return dicData[value] || value;
721
- }
722
- let dicData = [];
723
- let dictionaryData: any;
724
- if (!dictionaryData) {
725
- let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
726
- ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
727
- : {};
728
- dicData = storageDic[dicCode];
729
- } else {
730
- dicData = dictionaryData[dicCode];
731
- }
732
-
733
- if (!dicData || !dicData.length) {
734
- // throw new Error(`当前没有${dicCode}字典值`);
735
- }
736
-
737
- if (value === undefined) return '- -';
738
-
739
- const dicItemArray = dicData?.filter(
740
- (item: { value: string }) => item.value === value.toString(),
741
- );
742
-
743
- if (!dicItemArray?.length) {
744
- // throw new Error(`当前${dicCode}字典值合没有${value}的数据`)
745
- return value;
746
- }
747
-
748
- return dicItemArray[0].text;
749
- };
750
-
751
- timeFormat = (timeStr, format, notNeedConvertTimeZone) => {
752
- if (!timeStr) return '- -';
753
-
754
- if (notNeedConvertTimeZone) {
755
- return moment(timeStr).format(format);
756
- }
757
-
758
- return moment(timeStr).add(8, 'hours').format(format) || '- -';
759
- };
760
-
761
- onChange = (key) => {
762
- if (key !== this.state.activeKey) {
763
- this.setState({
764
- activeKey: key,
765
- });
766
- localStorage.setItem('isTabChange', '1');
767
- let newKey = encodeUrlQuery(key);
768
- history.push(newKey);
769
- }
770
- };
771
-
772
- getPageTitle = (pathname) => {
773
- const { formatMessage } = this.props;
774
- const { breadcrumbNameMap } = this.state;
775
- const currRouterData = this.matchParamsPath(pathname, breadcrumbNameMap);
776
-
777
- if (!currRouterData) {
778
- return '';
779
- }
780
- const pageName = formatMessage({
781
- id: currRouterData.locale || currRouterData.name,
782
- defaultMessage: currRouterData.name,
783
- });
784
-
785
- return `${pageName}`;
786
- };
787
-
788
- matchParamsPath = (pathname, breadcrumbNameMap) => {
789
- const { pathToRegexp } = this.props;
790
- const pathKey = Object.keys(breadcrumbNameMap).find((key) =>
791
- pathToRegexp(key).test(pathname),
792
- );
793
- return breadcrumbNameMap[pathKey];
794
- };
795
-
796
- onEdit = (
797
- targetKey: React.MouseEvent | React.KeyboardEvent | string,
798
- action: string,
799
- ) => {
800
- this.tabActions[action](targetKey);
801
- };
802
-
803
- tabActions: any = {
804
- remove: (targetKey: string) => {
805
- const { listenRouterState, activeKey, customerMatchs, listenRouterKey } =
806
- this.state;
807
-
808
- let lastIndex: number = 0;
809
- let newActiveKey: string | undefined = activeKey;
810
- let newListenRouterState = [];
811
- let newListenRouterKey = [];
812
-
813
- if (targetKey === activeKey) {
814
- listenRouterState.forEach((pane, i) => {
815
- if (pane.key === targetKey) {
816
- lastIndex = i - 1;
817
- }
818
- });
819
-
820
- newListenRouterState = listenRouterState.filter(
821
- (item) => item.key !== targetKey,
822
- );
823
- newListenRouterKey = listenRouterKey.filter(
824
- (item) => item !== targetKey,
825
- );
826
-
827
- if (lastIndex < 0) {
828
- lastIndex = 0;
829
- }
830
-
831
- newActiveKey = newListenRouterState[lastIndex].key;
832
- } else {
833
- newListenRouterState = listenRouterState.filter(
834
- (item) => item.key !== targetKey,
835
- );
836
- newListenRouterKey = listenRouterKey.filter(
837
- (item) => item !== targetKey,
838
- );
839
- }
840
-
841
- this.setState(
842
- {
843
- activeKey: newActiveKey,
844
- listenRouterState: newListenRouterState,
845
- listenRouterKey: newListenRouterKey,
846
- },
847
- () => {
848
- let newKey = encodeUrlQuery(newActiveKey);
849
- history.push({
850
- pathname: newKey,
851
- });
852
- this.checkisNavSlide();
853
- },
854
- );
855
- },
856
- };
857
-
858
- updateState = (newListenRouterState, newListenRouterKey, cb) => {
859
- this.setState(
860
- {
861
- listenRouterState: newListenRouterState,
862
- listenRouterKey: newListenRouterKey,
863
- },
864
- () => {
865
- this.checkisNavSlide();
866
- if (cb) cb();
867
- },
868
- );
869
- };
870
-
871
- handleClose = () => {
872
- this.setState({
873
- drawerLeftParams: {
874
- ...this.state.drawerLeftParams,
875
- visible: false,
876
- },
877
- isCollapse: true,
878
- });
879
- this.allFunc.current?.close?.();
880
- this.customerMenuRef.current?.close?.();
881
- };
882
-
883
- handleMenuClick = (item: any) => {
884
- if (item.children || !item.component) return;
885
- let newKey = encodeUrlQuery(item.path);
886
- history.push({
887
- pathname: newKey,
888
- });
889
- this.setShowMenu(false);
890
- };
891
-
892
- getMenuDom = (menuData) => {
893
- return menuData.map((item) => (
894
- <div>
895
- <div
896
- onClick={() => {
897
- this.handleMenuClick(item);
898
- }}
899
- className={`${'menu_item'} ${item.children || !item.component ? '' : 'link_style'
900
- }`}
901
- style={{
902
- fontWeight: item.children || !item.component ? 'bolder' : '400',
903
- paddingLeft: '10px',
904
- marginTop: item.children || !item.component ? '5px' : '0px',
905
- fontSize: item.children || !item.component ? '14px' : '12px',
906
- }}
907
- >
908
- {item.name}
909
- </div>
910
- {!!item.children &&
911
- !!item.children.length &&
912
- this.getMenuDom(item.children)}
913
- </div>
914
- ));
915
- };
916
-
917
- setShowMenu = debounce((isShow) => {
918
- this.setState({
919
- showSubMenu: isShow,
920
- });
921
- }, 500);
922
-
923
- //设置tabs标签左右滚动
924
- setTabNavTransLate = (num) => {
925
- let globalTabsNav = document
926
- .getElementById('globalTabs')
927
- ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
928
- let globalTabsNavWrap = document
929
- .getElementById('globalTabs')
930
- ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
931
- let wrapWidth = globalTabsNavWrap.offsetWidth; //tabsNav父节点宽度
932
- let navListWidth = globalTabsNav.offsetWidth; //tabsNav总宽度
933
- if (navListWidth - wrapWidth <= 0) return;
934
- let maxTransX = navListWidth - wrapWidth; // 允许移动最大宽度
935
- let transXStr = document.defaultView?.getComputedStyle(
936
- globalTabsNav,
937
- null,
938
- ).transform;
939
- let transx = transXStr?.split(',')[4]; //当前translateX的值
940
-
941
- let targetTransX = Math.abs(Number(transx)) + num;
942
- if (targetTransX <= 0) targetTransX = 0;
943
- if (targetTransX >= Number(maxTransX)) targetTransX = Number(maxTransX);
944
- globalTabsNav.style.transform = 'translateX(-' + targetTransX + 'px)';
945
- };
946
-
947
- checkisNavSlide = () => {
948
- if (window.top != window) return;
949
- //监听tabs页签总长度判断是否可点击滑动
950
- let globalTabsNav = document
951
- .getElementById('globalTabs')
952
- ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
953
- let globalTabsNavWrap = document
954
- .getElementById('globalTabs')
955
- ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
956
- let wrapWidth = globalTabsNavWrap?.offsetWidth; //tabsNav父节点宽度
957
- let navListWidth = globalTabsNav?.offsetWidth; //tabsNav总宽度
958
- if (navListWidth - wrapWidth <= 0) {
959
- this.setState({
960
- isSlider: false,
961
- });
962
- return;
963
- }
964
- this.setState({
965
- isSlider: true,
966
- });
967
- };
968
-
969
- changeListenRouterState = (dragIndex: number, hoverIndex: number) => {
970
- const { listenRouterState, listenRouterKey } = this.state;
971
- let dragItem = listenRouterState[dragIndex];
972
- let dragKeyItem = listenRouterKey[dragIndex];
973
-
974
- listenRouterState.splice(dragIndex, 1);
975
- listenRouterState.splice(hoverIndex, 0, dragItem);
976
-
977
- listenRouterKey.splice(dragIndex, 1);
978
- listenRouterKey.splice(hoverIndex, 0, dragKeyItem);
979
- };
980
-
981
- operateFun = (key, type) => {
982
- const { listenRouterState, activeKey, listenRouterKey } = this.state;
983
- let deleteKey = '';
984
- let newlistenRouterState = [];
985
- let newlistenRouterKey = [];
986
- let newActiveKey = '';
987
- let deleteIndex = 0;
988
- if (type === 'self') {
989
- deleteIndex = listenRouterState.findIndex((item) => item.key === key);
990
- deleteKey = key;
991
- if (deleteIndex > 0) {
992
- newActiveKey = listenRouterState[deleteIndex - 1].key;
993
- } else {
994
- newActiveKey = listenRouterState[1].key;
995
- }
996
- newlistenRouterState = listenRouterState.filter((d) => d.key !== key);
997
- newlistenRouterKey = listenRouterKey.filter((d) => d !== key);
998
- this.updateState(newlistenRouterState, newlistenRouterKey, () => {
999
- if (deleteKey === activeKey) {
1000
- let newKey = encodeUrlQuery(newActiveKey);
1001
- history.push({
1002
- pathname: newKey,
1003
- });
1004
- }
1005
- });
1006
- }
1007
- if (type === 'left') {
1008
- const index = listenRouterState.findIndex((item) => item.key === key);
1009
- newlistenRouterState = listenRouterState.filter(
1010
- (d: any, i: number) => i >= index || d.key === '/',
1011
- );
1012
- newlistenRouterKey = listenRouterKey.filter(
1013
- (d: any, i: number) => i >= index || d === '/',
1014
- );
1015
- this.updateState(newlistenRouterState, newlistenRouterKey, () => {
1016
- if (newlistenRouterKey.find((item) => item === activeKey)) {
1017
- return;
1018
- } else {
1019
- let newKey = encodeUrlQuery(key);
1020
- history.push({
1021
- pathname: newKey,
1022
- });
1023
- }
1024
- });
1025
- }
1026
- if (type === 'right') {
1027
- const index = listenRouterState.findIndex((item) => item.key === key);
1028
- newlistenRouterState = listenRouterState.filter(
1029
- (d: any, i: number) => i <= index || d.key === '/',
1030
- );
1031
- newlistenRouterKey = listenRouterKey.filter(
1032
- (d: any, i: number) => i <= index || d === '/',
1033
- );
1034
- this.updateState(
1035
- listenRouterState.filter(
1036
- (d: any, i: number) => i <= index || d.key === '/',
1037
- ),
1038
- listenRouterKey.filter((d: any, i: number) => i <= index || d === '/'),
1039
- () => {
1040
- if (newlistenRouterKey.find((item) => item === activeKey)) {
1041
- return;
1042
- } else {
1043
- let newKey = encodeUrlQuery(key);
1044
- history.push({
1045
- pathname: newKey,
1046
- });
1047
- }
1048
- },
1049
- );
1050
- }
1051
- if (type === 'all') {
1052
- this.updateState(
1053
- listenRouterState.filter((item) => item.key === '/'),
1054
- listenRouterKey.filter((item) => item === '/'),
1055
- () => {
1056
- history.push({
1057
- pathname: '/',
1058
- });
1059
- },
1060
- );
1061
- }
1062
- if (type === 'other') {
1063
- this.updateState(
1064
- listenRouterState.filter(
1065
- (item) => item.key === key || item.key === '/',
1066
- ),
1067
- listenRouterKey.filter((item) => item === key || item === '/'),
1068
- () => {
1069
- if (key !== activeKey) {
1070
- let newKey = encodeUrlQuery(key);
1071
- history.push({
1072
- pathname: newKey,
1073
- });
1074
- }
1075
- },
1076
- );
1077
- }
1078
- };
1079
-
1080
- render() {
1081
- const {
1082
- listenRouterState,
1083
- activeKey,
1084
- listenRouterKey,
1085
- drawerLeftParams,
1086
- collapse,
1087
- currentSubMenuData,
1088
- showSubMenu,
1089
- currentSubPath,
1090
- } = this.state;
1091
- const { originRoutes, itemPath, defaultSettings, transparentProps = {} } = this.props;
1092
- const TabTitle: React.FC<{}> = ({ item, index, updateState }) => {
1093
- return (
1094
- <div className="tab_title_content">
1095
- {item.tab}
1096
- {item.key !== '/' && (
1097
- <ItemMenu
1098
- info={item}
1099
- operateFun={this.operateFun}
1100
- listenRouterState={listenRouterState}
1101
- />
1102
- )}
1103
- </div>
1104
- );
1105
- };
1106
-
1107
- // 左侧菜单 route
1108
- const dataShowRoute = this.props.routes.find(
1109
- (route) => route.path === '/homePage/data-show',
1110
- ); // 添加数据大屏
1111
- const { route, ...restPrpos } = this.props;
1112
- const exist = route.routes.find(
1113
- (route) => route.path === '/homePage/data-show',
1114
- );
1115
- if (dataShowRoute && !exist) {
1116
- route.routes.splice(1, 0, dataShowRoute);
1117
- }
1118
-
1119
- const menu = (
1120
- <Menu>
1121
- <Menu.Item
1122
- key="0"
1123
- style={{
1124
- background: '#FFFFFF',
1125
- color: '#848484',
1126
- fontSize: '12px',
1127
- textAlign: 'center',
1128
- }}
1129
- >
1130
- <div>已打开的页签数: {listenRouterState.length}</div>
1131
- </Menu.Item>
1132
- <Menu.Item key="1" style={{ fontSize: '12px', textAlign: 'center' }}>
1133
- <a
1134
- onClick={() => {
1135
- // 关闭全部
1136
- this.updateState(
1137
- [
1138
- {
1139
- ...this.state.homeRouter,
1140
- key: '/',
1141
- tab: '欢迎',
1142
- closable: false,
1143
- },
1144
- ],
1145
- ['/'],
1146
- () => {
1147
- history.push('/');
1148
- },
1149
- );
1150
- }}
1151
- >
1152
- 关闭全部标签
1153
- </a>
1154
- </Menu.Item>
1155
- <Menu.Item key="2" style={{ fontSize: '12px', textAlign: 'center' }}>
1156
- <a
1157
- onClick={() => {
1158
- if (activeKey === '/') return;
1159
- const index = listenRouterState.findIndex(
1160
- (item) => item.key === activeKey,
1161
- );
1162
- let newActiveKey = '';
1163
- if (index > 0) {
1164
- newActiveKey = listenRouterState[index - 1].key;
1165
- } else {
1166
- newActiveKey = listenRouterState[1].key;
1167
- }
1168
- this.updateState(
1169
- listenRouterState.filter((d) => d.key !== activeKey),
1170
- listenRouterKey.filter((d) => d !== activeKey),
1171
- () => {
1172
- let newKey = encodeUrlQuery(newActiveKey);
1173
- history.push({
1174
- pathname: newKey,
1175
- });
1176
- },
1177
- );
1178
- }}
1179
- >
1180
- 关闭当前标签
1181
- </a>
1182
- </Menu.Item>
1183
- <Menu.Item key="3" style={{ fontSize: '12px', textAlign: 'center' }}>
1184
- <a
1185
- onClick={() => {
1186
- const index = listenRouterState.findIndex(
1187
- (item) => item.key === activeKey,
1188
- );
1189
- // let deleteKey = listenRouterState[index - 1]?.key;
1190
- // if (deleteKey === '/') {
1191
- // message.warning('首页不可关闭。');
1192
- // return;
1193
- // }
1194
-
1195
- this.updateState(
1196
- listenRouterState.filter(
1197
- (d: any, i: number) => i >= index || d.key === '/',
1198
- ),
1199
- listenRouterKey.filter(
1200
- (d: any, i: number) => i >= index || d === '/',
1201
- ),
1202
- );
1203
- }}
1204
- >
1205
- 关闭其左侧标签
1206
- </a>
1207
- </Menu.Item>
1208
- <Menu.Item key="4" style={{ fontSize: '12px', textAlign: 'center' }}>
1209
- <a
1210
- onClick={() => {
1211
- let index = listenRouterState.findIndex(
1212
- (item) => item.key === activeKey,
1213
- );
1214
- this.updateState(
1215
- listenRouterState.filter(
1216
- (d: any, i: number) => i <= index || d.key === '/',
1217
- ),
1218
- listenRouterKey.filter(
1219
- (d: any, i: number) => i <= index || d === '/',
1220
- ),
1221
- );
1222
- }}
1223
- >
1224
- 关闭其右侧标签
1225
- </a>
1226
- </Menu.Item>
1227
- </Menu>
1228
- );
1229
-
1230
- const filterByMenuDate = (
1231
- data: MenuDataItem[],
1232
- keyWord: string,
1233
- ): MenuDataItem[] =>
1234
- data
1235
- .map((item) => {
1236
- if (item.name && item.name.includes(keyWord)) {
1237
- return {
1238
- ...item,
1239
- };
1240
- }
1241
- return undefined;
1242
- })
1243
- .filter((item) => item) as MenuDataItem[];
1244
-
1245
- let weiqianduanProps = {};
1246
- let isWeiqianduan = false;
1247
-
1248
- if (window.top != window) {
1249
- isWeiqianduan = true;
1250
- weiqianduanProps = {
1251
- headerRender: false,
1252
- footerRender: false,
1253
- menuRender: false,
1254
- menuHeaderRender: false,
1255
- menuExtraRender: false,
1256
- };
1257
- }
1258
-
1259
- const OperationsSlot: Record<PositionType, React.ReactNode> = {
1260
- left: (
1261
- <div className={'tab_left_operate'}>
1262
- <div
1263
- onClick={() => {
1264
- history.push({
1265
- pathname: '/',
1266
- });
1267
- }}
1268
- >
1269
- <HomeOutlined />
1270
- </div>
1271
- <div
1272
- style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1273
- onClick={() => {
1274
- this.setTabNavTransLate(-100);
1275
- }}
1276
- >
1277
- <DoubleLeftOutlined />
1278
- </div>
1279
- </div>
1280
- ),
1281
- right: (
1282
- <div
1283
- style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1284
- className={'tab_right_operate'}
1285
- onClick={() => {
1286
- this.setTabNavTransLate(100);
1287
- }}
1288
- >
1289
- <DoubleRightOutlined />
1290
- </div>
1291
- ),
1292
- };
1293
-
1294
- return (
1295
- <ProLayout
1296
- actionRef={this.actionRef}
1297
- onMenuHeaderClick={() => history.push('/')}
1298
- menuHeaderRender={({ }) => (
1299
- <CustomerMenuHeader
1300
- originRoutes={originRoutes}
1301
- itemPath={itemPath}
1302
- handleClose={this.handleClose}
1303
- collapsed={collapse}
1304
- />
1305
- )}
1306
- menuExtraRender={() => {
1307
- if (!collapse) {
1308
- return (
1309
- <div>
1310
- <CustomerMenu
1311
- originRoutes={originRoutes}
1312
- itemPath={itemPath}
1313
- ref={this.customerMenuRef}
1314
- actionRef={this.actionRef}
1315
- handleClose={this.handleClose}
1316
- isCollapse={this.state.collapse}
1317
- />
1318
- </div>
1319
- );
1320
- }
1321
- return (
1322
- <div className="collapse_icon_close">
1323
- <span
1324
- className="collapse_icon"
1325
- onClick={() => {
1326
- this.setState({
1327
- collapse: !collapse,
1328
- });
1329
- }}
1330
- >
1331
- <MenuUnfoldOutlined />
1332
- </span>
1333
- </div>
1334
- );
1335
- }}
1336
- menuProps={{
1337
- onClick: () => {
1338
- localStorage.setItem('isMenuClick', 'true');
1339
- },
1340
- }}
1341
- collapsed={collapse}
1342
- onCollapse={(boo: boolean) => {
1343
- this.setState({
1344
- collapse: boo,
1345
- });
1346
- }}
1347
- menuItemRender={(menuItemProps, defaultDom) => {
1348
- if (menuItemProps?.path === '/') {
1349
- return (
1350
- <>
1351
- <div className="one_menu_wrap">
1352
- <Link
1353
- onClick={() => {
1354
- localStorage.setItem('isMenuClick', 'true');
1355
- }}
1356
- to={menuItemProps.path}
1357
- >
1358
- {defaultDom}
1359
- </Link>
1360
- </div>
1361
- </>
1362
- );
1363
- }
1364
- return (
1365
- <Link
1366
- onClick={() => {
1367
- localStorage.setItem('isMenuClick', 'true');
1368
- }}
1369
- to={menuItemProps.path}
1370
- >
1371
- {defaultDom}
1372
- </Link>
1373
- );
1374
- }}
1375
- subMenuItemRender={(menuItemProps, defaultDom) => {
1376
- return (
1377
- <div
1378
- style={{
1379
- height: '40px',
1380
- lineHeight: '40px',
1381
- position: 'relative',
1382
- overflow: 'hidden',
1383
- textOverflow: 'ellipsis',
1384
- whiteSpace: 'nowrap',
1385
- boxSizing: 'border-box',
1386
- paddingRight: '10px',
1387
- }}
1388
- onMouseEnter={() => {
1389
- if (
1390
- menuItemProps.pro_layout_parentKeys &&
1391
- menuItemProps.pro_layout_parentKeys.length
1392
- )
1393
- return;
1394
- this.setState({
1395
- currentSubMenuData: menuItemProps.children,
1396
- currentSubPath: menuItemProps.path,
1397
- });
1398
- this.setShowMenu(true);
1399
- }}
1400
- onMouseLeave={() => {
1401
- this.setShowMenu(false);
1402
- }}
1403
- >
1404
- {defaultDom}
1405
- {showSubMenu &&
1406
- currentSubPath === menuItemProps.path &&
1407
- !collapse && (
1408
- <CaretLeftOutlined
1409
- style={{ position: 'absolute', top: '14px', right: '-4px' }}
1410
- />
1411
- )}
1412
- </div>
1413
- );
1414
- }}
1415
- collapsedButtonRender={() => {
1416
- return (
1417
- <div
1418
- onClick={(e) => {
1419
- e.stopPropagation();
1420
- }}
1421
- className="banquan"
1422
- >
1423
- {''}
1424
- </div>
1425
- );
1426
- }}
1427
- postMenuData={(menus) => {
1428
- return [...filterByMenuDate(menus || [], this.state.keyWord)];
1429
- }}
1430
- links={[
1431
- !this.state.collapse ? (
1432
- <AllFunc
1433
- ref={this.allFunc}
1434
- itemPath={itemPath}
1435
- handleClose={this.handleClose}
1436
- isCollapse={this.state.collapse}
1437
- />
1438
- ) : (
1439
- ''
1440
- ),
1441
- ]}
1442
- onPageChange={() => {
1443
- const { location } = history;
1444
- // 如果没有登录,重定向到 login
1445
- if (
1446
- !localStorage.getItem(ENUM.BROWSER_CACHE.USER_INFO) &&
1447
- location.pathname !== '/user/login'
1448
- ) {
1449
- history.push('/user/login');
1450
- }
1451
- }}
1452
- headerRender={(props) => <GlobalHeaderCom {...props} />}
1453
- menu={{
1454
- request: async () => {
1455
- return JSON.parse(
1456
- localStorage.getItem(`customerMenu_${itemPath}_front`) || '[]',
1457
- );
1458
- },
1459
- type: 'group',
1460
- }}
1461
- route={route}
1462
- {...restPrpos}
1463
- {...defaultSettings}
1464
- {...weiqianduanProps}
1465
- >
1466
- <div id="globalTabsContent" className="globalTabs">
1467
- <DraggableTabs
1468
- activeKey={activeKey}
1469
- id="globalTabs"
1470
- onChange={this.onChange}
1471
- // tabBarExtraContent={operations}
1472
- type="editable-card"
1473
- tabBarStyle={{
1474
- background: '#f3f3f3',
1475
- height: '28px',
1476
- marginRight: 0,
1477
- fontSize: '12px',
1478
- color: '#2C2F2E70',
1479
- marginBottom: '-2px',
1480
- position: 'fixed',
1481
- top: 50,
1482
- zIndex: 10,
1483
- width: collapse ? 'calc(100% - 75px)' : 'calc(100% - 167px)',
1484
- display: isWeiqianduan ? 'none' : 'flex',
1485
- }}
1486
- tabPosition="top"
1487
- tabBarGutter={8}
1488
- onEdit={this.onEdit}
1489
- tabBarExtraContent={OperationsSlot}
1490
- animated={false}
1491
- hideAdd
1492
- >
1493
- {listenRouterState.map((item, index) => (
1494
- <TabPane
1495
- tab={
1496
- <TabTitle
1497
- item={item}
1498
- index={index}
1499
- updateState={this.updateState}
1500
- />
1501
- }
1502
- style={{ marginTop: isWeiqianduan ? 0 : 30 }}
1503
- key={item.key}
1504
- closable={item.key !== '/'}
1505
- closeIcon={<img src="./biaoqian-guanbi-icon.svg" />}
1506
- >
1507
- <WrapperComponent
1508
- item={item}
1509
- routerProps={this.props}
1510
- getDictionarySource={this.getDictionarySource}
1511
- getDictionaryTextByValue={this.getDictionaryTextByValue}
1512
- timeFormat={this.timeFormat}
1513
- transparentProps={transparentProps}
1514
- />
1515
- </TabPane>
1516
- ))}
1517
- </DraggableTabs>
1518
- <div
1519
- className="globalTabsOper"
1520
- style={{
1521
- position: 'fixed',
1522
- top: '50px',
1523
- zIndex: 10,
1524
- background: '#fff',
1525
- display: isWeiqianduan ? 'none' : 'block',
1526
- borderLeft: '1px solid #E4E4E4',
1527
- }}
1528
- >
1529
- <Dropdown overlay={menu} trigger={['click']}>
1530
- <a
1531
- className="ant-dropdown-link"
1532
- onClick={(e) => e.preventDefault()}
1533
- >
1534
- <DashOutlined />
1535
- </a>
1536
- </Dropdown>
1537
- </div>
1538
- <SearchFunc itemPath={itemPath} {...drawerLeftParams}></SearchFunc>
1539
- <div
1540
- onMouseEnter={() => {
1541
- this.setShowMenu(true);
1542
- }}
1543
- onMouseLeave={() => {
1544
- this.setShowMenu(false);
1545
- }}
1546
- className={'sub_menu_content'}
1547
- style={{ display: showSubMenu && !collapse ? 'block' : 'none' }}
1548
- >
1549
- {this.getMenuDom(currentSubMenuData)}
1550
- </div>
1551
- </div>
1552
- </ProLayout>
1553
- );
1554
- }
1555
- }
1556
-
1557
- class WrapperComponent extends React.Component {
1558
- constructor(props) {
1559
- super(props);
1560
- }
1561
-
1562
- shouldComponentUpdate(nextProps) {
1563
- if (window.__POWERED_BY_WUJIE__ && nextProps?.item?.key?.indexOf('edit-template-template') > -1) { // 适配wujie环境主应用下渲染打印编辑器
1564
- return true
1565
- }
1566
- return false;
1567
- }
1568
- render() {
1569
- const {
1570
- item,
1571
- routerProps,
1572
- getDictionarySource,
1573
- getDictionaryTextByValue,
1574
- timeFormat,
1575
- transparentProps,
1576
- } = this.props;
1577
- return (
1578
- <>
1579
- {item.isNotFound ? ( <NoFoundPage />) :
1580
- React.createElement(item.content, {
1581
- getDictionarySource: getDictionarySource,
1582
- getDictionaryTextByValue: getDictionaryTextByValue,
1583
- timeFormat: timeFormat,
1584
- ...routerProps,
1585
- ...transparentProps,
1586
- match: item.match,
1587
- })}
1588
- </>
1589
- );
1590
- }
1591
- }
1592
-
1593
- export default (props) => {
1594
- const { initialState = {} } = useModel('@@initialState');
1595
-
1596
- const { dictionaryData } = initialState;
1597
- const intl = useIntl();
1598
- const { formatMessage } = intl;
1599
- return (
1600
- <BasicLayout
1601
- {...props}
1602
- dictionaryData={dictionaryData}
1603
- formatMessage={formatMessage}
1604
- />
1605
- );
1606
- };
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, route?.state);
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
+ // -------------------处理页签关闭----------------------------
518
+ lastTwoRouterArray.push(route.pathname);
519
+ lastTwoRouterArray.shift();
520
+
521
+ const {
522
+ thisHideInMenuDoNotClose = false,
523
+ closePrevPage = false,
524
+ updateCurrentPage = false,
525
+ } = route?.state || {};
526
+
527
+ let needRemoveKey = '';
528
+
529
+ // lastTwoRouterArray[0] != lastTwoRouterArray[1] 该判断条件用于判断是否是tab删除操作,如果是tab页删除操作,删除的是不是最后一个打开的tab页,执行history.push会导致错误的将最后打开的那个tab页也删除掉
530
+ let notSamePageFlag = lastTwoRouterArray[0] != lastTwoRouterArray[1];
531
+
532
+ // 满足包含closePrevPage标识则直接删除上一页
533
+ if (closePrevPage) {
534
+ needRemoveKey = lastTwoRouterArray[0] && typeof lastTwoRouterArray[0] === 'string' && notSamePageFlag ? lastTwoRouterArray[0] : '';
535
+ } else {
536
+ // 满足非tabclick或者menuClick的hideInMenu类型菜单自动关闭
537
+ const shouldClosePrev = (!localStorage.getItem('isTabChange') && !localStorage.getItem('isMenuClick'));
538
+ const needRemoveKeyArray = lastTwoRouterArray[0] && typeof lastTwoRouterArray[0] === 'string' && shouldClosePrev ?
539
+ hideMenuArray.filter((itemRoute) =>
540
+ pathToRegexp(itemRoute.path || '').test(lastTwoRouterArray[0]),
541
+ ) : [];
542
+ needRemoveKey = needRemoveKeyArray.length && notSamePageFlag && !thisHideInMenuDoNotClose ? needRemoveKeyArray[0] : '';
543
+ }
544
+
545
+ if (needRemoveKey) {
546
+ newListenRouterState = newListenRouterState.filter((item) => {
547
+ const [pathname] = item.key ? item.key.split('?') : [];
548
+ return pathname && pathname !== lastTwoRouterArray[0];
549
+ });
550
+ newListenRouterKey = newListenRouterKey.filter((item) => {
551
+ const [pathname] = item ? item.split('?') : [];
552
+ return pathname && pathname !== lastTwoRouterArray[0];
553
+ });
554
+ }
555
+
556
+ setTimeout(() => {
557
+ // 处理页面刷新两面
558
+ localStorage.removeItem('isTabChange');
559
+ localStorage.removeItem('isMenuClick');
560
+ }, 0);
561
+
562
+ // -------------------处理页签关闭 end----------------------------
563
+
564
+ this.setState(
565
+ {
566
+ //路由监听函数最后执行setState,避免处理hideMenu类型页面自动关闭的逻辑块内获取不到最新state的listenRouterState和listenRouterKey
567
+ activeKey: currentKey,
568
+ listenRouterState: newListenRouterState,
569
+ listenRouterKey: newListenRouterKey,
570
+ },
571
+ () => {
572
+ this.checkisNavSlide();
573
+ },
574
+ );
575
+
576
+ istParent = 0;
577
+ });
578
+
579
+ if (localStorage.getItem('mainRoutePath') && localStorage.getItem('mainRoutePath')?.startsWith(`/${itemPath}/`)) {
580
+ istParent = 1;
581
+ history.push(localStorage.getItem('mainRoutePath').replace(/^\/\w+\//, '/'))
582
+ } else if (localStorage.getItem('firstPage') && localStorage.getItem('firstPage')?.startsWith(`#/${itemPath}/`)) {
583
+ // 暂时保留,兼容老版本
584
+ istParent = 1;
585
+ history.push(
586
+ localStorage
587
+ .getItem('firstPage')
588
+ ?.slice(1)
589
+ .replace(/^\/\w+\//, '/'),
590
+ );
591
+ } else {
592
+ history.push(location);
593
+ }
594
+ }
595
+
596
+ componentWillUnmount() {
597
+ // eslint-disable-next-line no-unused-expressions
598
+ UN_LISTTEN_DRP && UN_LISTTEN_DRP();
599
+ }
600
+
601
+ parseQueryString = (queryString) => {
602
+ if (!queryString) {
603
+ return '';
604
+ }
605
+
606
+ if (queryString.indexOf('?') < 0) {
607
+ return `?${queryString}`;
608
+ }
609
+
610
+ return queryString;
611
+ };
612
+
613
+ updateTree = (Tree, authMenuKeys = []) => {
614
+ const treeData = Tree;
615
+ const treeList = [];
616
+
617
+
618
+
619
+ // 是否为权限菜单路径
620
+ const getLimitedMenuPath = (node) => {
621
+ return authMenuKeys.some(item => (node.path || '').includes(item));
622
+ }
623
+
624
+ // 是否为通用单据菜单路径
625
+ const getGenerateDocs = (node) => {
626
+ return (node.path || '').includes('all-general-documents');
627
+ }
628
+
629
+ // 递归获取树列表
630
+ const getTreeList = (data) => {
631
+ data.forEach((node) => {
632
+ if (node.routes && node.routes.length > 0) {
633
+ getTreeList(node.routes);
634
+ return;
635
+ }
636
+ // todo:暂时处理非wujie环境不做404管控
637
+ if (!window.__POWERED_BY_WUJIE__) {
638
+ treeList.push({
639
+ tab: node.locale,
640
+ key: node.path,
641
+ locale: node.locale,
642
+ closable: true,
643
+ content: node.component,
644
+ name: node.name,
645
+ hideInMenu: node.hideInMenu,
646
+ isOnlyOnePage: node.isOnlyOnePage,
647
+ });
648
+ return;
649
+ }
650
+ if (node.path === '/' || getLimitedMenuPath(node) || getGenerateDocs(node) || node.noAuth) {
651
+ treeList.push({
652
+ tab: node.locale,
653
+ key: node.path,
654
+ locale: node.locale,
655
+ closable: true,
656
+ content: node.component,
657
+ name: node.name,
658
+ hideInMenu: node.hideInMenu,
659
+ isOnlyOnePage: node.isOnlyOnePage,
660
+ });
661
+ }
662
+ });
663
+ };
664
+ getTreeList(treeData);
665
+ return treeList;
666
+ };
667
+
668
+ getDictionarySource = (dicCode: string, needConvertInterger = false) => {
669
+ const { dictionaryData } = this.props;
670
+
671
+ let dicData = {};
672
+
673
+ if (!dictionaryData) {
674
+ let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
675
+ ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
676
+ : {};
677
+ dicData = storageDic[dicCode];
678
+ } else {
679
+ dicData = dictionaryData[dicCode];
680
+ }
681
+ // if (!dicData || !dicData.length) {
682
+ // throw new Error(`当前没有${dicCode}字典值`);
683
+ // }
684
+
685
+ try {
686
+ if (needConvertInterger) {
687
+ dicData = dicData.map((item: { text: string; value: string }) => ({
688
+ ...item,
689
+ value: parseFloat(item.value),
690
+ }));
691
+ }
692
+ } catch (e) { }
693
+
694
+ return dicData;
695
+ };
696
+
697
+ getDictionaryTextByValue = (dicCode: string, value: string) => {
698
+ let startPerformance = performance.now();
699
+ if (window.dicDataTextValue) {
700
+ const dicDataTextValue = window.dicDataTextValue;
701
+ let dicData = [];
702
+
703
+ dicData = dicDataTextValue[dicCode];
704
+
705
+ let endPerformance1 = performance.now();
706
+
707
+ console.log("字典方法时间花费1:", endPerformance1 - startPerformance);
708
+
709
+ if (value === undefined) return "- -";
710
+
711
+ if (!dicData) {
712
+ // throw new Error(`当前${dicCode}字典值合没有${value}的数据`)
713
+ return value;
714
+ }
715
+
716
+ let endPerformance = performance.now();
717
+
718
+ console.log("字典方法时间花费:", endPerformance - startPerformance);
719
+
720
+ return dicData[value] || value;
721
+ }
722
+ let dicData = [];
723
+ let dictionaryData: any;
724
+ if (!dictionaryData) {
725
+ let storageDic = localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES)
726
+ ? JSON.parse(localStorage.getItem(ENUM.BROWSER_CACHE.DICT_CODES))
727
+ : {};
728
+ dicData = storageDic[dicCode];
729
+ } else {
730
+ dicData = dictionaryData[dicCode];
731
+ }
732
+
733
+ if (!dicData || !dicData.length) {
734
+ // throw new Error(`当前没有${dicCode}字典值`);
735
+ }
736
+
737
+ if (value === undefined) return '- -';
738
+
739
+ const dicItemArray = dicData?.filter(
740
+ (item: { value: string }) => item.value === value.toString(),
741
+ );
742
+
743
+ if (!dicItemArray?.length) {
744
+ // throw new Error(`当前${dicCode}字典值合没有${value}的数据`)
745
+ return value;
746
+ }
747
+
748
+ return dicItemArray[0].text;
749
+ };
750
+
751
+ timeFormat = (timeStr, format, notNeedConvertTimeZone) => {
752
+ if (!timeStr) return '- -';
753
+
754
+ if (notNeedConvertTimeZone) {
755
+ return moment(timeStr).format(format);
756
+ }
757
+
758
+ return moment(timeStr).add(8, 'hours').format(format) || '- -';
759
+ };
760
+
761
+ onChange = (key) => {
762
+ if (key !== this.state.activeKey) {
763
+ this.setState({
764
+ activeKey: key,
765
+ });
766
+ localStorage.setItem('isTabChange', '1');
767
+ let newKey = encodeUrlQuery(key);
768
+ history.push(newKey);
769
+ }
770
+ };
771
+
772
+ getPageTitle = (pathname) => {
773
+ const { formatMessage } = this.props;
774
+ const { breadcrumbNameMap } = this.state;
775
+ const currRouterData = this.matchParamsPath(pathname, breadcrumbNameMap);
776
+
777
+ if (!currRouterData) {
778
+ return '';
779
+ }
780
+ const pageName = formatMessage({
781
+ id: currRouterData.locale || currRouterData.name,
782
+ defaultMessage: currRouterData.name,
783
+ });
784
+
785
+ return `${pageName}`;
786
+ };
787
+
788
+ matchParamsPath = (pathname, breadcrumbNameMap) => {
789
+ const { pathToRegexp } = this.props;
790
+ const pathKey = Object.keys(breadcrumbNameMap).find((key) =>
791
+ pathToRegexp(key).test(pathname),
792
+ );
793
+ return breadcrumbNameMap[pathKey];
794
+ };
795
+
796
+ onEdit = (
797
+ targetKey: React.MouseEvent | React.KeyboardEvent | string,
798
+ action: string,
799
+ ) => {
800
+ this.tabActions[action](targetKey);
801
+ };
802
+
803
+ tabActions: any = {
804
+ remove: (targetKey: string) => {
805
+ const { listenRouterState, activeKey, customerMatchs, listenRouterKey } =
806
+ this.state;
807
+
808
+ let lastIndex: number = 0;
809
+ let newActiveKey: string | undefined = activeKey;
810
+ let newListenRouterState = [];
811
+ let newListenRouterKey = [];
812
+
813
+ if (targetKey === activeKey) {
814
+ listenRouterState.forEach((pane, i) => {
815
+ if (pane.key === targetKey) {
816
+ lastIndex = i - 1;
817
+ }
818
+ });
819
+
820
+ newListenRouterState = listenRouterState.filter(
821
+ (item) => item.key !== targetKey,
822
+ );
823
+ newListenRouterKey = listenRouterKey.filter(
824
+ (item) => item !== targetKey,
825
+ );
826
+
827
+ if (lastIndex < 0) {
828
+ lastIndex = 0;
829
+ }
830
+
831
+ newActiveKey = newListenRouterState[lastIndex].key;
832
+ } else {
833
+ newListenRouterState = listenRouterState.filter(
834
+ (item) => item.key !== targetKey,
835
+ );
836
+ newListenRouterKey = listenRouterKey.filter(
837
+ (item) => item !== targetKey,
838
+ );
839
+ }
840
+
841
+ this.setState(
842
+ {
843
+ activeKey: newActiveKey,
844
+ listenRouterState: newListenRouterState,
845
+ listenRouterKey: newListenRouterKey,
846
+ },
847
+ () => {
848
+ let newKey = encodeUrlQuery(newActiveKey);
849
+ history.push({
850
+ pathname: newKey,
851
+ });
852
+ this.checkisNavSlide();
853
+ },
854
+ );
855
+ },
856
+ };
857
+
858
+ updateState = (newListenRouterState, newListenRouterKey, cb) => {
859
+ this.setState(
860
+ {
861
+ listenRouterState: newListenRouterState,
862
+ listenRouterKey: newListenRouterKey,
863
+ },
864
+ () => {
865
+ this.checkisNavSlide();
866
+ if (cb) cb();
867
+ },
868
+ );
869
+ };
870
+
871
+ handleClose = () => {
872
+ this.setState({
873
+ drawerLeftParams: {
874
+ ...this.state.drawerLeftParams,
875
+ visible: false,
876
+ },
877
+ isCollapse: true,
878
+ });
879
+ this.allFunc.current?.close?.();
880
+ this.customerMenuRef.current?.close?.();
881
+ };
882
+
883
+ handleMenuClick = (item: any) => {
884
+ if (item.children || !item.component) return;
885
+ let newKey = encodeUrlQuery(item.path);
886
+ history.push({
887
+ pathname: newKey,
888
+ });
889
+ this.setShowMenu(false);
890
+ };
891
+
892
+ getMenuDom = (menuData) => {
893
+ return menuData.map((item) => (
894
+ <div>
895
+ <div
896
+ onClick={() => {
897
+ this.handleMenuClick(item);
898
+ }}
899
+ className={`${'menu_item'} ${item.children || !item.component ? '' : 'link_style'
900
+ }`}
901
+ style={{
902
+ fontWeight: item.children || !item.component ? 'bolder' : '400',
903
+ paddingLeft: '10px',
904
+ marginTop: item.children || !item.component ? '5px' : '0px',
905
+ fontSize: item.children || !item.component ? '14px' : '12px',
906
+ }}
907
+ >
908
+ {item.name}
909
+ </div>
910
+ {!!item.children &&
911
+ !!item.children.length &&
912
+ this.getMenuDom(item.children)}
913
+ </div>
914
+ ));
915
+ };
916
+
917
+ setShowMenu = debounce((isShow) => {
918
+ this.setState({
919
+ showSubMenu: isShow,
920
+ });
921
+ }, 500);
922
+
923
+ //设置tabs标签左右滚动
924
+ setTabNavTransLate = (num) => {
925
+ let globalTabsNav = document
926
+ .getElementById('globalTabs')
927
+ ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
928
+ let globalTabsNavWrap = document
929
+ .getElementById('globalTabs')
930
+ ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
931
+ let wrapWidth = globalTabsNavWrap.offsetWidth; //tabsNav父节点宽度
932
+ let navListWidth = globalTabsNav.offsetWidth; //tabsNav总宽度
933
+ if (navListWidth - wrapWidth <= 0) return;
934
+ let maxTransX = navListWidth - wrapWidth; // 允许移动最大宽度
935
+ let transXStr = document.defaultView?.getComputedStyle(
936
+ globalTabsNav,
937
+ null,
938
+ ).transform;
939
+ let transx = transXStr?.split(',')[4]; //当前translateX的值
940
+
941
+ let targetTransX = Math.abs(Number(transx)) + num;
942
+ if (targetTransX <= 0) targetTransX = 0;
943
+ if (targetTransX >= Number(maxTransX)) targetTransX = Number(maxTransX);
944
+ globalTabsNav.style.transform = 'translateX(-' + targetTransX + 'px)';
945
+ };
946
+
947
+ checkisNavSlide = () => {
948
+ if (window.top != window) return;
949
+ //监听tabs页签总长度判断是否可点击滑动
950
+ let globalTabsNav = document
951
+ .getElementById('globalTabs')
952
+ ?.getElementsByClassName('ant-tabs-nav-list')?.[0];
953
+ let globalTabsNavWrap = document
954
+ .getElementById('globalTabs')
955
+ ?.getElementsByClassName('ant-tabs-nav-wrap')?.[0];
956
+ let wrapWidth = globalTabsNavWrap?.offsetWidth; //tabsNav父节点宽度
957
+ let navListWidth = globalTabsNav?.offsetWidth; //tabsNav总宽度
958
+ if (navListWidth - wrapWidth <= 0) {
959
+ this.setState({
960
+ isSlider: false,
961
+ });
962
+ return;
963
+ }
964
+ this.setState({
965
+ isSlider: true,
966
+ });
967
+ };
968
+
969
+ changeListenRouterState = (dragIndex: number, hoverIndex: number) => {
970
+ const { listenRouterState, listenRouterKey } = this.state;
971
+ let dragItem = listenRouterState[dragIndex];
972
+ let dragKeyItem = listenRouterKey[dragIndex];
973
+
974
+ listenRouterState.splice(dragIndex, 1);
975
+ listenRouterState.splice(hoverIndex, 0, dragItem);
976
+
977
+ listenRouterKey.splice(dragIndex, 1);
978
+ listenRouterKey.splice(hoverIndex, 0, dragKeyItem);
979
+ };
980
+
981
+ operateFun = (key, type) => {
982
+ const { listenRouterState, activeKey, listenRouterKey } = this.state;
983
+ let deleteKey = '';
984
+ let newlistenRouterState = [];
985
+ let newlistenRouterKey = [];
986
+ let newActiveKey = '';
987
+ let deleteIndex = 0;
988
+ if (type === 'self') {
989
+ deleteIndex = listenRouterState.findIndex((item) => item.key === key);
990
+ deleteKey = key;
991
+ if (deleteIndex > 0) {
992
+ newActiveKey = listenRouterState[deleteIndex - 1].key;
993
+ } else {
994
+ newActiveKey = listenRouterState[1].key;
995
+ }
996
+ newlistenRouterState = listenRouterState.filter((d) => d.key !== key);
997
+ newlistenRouterKey = listenRouterKey.filter((d) => d !== key);
998
+ this.updateState(newlistenRouterState, newlistenRouterKey, () => {
999
+ if (deleteKey === activeKey) {
1000
+ let newKey = encodeUrlQuery(newActiveKey);
1001
+ history.push({
1002
+ pathname: newKey,
1003
+ });
1004
+ }
1005
+ });
1006
+ }
1007
+ if (type === 'left') {
1008
+ const index = listenRouterState.findIndex((item) => item.key === key);
1009
+ newlistenRouterState = listenRouterState.filter(
1010
+ (d: any, i: number) => i >= index || d.key === '/',
1011
+ );
1012
+ newlistenRouterKey = listenRouterKey.filter(
1013
+ (d: any, i: number) => i >= index || d === '/',
1014
+ );
1015
+ this.updateState(newlistenRouterState, newlistenRouterKey, () => {
1016
+ if (newlistenRouterKey.find((item) => item === activeKey)) {
1017
+ return;
1018
+ } else {
1019
+ let newKey = encodeUrlQuery(key);
1020
+ history.push({
1021
+ pathname: newKey,
1022
+ });
1023
+ }
1024
+ });
1025
+ }
1026
+ if (type === 'right') {
1027
+ const index = listenRouterState.findIndex((item) => item.key === key);
1028
+ newlistenRouterState = listenRouterState.filter(
1029
+ (d: any, i: number) => i <= index || d.key === '/',
1030
+ );
1031
+ newlistenRouterKey = listenRouterKey.filter(
1032
+ (d: any, i: number) => i <= index || d === '/',
1033
+ );
1034
+ this.updateState(
1035
+ listenRouterState.filter(
1036
+ (d: any, i: number) => i <= index || d.key === '/',
1037
+ ),
1038
+ listenRouterKey.filter((d: any, i: number) => i <= index || d === '/'),
1039
+ () => {
1040
+ if (newlistenRouterKey.find((item) => item === activeKey)) {
1041
+ return;
1042
+ } else {
1043
+ let newKey = encodeUrlQuery(key);
1044
+ history.push({
1045
+ pathname: newKey,
1046
+ });
1047
+ }
1048
+ },
1049
+ );
1050
+ }
1051
+ if (type === 'all') {
1052
+ this.updateState(
1053
+ listenRouterState.filter((item) => item.key === '/'),
1054
+ listenRouterKey.filter((item) => item === '/'),
1055
+ () => {
1056
+ history.push({
1057
+ pathname: '/',
1058
+ });
1059
+ },
1060
+ );
1061
+ }
1062
+ if (type === 'other') {
1063
+ this.updateState(
1064
+ listenRouterState.filter(
1065
+ (item) => item.key === key || item.key === '/',
1066
+ ),
1067
+ listenRouterKey.filter((item) => item === key || item === '/'),
1068
+ () => {
1069
+ if (key !== activeKey) {
1070
+ let newKey = encodeUrlQuery(key);
1071
+ history.push({
1072
+ pathname: newKey,
1073
+ });
1074
+ }
1075
+ },
1076
+ );
1077
+ }
1078
+ };
1079
+
1080
+ render() {
1081
+ const {
1082
+ listenRouterState,
1083
+ activeKey,
1084
+ listenRouterKey,
1085
+ drawerLeftParams,
1086
+ collapse,
1087
+ currentSubMenuData,
1088
+ showSubMenu,
1089
+ currentSubPath,
1090
+ } = this.state;
1091
+ const { originRoutes, itemPath, defaultSettings, transparentProps = {} } = this.props;
1092
+ const TabTitle: React.FC<{}> = ({ item, index, updateState }) => {
1093
+ return (
1094
+ <div className="tab_title_content">
1095
+ {item.tab}
1096
+ {item.key !== '/' && (
1097
+ <ItemMenu
1098
+ info={item}
1099
+ operateFun={this.operateFun}
1100
+ listenRouterState={listenRouterState}
1101
+ />
1102
+ )}
1103
+ </div>
1104
+ );
1105
+ };
1106
+
1107
+ // 左侧菜单 route
1108
+ const dataShowRoute = this.props.routes.find(
1109
+ (route) => route.path === '/homePage/data-show',
1110
+ ); // 添加数据大屏
1111
+ const { route, ...restPrpos } = this.props;
1112
+ const exist = route.routes.find(
1113
+ (route) => route.path === '/homePage/data-show',
1114
+ );
1115
+ if (dataShowRoute && !exist) {
1116
+ route.routes.splice(1, 0, dataShowRoute);
1117
+ }
1118
+
1119
+ const menu = (
1120
+ <Menu>
1121
+ <Menu.Item
1122
+ key="0"
1123
+ style={{
1124
+ background: '#FFFFFF',
1125
+ color: '#848484',
1126
+ fontSize: '12px',
1127
+ textAlign: 'center',
1128
+ }}
1129
+ >
1130
+ <div>已打开的页签数: {listenRouterState.length}</div>
1131
+ </Menu.Item>
1132
+ <Menu.Item key="1" style={{ fontSize: '12px', textAlign: 'center' }}>
1133
+ <a
1134
+ onClick={() => {
1135
+ // 关闭全部
1136
+ this.updateState(
1137
+ [
1138
+ {
1139
+ ...this.state.homeRouter,
1140
+ key: '/',
1141
+ tab: '欢迎',
1142
+ closable: false,
1143
+ },
1144
+ ],
1145
+ ['/'],
1146
+ () => {
1147
+ history.push('/');
1148
+ },
1149
+ );
1150
+ }}
1151
+ >
1152
+ 关闭全部标签
1153
+ </a>
1154
+ </Menu.Item>
1155
+ <Menu.Item key="2" style={{ fontSize: '12px', textAlign: 'center' }}>
1156
+ <a
1157
+ onClick={() => {
1158
+ if (activeKey === '/') return;
1159
+ const index = listenRouterState.findIndex(
1160
+ (item) => item.key === activeKey,
1161
+ );
1162
+ let newActiveKey = '';
1163
+ if (index > 0) {
1164
+ newActiveKey = listenRouterState[index - 1].key;
1165
+ } else {
1166
+ newActiveKey = listenRouterState[1].key;
1167
+ }
1168
+ this.updateState(
1169
+ listenRouterState.filter((d) => d.key !== activeKey),
1170
+ listenRouterKey.filter((d) => d !== activeKey),
1171
+ () => {
1172
+ let newKey = encodeUrlQuery(newActiveKey);
1173
+ history.push({
1174
+ pathname: newKey,
1175
+ });
1176
+ },
1177
+ );
1178
+ }}
1179
+ >
1180
+ 关闭当前标签
1181
+ </a>
1182
+ </Menu.Item>
1183
+ <Menu.Item key="3" style={{ fontSize: '12px', textAlign: 'center' }}>
1184
+ <a
1185
+ onClick={() => {
1186
+ const index = listenRouterState.findIndex(
1187
+ (item) => item.key === activeKey,
1188
+ );
1189
+ // let deleteKey = listenRouterState[index - 1]?.key;
1190
+ // if (deleteKey === '/') {
1191
+ // message.warning('首页不可关闭。');
1192
+ // return;
1193
+ // }
1194
+
1195
+ this.updateState(
1196
+ listenRouterState.filter(
1197
+ (d: any, i: number) => i >= index || d.key === '/',
1198
+ ),
1199
+ listenRouterKey.filter(
1200
+ (d: any, i: number) => i >= index || d === '/',
1201
+ ),
1202
+ );
1203
+ }}
1204
+ >
1205
+ 关闭其左侧标签
1206
+ </a>
1207
+ </Menu.Item>
1208
+ <Menu.Item key="4" style={{ fontSize: '12px', textAlign: 'center' }}>
1209
+ <a
1210
+ onClick={() => {
1211
+ let index = listenRouterState.findIndex(
1212
+ (item) => item.key === activeKey,
1213
+ );
1214
+ this.updateState(
1215
+ listenRouterState.filter(
1216
+ (d: any, i: number) => i <= index || d.key === '/',
1217
+ ),
1218
+ listenRouterKey.filter(
1219
+ (d: any, i: number) => i <= index || d === '/',
1220
+ ),
1221
+ );
1222
+ }}
1223
+ >
1224
+ 关闭其右侧标签
1225
+ </a>
1226
+ </Menu.Item>
1227
+ </Menu>
1228
+ );
1229
+
1230
+ const filterByMenuDate = (
1231
+ data: MenuDataItem[],
1232
+ keyWord: string,
1233
+ ): MenuDataItem[] =>
1234
+ data
1235
+ .map((item) => {
1236
+ if (item.name && item.name.includes(keyWord)) {
1237
+ return {
1238
+ ...item,
1239
+ };
1240
+ }
1241
+ return undefined;
1242
+ })
1243
+ .filter((item) => item) as MenuDataItem[];
1244
+
1245
+ let weiqianduanProps = {};
1246
+ let isWeiqianduan = false;
1247
+
1248
+ if (window.top != window) {
1249
+ isWeiqianduan = true;
1250
+ weiqianduanProps = {
1251
+ headerRender: false,
1252
+ footerRender: false,
1253
+ menuRender: false,
1254
+ menuHeaderRender: false,
1255
+ menuExtraRender: false,
1256
+ };
1257
+ }
1258
+
1259
+ const OperationsSlot: Record<PositionType, React.ReactNode> = {
1260
+ left: (
1261
+ <div className={'tab_left_operate'}>
1262
+ <div
1263
+ onClick={() => {
1264
+ history.push({
1265
+ pathname: '/',
1266
+ });
1267
+ }}
1268
+ >
1269
+ <HomeOutlined />
1270
+ </div>
1271
+ <div
1272
+ style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1273
+ onClick={() => {
1274
+ this.setTabNavTransLate(-100);
1275
+ }}
1276
+ >
1277
+ <DoubleLeftOutlined />
1278
+ </div>
1279
+ </div>
1280
+ ),
1281
+ right: (
1282
+ <div
1283
+ style={{ opacity: this.state.isSlider ? 1 : 0.5 }}
1284
+ className={'tab_right_operate'}
1285
+ onClick={() => {
1286
+ this.setTabNavTransLate(100);
1287
+ }}
1288
+ >
1289
+ <DoubleRightOutlined />
1290
+ </div>
1291
+ ),
1292
+ };
1293
+
1294
+ return (
1295
+ <ProLayout
1296
+ actionRef={this.actionRef}
1297
+ onMenuHeaderClick={() => history.push('/')}
1298
+ menuHeaderRender={({ }) => (
1299
+ <CustomerMenuHeader
1300
+ originRoutes={originRoutes}
1301
+ itemPath={itemPath}
1302
+ handleClose={this.handleClose}
1303
+ collapsed={collapse}
1304
+ />
1305
+ )}
1306
+ menuExtraRender={() => {
1307
+ if (!collapse) {
1308
+ return (
1309
+ <div>
1310
+ <CustomerMenu
1311
+ originRoutes={originRoutes}
1312
+ itemPath={itemPath}
1313
+ ref={this.customerMenuRef}
1314
+ actionRef={this.actionRef}
1315
+ handleClose={this.handleClose}
1316
+ isCollapse={this.state.collapse}
1317
+ />
1318
+ </div>
1319
+ );
1320
+ }
1321
+ return (
1322
+ <div className="collapse_icon_close">
1323
+ <span
1324
+ className="collapse_icon"
1325
+ onClick={() => {
1326
+ this.setState({
1327
+ collapse: !collapse,
1328
+ });
1329
+ }}
1330
+ >
1331
+ <MenuUnfoldOutlined />
1332
+ </span>
1333
+ </div>
1334
+ );
1335
+ }}
1336
+ menuProps={{
1337
+ onClick: () => {
1338
+ localStorage.setItem('isMenuClick', 'true');
1339
+ },
1340
+ }}
1341
+ collapsed={collapse}
1342
+ onCollapse={(boo: boolean) => {
1343
+ this.setState({
1344
+ collapse: boo,
1345
+ });
1346
+ }}
1347
+ menuItemRender={(menuItemProps, defaultDom) => {
1348
+ if (menuItemProps?.path === '/') {
1349
+ return (
1350
+ <>
1351
+ <div className="one_menu_wrap">
1352
+ <Link
1353
+ onClick={() => {
1354
+ localStorage.setItem('isMenuClick', 'true');
1355
+ }}
1356
+ to={menuItemProps.path}
1357
+ >
1358
+ {defaultDom}
1359
+ </Link>
1360
+ </div>
1361
+ </>
1362
+ );
1363
+ }
1364
+ return (
1365
+ <Link
1366
+ onClick={() => {
1367
+ localStorage.setItem('isMenuClick', 'true');
1368
+ }}
1369
+ to={menuItemProps.path}
1370
+ >
1371
+ {defaultDom}
1372
+ </Link>
1373
+ );
1374
+ }}
1375
+ subMenuItemRender={(menuItemProps, defaultDom) => {
1376
+ return (
1377
+ <div
1378
+ style={{
1379
+ height: '40px',
1380
+ lineHeight: '40px',
1381
+ position: 'relative',
1382
+ overflow: 'hidden',
1383
+ textOverflow: 'ellipsis',
1384
+ whiteSpace: 'nowrap',
1385
+ boxSizing: 'border-box',
1386
+ paddingRight: '10px',
1387
+ }}
1388
+ onMouseEnter={() => {
1389
+ if (
1390
+ menuItemProps.pro_layout_parentKeys &&
1391
+ menuItemProps.pro_layout_parentKeys.length
1392
+ )
1393
+ return;
1394
+ this.setState({
1395
+ currentSubMenuData: menuItemProps.children,
1396
+ currentSubPath: menuItemProps.path,
1397
+ });
1398
+ this.setShowMenu(true);
1399
+ }}
1400
+ onMouseLeave={() => {
1401
+ this.setShowMenu(false);
1402
+ }}
1403
+ >
1404
+ {defaultDom}
1405
+ {showSubMenu &&
1406
+ currentSubPath === menuItemProps.path &&
1407
+ !collapse && (
1408
+ <CaretLeftOutlined
1409
+ style={{ position: 'absolute', top: '14px', right: '-4px' }}
1410
+ />
1411
+ )}
1412
+ </div>
1413
+ );
1414
+ }}
1415
+ collapsedButtonRender={() => {
1416
+ return (
1417
+ <div
1418
+ onClick={(e) => {
1419
+ e.stopPropagation();
1420
+ }}
1421
+ className="banquan"
1422
+ >
1423
+ {''}
1424
+ </div>
1425
+ );
1426
+ }}
1427
+ postMenuData={(menus) => {
1428
+ return [...filterByMenuDate(menus || [], this.state.keyWord)];
1429
+ }}
1430
+ links={[
1431
+ !this.state.collapse ? (
1432
+ <AllFunc
1433
+ ref={this.allFunc}
1434
+ itemPath={itemPath}
1435
+ handleClose={this.handleClose}
1436
+ isCollapse={this.state.collapse}
1437
+ />
1438
+ ) : (
1439
+ ''
1440
+ ),
1441
+ ]}
1442
+ onPageChange={() => {
1443
+ const { location } = history;
1444
+ // 如果没有登录,重定向到 login
1445
+ if (
1446
+ !localStorage.getItem(ENUM.BROWSER_CACHE.USER_INFO) &&
1447
+ location.pathname !== '/user/login'
1448
+ ) {
1449
+ history.push('/user/login');
1450
+ }
1451
+ }}
1452
+ headerRender={(props) => <GlobalHeaderCom {...props} />}
1453
+ menu={{
1454
+ request: async () => {
1455
+ return JSON.parse(
1456
+ localStorage.getItem(`customerMenu_${itemPath}_front`) || '[]',
1457
+ );
1458
+ },
1459
+ type: 'group',
1460
+ }}
1461
+ route={route}
1462
+ {...restPrpos}
1463
+ {...defaultSettings}
1464
+ {...weiqianduanProps}
1465
+ >
1466
+ <div id="globalTabsContent" className="globalTabs">
1467
+ <DraggableTabs
1468
+ activeKey={activeKey}
1469
+ id="globalTabs"
1470
+ onChange={this.onChange}
1471
+ // tabBarExtraContent={operations}
1472
+ type="editable-card"
1473
+ tabBarStyle={{
1474
+ background: '#f3f3f3',
1475
+ height: '28px',
1476
+ marginRight: 0,
1477
+ fontSize: '12px',
1478
+ color: '#2C2F2E70',
1479
+ marginBottom: '-2px',
1480
+ position: 'fixed',
1481
+ top: 50,
1482
+ zIndex: 10,
1483
+ width: collapse ? 'calc(100% - 75px)' : 'calc(100% - 167px)',
1484
+ display: isWeiqianduan ? 'none' : 'flex',
1485
+ }}
1486
+ tabPosition="top"
1487
+ tabBarGutter={8}
1488
+ onEdit={this.onEdit}
1489
+ tabBarExtraContent={OperationsSlot}
1490
+ animated={false}
1491
+ hideAdd
1492
+ >
1493
+ {listenRouterState.map((item, index) => (
1494
+ <TabPane
1495
+ tab={
1496
+ <TabTitle
1497
+ item={item}
1498
+ index={index}
1499
+ updateState={this.updateState}
1500
+ />
1501
+ }
1502
+ style={{ marginTop: isWeiqianduan ? 0 : 30 }}
1503
+ key={item.key}
1504
+ closable={item.key !== '/'}
1505
+ closeIcon={<img src="./biaoqian-guanbi-icon.svg" />}
1506
+ >
1507
+ <WrapperComponent
1508
+ item={item}
1509
+ routerProps={this.props}
1510
+ getDictionarySource={this.getDictionarySource}
1511
+ getDictionaryTextByValue={this.getDictionaryTextByValue}
1512
+ timeFormat={this.timeFormat}
1513
+ transparentProps={transparentProps}
1514
+ />
1515
+ </TabPane>
1516
+ ))}
1517
+ </DraggableTabs>
1518
+ <div
1519
+ className="globalTabsOper"
1520
+ style={{
1521
+ position: 'fixed',
1522
+ top: '50px',
1523
+ zIndex: 10,
1524
+ background: '#fff',
1525
+ display: isWeiqianduan ? 'none' : 'block',
1526
+ borderLeft: '1px solid #E4E4E4',
1527
+ }}
1528
+ >
1529
+ <Dropdown overlay={menu} trigger={['click']}>
1530
+ <a
1531
+ className="ant-dropdown-link"
1532
+ onClick={(e) => e.preventDefault()}
1533
+ >
1534
+ <DashOutlined />
1535
+ </a>
1536
+ </Dropdown>
1537
+ </div>
1538
+ <SearchFunc itemPath={itemPath} {...drawerLeftParams}></SearchFunc>
1539
+ <div
1540
+ onMouseEnter={() => {
1541
+ this.setShowMenu(true);
1542
+ }}
1543
+ onMouseLeave={() => {
1544
+ this.setShowMenu(false);
1545
+ }}
1546
+ className={'sub_menu_content'}
1547
+ style={{ display: showSubMenu && !collapse ? 'block' : 'none' }}
1548
+ >
1549
+ {this.getMenuDom(currentSubMenuData)}
1550
+ </div>
1551
+ </div>
1552
+ </ProLayout>
1553
+ );
1554
+ }
1555
+ }
1556
+
1557
+ class WrapperComponent extends React.Component {
1558
+ constructor(props) {
1559
+ super(props);
1560
+ }
1561
+
1562
+ shouldComponentUpdate(nextProps) {
1563
+ if (window.__POWERED_BY_WUJIE__ && nextProps?.item?.key?.indexOf('edit-template-template') > -1) { // 适配wujie环境主应用下渲染打印编辑器
1564
+ return true
1565
+ }
1566
+ return false;
1567
+ }
1568
+ render() {
1569
+ const {
1570
+ item,
1571
+ routerProps,
1572
+ getDictionarySource,
1573
+ getDictionaryTextByValue,
1574
+ timeFormat,
1575
+ transparentProps,
1576
+ } = this.props;
1577
+ return (
1578
+ <>
1579
+ {item.isNotFound ? ( <NoFoundPage />) :
1580
+ React.createElement(item.content, {
1581
+ getDictionarySource: getDictionarySource,
1582
+ getDictionaryTextByValue: getDictionaryTextByValue,
1583
+ timeFormat: timeFormat,
1584
+ ...routerProps,
1585
+ ...transparentProps,
1586
+ match: item.match,
1587
+ })}
1588
+ </>
1589
+ );
1590
+ }
1591
+ }
1592
+
1593
+ export default (props) => {
1594
+ const { initialState = {} } = useModel('@@initialState');
1595
+
1596
+ const { dictionaryData } = initialState;
1597
+ const intl = useIntl();
1598
+ const { formatMessage } = intl;
1599
+ return (
1600
+ <BasicLayout
1601
+ {...props}
1602
+ dictionaryData={dictionaryData}
1603
+ formatMessage={formatMessage}
1604
+ />
1605
+ );
1606
+ };