win-chart 1.0.0

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 (185) hide show
  1. package/.eslintrc.json +3 -0
  2. package/.prettierrc.json +5 -0
  3. package/README.md +0 -0
  4. package/localhost-key.pem +28 -0
  5. package/localhost.pem +25 -0
  6. package/package.json +65 -0
  7. package/rsbuild.config.ts +48 -0
  8. package/src/api/README.md +15 -0
  9. package/src/api/index.js +5 -0
  10. package/src/api/layout/index.js +32 -0
  11. package/src/api/request.ts +87 -0
  12. package/src/api/url-map/index.js +10 -0
  13. package/src/api/user/index.js +12 -0
  14. package/src/components/FilterContext.tsx +6 -0
  15. package/src/components/GlobalStyle.tsx +25 -0
  16. package/src/components/HalfScreenBrowser.tsx +95 -0
  17. package/src/components/ImgBox.tsx +19 -0
  18. package/src/components/JumpBtn.tsx +38 -0
  19. package/src/components/MCardWrapper.tsx +33 -0
  20. package/src/components/NoContent/index.tsx +85 -0
  21. package/src/components/ResponsiveReactGridLayout.tsx +218 -0
  22. package/src/components/SliderDecoration.tsx +27 -0
  23. package/src/components/VisionUserConfigContext.ts +6 -0
  24. package/src/components/WinMenu/README.md +11 -0
  25. package/src/components/WinMenu/WinHeader.tsx +5 -0
  26. package/src/components/WinMenu/components/ExtraBox.tsx +61 -0
  27. package/src/components/WinMenu/components/FullMenuBox.tsx +80 -0
  28. package/src/components/WinMenu/components/FullMenuContainer.tsx +50 -0
  29. package/src/components/WinMenu/components/FullMenuItem.tsx +128 -0
  30. package/src/components/WinMenu/components/LangSwitch.tsx +84 -0
  31. package/src/components/WinMenu/components/LogoBox.tsx +29 -0
  32. package/src/components/WinMenu/components/PinDialog.tsx +72 -0
  33. package/src/components/WinMenu/components/PinnedMenuBox.tsx +183 -0
  34. package/src/components/WinMenu/components/UserBox.tsx +83 -0
  35. package/src/components/WinMenu/hooks/useUserInfo.ts +21 -0
  36. package/src/components/WinMenu/hooks/useUserMenu.ts +35 -0
  37. package/src/components/WinMenu/index.tsx +100 -0
  38. package/src/components/WinMenu/services/WinService.ts +79 -0
  39. package/src/components/WinMenu/services/request.ts +53 -0
  40. package/src/components/WinMenu/utils/const.ts +80 -0
  41. package/src/components/WinMenu/utils/enum.ts +19 -0
  42. package/src/components/WinMenu/utils/interface.ts +61 -0
  43. package/src/components/WinMenu/utils/map.ts +39 -0
  44. package/src/components/WinMenu/utils/tool.ts +142 -0
  45. package/src/components/WinMenu/utils/type.ts +1 -0
  46. package/src/components/hover-view.tsx +48 -0
  47. package/src/components/icon.tsx +44 -0
  48. package/src/components/indicator-remark.tsx +25 -0
  49. package/src/components/none-content.tsx +93 -0
  50. package/src/components/panel-tab.tsx +150 -0
  51. package/src/components/panel-title-tab.tsx +60 -0
  52. package/src/components/win-card/components/ChartContent.tsx +47 -0
  53. package/src/components/win-card/components/Indicator.tsx +42 -0
  54. package/src/components/win-card/components/IndicatorArea.tsx +63 -0
  55. package/src/components/win-card/components/IndicatorInfo.tsx +78 -0
  56. package/src/components/win-card/components/MatterContent.tsx +121 -0
  57. package/src/components/win-card/components/MatterList.tsx +141 -0
  58. package/src/components/win-card/components/NoticeContent.tsx +73 -0
  59. package/src/components/win-card/components/NoticeList.tsx +68 -0
  60. package/src/components/win-card/components/SelectDecoration.tsx +34 -0
  61. package/src/components/win-card/components/WinRankContent.tsx +102 -0
  62. package/src/components/win-card/index.tsx +298 -0
  63. package/src/components/win-card/utils/interface.ts +12 -0
  64. package/src/components/win-card/utils/tool.ts +11 -0
  65. package/src/components/win-card-mobile/components/ChartContent.tsx +47 -0
  66. package/src/components/win-card-mobile/components/DualLineBar.tsx +61 -0
  67. package/src/components/win-card-mobile/components/Indicator.tsx +42 -0
  68. package/src/components/win-card-mobile/components/IndicatorArea.tsx +65 -0
  69. package/src/components/win-card-mobile/components/IndicatorInfo.tsx +83 -0
  70. package/src/components/win-card-mobile/components/SelectDecoration.tsx +28 -0
  71. package/src/components/win-card-mobile/index.tsx +235 -0
  72. package/src/components/win-card-mobile/utils/interface.ts +12 -0
  73. package/src/components/win-card-mobile/utils/tool.ts +9 -0
  74. package/src/components/win-chart/components/chart-wrapper.tsx +5 -0
  75. package/src/components/win-chart/index.tsx +59 -0
  76. package/src/components/win-chart/theme/win-dark.json +372 -0
  77. package/src/components/win-chart/theme/win-light.json +372 -0
  78. package/src/components/win-chart/utils/const.ts +37 -0
  79. package/src/components/win-chart/utils/getAreaSpec.ts +150 -0
  80. package/src/components/win-chart/utils/getBarSpec.ts +60 -0
  81. package/src/components/win-chart/utils/getChartOptions.ts +59 -0
  82. package/src/components/win-chart/utils/getColumnSpec.ts +112 -0
  83. package/src/components/win-chart/utils/getDualSpec.ts +79 -0
  84. package/src/components/win-chart/utils/getFunnelSpec.ts +70 -0
  85. package/src/components/win-chart/utils/getLineSpec.ts +53 -0
  86. package/src/components/win-chart/utils/getPieSpec.ts +124 -0
  87. package/src/components/win-chart/utils/getRadarSpec.ts +87 -0
  88. package/src/components/win-chart/utils/tool.ts +163 -0
  89. package/src/components/win-chart/utils/type.ts +96 -0
  90. package/src/components/win-icon/index.tsx +97 -0
  91. package/src/components/win-v/components/EmptyBox.tsx +9 -0
  92. package/src/components/win-v/components/VDialog.tsx +173 -0
  93. package/src/components/win-v/components/VDialogBtn.tsx +119 -0
  94. package/src/components/win-v/components/VDialogMsg.tsx +325 -0
  95. package/src/components/win-v/components/VInput.tsx +15 -0
  96. package/src/components/win-v/components/VRemindMsgList.tsx +303 -0
  97. package/src/components/win-v/components/VRobot.tsx +97 -0
  98. package/src/components/win-v/hooks/useVDialogCore.ts +102 -0
  99. package/src/components/win-v/hooks/useVDialogOperate.ts +132 -0
  100. package/src/components/win-v/hooks/useVDialogState.ts +52 -0
  101. package/src/components/win-v/hooks/useVRemindMsgShow.ts +15 -0
  102. package/src/components/win-v/index.tsx +205 -0
  103. package/src/components/win-wrappers/card-wrapper.tsx +103 -0
  104. package/src/components/win-wrappers/dot-wrapper.tsx +18 -0
  105. package/src/components/win-wrappers/iframe-wrapper.tsx +7 -0
  106. package/src/components/win-wrappers/request-wrapper.tsx +190 -0
  107. package/src/global.d.ts +53 -0
  108. package/src/hooks/useCardOptionList.ts +23 -0
  109. package/src/hooks/useCostFiltersDicList.ts +22 -0
  110. package/src/hooks/useFbiUrl.ts +22 -0
  111. package/src/hooks/useHalfScreenState.ts +50 -0
  112. package/src/hooks/useHasIntersected.ts +36 -0
  113. package/src/hooks/useIndicatorCardInfo.ts +26 -0
  114. package/src/hooks/useIndicatorCardQueryList.ts +22 -0
  115. package/src/hooks/useIndicatorClassifyList.ts +25 -0
  116. package/src/hooks/useIndicatorDetailsDateList.ts +22 -0
  117. package/src/hooks/useIndicatorDetailsInfo.ts +49 -0
  118. package/src/hooks/useIndicatorDetailsTrend.ts +25 -0
  119. package/src/hooks/useIndicatorDicList.ts +22 -0
  120. package/src/hooks/useIndicatorLabelList.ts +20 -0
  121. package/src/hooks/useIndicatorList.ts +24 -0
  122. package/src/hooks/useIndicatorRangeList.ts +20 -0
  123. package/src/hooks/useIndicatorTypeList.ts +20 -0
  124. package/src/hooks/useIndicatorUnitList.ts +21 -0
  125. package/src/hooks/useListenQuery.ts +29 -0
  126. package/src/hooks/useMobile.ts +58 -0
  127. package/src/hooks/useNotice.ts +42 -0
  128. package/src/hooks/useOrgLevelList.ts +23 -0
  129. package/src/hooks/usePageSelection.ts +121 -0
  130. package/src/hooks/usePageState.ts +22 -0
  131. package/src/hooks/usePendingList.ts +27 -0
  132. package/src/hooks/usePortalPageInfo.ts +43 -0
  133. package/src/hooks/useRefreshByLocationChange.ts +16 -0
  134. package/src/hooks/useReportIndicatorList.ts +21 -0
  135. package/src/hooks/useReportInfo.ts +45 -0
  136. package/src/hooks/useReportPersonList.ts +21 -0
  137. package/src/hooks/useScriptLoader.ts +22 -0
  138. package/src/hooks/useUnreadMsgList.ts +26 -0
  139. package/src/hooks/useUserAvatar.ts +23 -0
  140. package/src/hooks/useVReportInfo.ts +50 -0
  141. package/src/hooks/useVisionUserConfig.ts +25 -0
  142. package/src/hooks/useWorkbenchOptions.ts +63 -0
  143. package/src/index.tsx +20 -0
  144. package/src/services/CardService.ts +91 -0
  145. package/src/services/CommonService.ts +23 -0
  146. package/src/services/CostService.ts +56 -0
  147. package/src/services/DialogService.ts +74 -0
  148. package/src/services/IndicatorService.ts +406 -0
  149. package/src/services/PageService.ts +204 -0
  150. package/src/services/ReportService.ts +335 -0
  151. package/src/services/WorkbenchService.ts +411 -0
  152. package/src/styles/README.md +12 -0
  153. package/src/styles/index.scss +9 -0
  154. package/src/styles/mixins/index.scss +25 -0
  155. package/src/styles/next-cover.scss +4 -0
  156. package/src/styles/normalize.scss +27 -0
  157. package/src/styles/utilities/index.scss +5 -0
  158. package/src/styles/vars/index.scss +17 -0
  159. package/src/types/enum-workbench.ts +29 -0
  160. package/src/types/enum.ts +156 -0
  161. package/src/types/index.ts +19 -0
  162. package/src/types/indicator.ts +299 -0
  163. package/src/types/interface.ts +303 -0
  164. package/src/types/portal.ts +211 -0
  165. package/src/types/report.ts +28 -0
  166. package/src/types/type.ts +11 -0
  167. package/src/types/user.ts +28 -0
  168. package/src/utils/README.md +4 -0
  169. package/src/utils/arms.ts +59 -0
  170. package/src/utils/arr.ts +123 -0
  171. package/src/utils/const-workbench.ts +9 -0
  172. package/src/utils/const.ts +18 -0
  173. package/src/utils/index.ts +18 -0
  174. package/src/utils/init.ts +5 -0
  175. package/src/utils/map-workbench.ts +66 -0
  176. package/src/utils/map.ts +377 -0
  177. package/src/utils/number.ts +101 -0
  178. package/src/utils/page.ts +81 -0
  179. package/src/utils/str.ts +26 -0
  180. package/src/utils/tools.ts +44 -0
  181. package/src/utils/tree.ts +145 -0
  182. package/src/utils/url.ts +40 -0
  183. package/src/utils/util.ts +99 -0
  184. package/src/utils/workbench.ts +25 -0
  185. package/tsconfig.json +33 -0
@@ -0,0 +1,72 @@
1
+ import { CnDialog, CnTagCloseable, CnTagGroup } from '@cainiaofe/cn-ui';
2
+ import { MAX_PINNED_LENGTH } from '../utils/const';
3
+ import { IMenuItem } from '../utils/interface';
4
+
5
+ export interface IProps {
6
+ show: boolean;
7
+ operateItem?: IMenuItem;
8
+ pinnedMenuList: IMenuItem[];
9
+ onConfirmPin: (data: IMenuItem) => void;
10
+ onClose: () => void;
11
+ }
12
+
13
+ export const PinDialog = ({
14
+ pinnedMenuList,
15
+ show: showDialog,
16
+ operateItem,
17
+ onClose,
18
+ onConfirmPin,
19
+ }: IProps) => {
20
+ const canPin = pinnedMenuList.length < MAX_PINNED_LENGTH;
21
+
22
+ return (
23
+ <CnDialog
24
+ title={`当前导航菜单已满 ${MAX_PINNED_LENGTH} 个`}
25
+ visible={showDialog}
26
+ okProps={{
27
+ disabled: !canPin,
28
+ }}
29
+ onOk={() => {
30
+ if (operateItem) {
31
+ onConfirmPin(operateItem);
32
+ onClose();
33
+ }
34
+ }}
35
+ onCancel={onClose}
36
+ onClose={onClose}
37
+ >
38
+ <div>
39
+ {`导航空间最多可展示 ${MAX_PINNED_LENGTH} 个菜单,如需添加新菜单,请选择当前导航上的已有菜单任意一个进行替换。`}
40
+ </div>
41
+ <div>
42
+ 如需添加,请至少取消以下其中一个,点击确认后即可添加
43
+ <span
44
+ style={{
45
+ margin: '0 4px',
46
+ color: '#3D84FF',
47
+ }}
48
+ >
49
+ {operateItem?.menuTitle}
50
+ </span>
51
+ 菜单。
52
+ </div>
53
+ <CnTagGroup
54
+ style={{
55
+ marginTop: 16,
56
+ }}
57
+ >
58
+ {pinnedMenuList.map((item) => (
59
+ <CnTagCloseable
60
+ key={item.menuCode}
61
+ onClose={() => {
62
+ onConfirmPin(item);
63
+ return false;
64
+ }}
65
+ >
66
+ {item.menuTitle}
67
+ </CnTagCloseable>
68
+ ))}
69
+ </CnTagGroup>
70
+ </CnDialog>
71
+ );
72
+ };
@@ -0,0 +1,183 @@
1
+ import { Box } from '@cainiaofe/cn-ui';
2
+ import { THEME } from '../utils/const';
3
+ import { IWinHeaderProps } from '../utils/interface';
4
+ import { useEffect, useState } from 'react';
5
+ import { styled, css } from 'styled-components';
6
+ import {
7
+ checkCurLink,
8
+ checkEntityArr,
9
+ getCurLocationFirstIdByMenuList,
10
+ getHandleJump,
11
+ } from '../utils/tool';
12
+
13
+ export const PinnedMenuBox = ({
14
+ data = [],
15
+ isMiniOverlay,
16
+ }: IWinHeaderProps) => {
17
+ const [curFirstMenuCode, setCurFirstMenuCode] = useState<
18
+ number | string | undefined
19
+ >();
20
+
21
+ useEffect(() => {
22
+ if (data.length !== 0) {
23
+ setCurFirstMenuCode(getCurLocationFirstIdByMenuList(data));
24
+ }
25
+ }, [data]);
26
+
27
+ return (
28
+ <Box direction='row' align='center' spacing={40} style={{ height: 64 }}>
29
+ {data.map((item) => (
30
+ <FirstMenuItem
31
+ $mini={isMiniOverlay}
32
+ key={item.menuTitle}
33
+ theme={{ checked: item.menuCode === curFirstMenuCode }}
34
+ >
35
+ <div>{item.menuTitle}</div>
36
+ <MenuOverlay $mini={isMiniOverlay} data-overlay>
37
+ {item.children?.map((secondMenu) => {
38
+ if (!checkEntityArr(secondMenu.children)) {
39
+ // 二级菜单为叶子节点
40
+ return (
41
+ // <div onClick={getHandleJump(secondMenu)} key={item.menuTitle}>
42
+ // <span
43
+ // style={{
44
+ // color: THEME.mainColor,
45
+ // marginRight: 4,
46
+ // }}
47
+ // >
48
+ // {secondMenu.menuTitle}
49
+ // </span>
50
+ // {secondMenu.menuUrl && <IconBox size={12} src={LINK} />}
51
+ // </div>
52
+ <LinkItem
53
+ onClick={getHandleJump(secondMenu)}
54
+ key={item.menuTitle}
55
+ theme={{
56
+ checked: checkCurLink(secondMenu),
57
+ }}
58
+ style={{
59
+ fontSize: 16,
60
+ height: 22,
61
+ }}
62
+ >
63
+ {secondMenu.menuTitle}
64
+ </LinkItem>
65
+ );
66
+ }
67
+ // 三极菜单为叶子节点
68
+ return (
69
+ <SecondMenuItem key={secondMenu.menuTitle}>
70
+ <div>{secondMenu.menuTitle}</div>
71
+ <LinkBox>
72
+ {secondMenu.children?.map((thirdMenu) => (
73
+ <LinkItem
74
+ key={thirdMenu.menuTitle}
75
+ onClick={getHandleJump(thirdMenu)}
76
+ theme={{
77
+ checked: checkCurLink(thirdMenu),
78
+ }}
79
+ >
80
+ {thirdMenu.menuTitle}
81
+ </LinkItem>
82
+ ))}
83
+ </LinkBox>
84
+ </SecondMenuItem>
85
+ );
86
+ })}
87
+ </MenuOverlay>
88
+ </FirstMenuItem>
89
+ ))}
90
+ </Box>
91
+ );
92
+ };
93
+
94
+ export const FirstMenuItem = styled.div<{ $mini?: boolean }>`
95
+ color: rgba(255, 255, 255, 0.6);
96
+ font-size: 16px;
97
+ height: 64px;
98
+ display: flex;
99
+ justify-content: center;
100
+ align-items: center;
101
+ min-width: max-content;
102
+ cursor: pointer;
103
+
104
+ ${(props) =>
105
+ props.theme.checked &&
106
+ css`
107
+ color: #fff;
108
+ border-bottom: 4px solid ${THEME.mainColor};
109
+ box-sizing: border-box;
110
+ `}
111
+
112
+ &:hover {
113
+ [data-overlay] {
114
+ display: inherit;
115
+ opacity: 1;
116
+ visibility: visible;
117
+ }
118
+ }
119
+
120
+ ${(props) =>
121
+ props.$mini &&
122
+ css`
123
+ position: relative;
124
+ `}
125
+ `;
126
+
127
+ export const MenuOverlay = styled.div<{ $mini?: boolean }>`
128
+ width: 100vw;
129
+ background: #fff;
130
+ color: #000;
131
+ padding: 50px;
132
+ display: grid;
133
+ grid: auto-flow / repeat(auto-fill, minmax(220px, 1fr));
134
+ gap: 40px;
135
+ box-shadow: 0 2px 6px 0 rgb(32 33 37 / 10%);
136
+ position: absolute;
137
+ left: 0;
138
+ top: 64px;
139
+ min-width: max-content;
140
+ z-index: 1000;
141
+ opacity: 0;
142
+ visibility: hidden;
143
+ transition: opacity 0.5s, visibility 0s, transform 0.25s;
144
+
145
+ ${(props) =>
146
+ props.$mini &&
147
+ css`
148
+ left: 50%;
149
+ width: max-content;
150
+ transform: translateX(-50%);
151
+ `}
152
+ `;
153
+
154
+ export const SecondMenuItem = styled.div`
155
+ color: #347fff;
156
+ font-size: 16px;
157
+ cursor: default;
158
+ `;
159
+
160
+ export const LinkBox = styled.div`
161
+ color: #000;
162
+ margin-top: 16px;
163
+ display: grid;
164
+ grid: 'auto-flow / 1fr';
165
+ gap: 8px;
166
+ `;
167
+
168
+ const LinkItem = styled.div`
169
+ font-size: 14px;
170
+ cursor: pointer;
171
+ border-bottom: 2px solid transparent;
172
+ width: max-content;
173
+
174
+ ${(props) =>
175
+ props.theme.checked && {
176
+ color: THEME.mainColor,
177
+ }};
178
+
179
+ &:hover {
180
+ color: ${THEME.mainColor};
181
+ border-bottom-color: ${THEME.mainColor};
182
+ }
183
+ `;
@@ -0,0 +1,83 @@
1
+ import { styled } from 'styled-components';
2
+ import { THEME, getLogoutUrl } from '../utils/const';
3
+ import { Box, CnBalloon, CnButton } from '@cainiaofe/cn-ui';
4
+ import { IWinHeaderProps } from '../utils/interface';
5
+
6
+ export const UserBox = ({ userInfo }: IWinHeaderProps) => {
7
+ const { employeeName, employeeId } = userInfo ?? {};
8
+
9
+ return (
10
+ <CnBalloon
11
+ v2
12
+ align='bl'
13
+ triggerType={['click']}
14
+ trigger={
15
+ <Avatar
16
+ theme={{
17
+ size: '32px',
18
+ }}
19
+ >
20
+ <span
21
+ style={{
22
+ fontSize: 12,
23
+ }}
24
+ >
25
+ {employeeName}
26
+ </span>
27
+ </Avatar>
28
+ }
29
+ >
30
+ <Box spacing={8} align='center'>
31
+ <UserInfo>
32
+ <Box spacing={16}>
33
+ <div data-name>{employeeName}</div>
34
+ <div data-id>{`用户ID: ${employeeId ?? ''}`}</div>
35
+ </Box>
36
+ </UserInfo>
37
+ <CnButton
38
+ size='small'
39
+ style={{ width: 100 }}
40
+ onClick={() => {
41
+ window.location.href = getLogoutUrl();
42
+ }}
43
+ >
44
+ 退出登入
45
+ </CnButton>
46
+ </Box>
47
+ </CnBalloon>
48
+ );
49
+ };
50
+
51
+ const Avatar = styled.div`
52
+ width: ${(props) => props.theme.size};
53
+ height: ${(props) => props.theme.size};
54
+ border-radius: 100%;
55
+ background-color: ${THEME.mainColor};
56
+ white-space: nowrap;
57
+ overflow: hidden;
58
+ color: #fff;
59
+ font-size: 16px;
60
+ display: grid;
61
+ place-items: center;
62
+ border: 4px solid transparent;
63
+ box-sizing: border-box;
64
+ cursor: pointer;
65
+ `;
66
+
67
+ const UserInfo = styled.div`
68
+ padding: 20px;
69
+ display: grid;
70
+ /* grid: auto-flow / 100px 1fr; */
71
+ place-items: center;
72
+ gap: 16px;
73
+ width: 220px;
74
+
75
+ [data-name] {
76
+ font-size: 20px;
77
+ font-weight: 500;
78
+ }
79
+
80
+ [data-id] {
81
+ font-size: 12px;
82
+ }
83
+ `;
@@ -0,0 +1,21 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { WinService } from '@/components/WinMenu/services/WinService';
3
+ import { IUserInfo } from '@/components/WinMenu/utils/interface';
4
+
5
+ export const useUserInfo = () => {
6
+ const [state, setState] = useState<Partial<IUserInfo>>({});
7
+
8
+ const queryData = useCallback(async () => {
9
+ try {
10
+ setState(await WinService.queryLoginInfo());
11
+ } catch (error) {
12
+ // CnMessage.error(error.message);
13
+ }
14
+ }, []);
15
+
16
+ useEffect(() => {
17
+ queryData();
18
+ }, [queryData]);
19
+
20
+ return state;
21
+ };
@@ -0,0 +1,35 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { WinService } from '@/components/WinMenu/services/WinService';
3
+ import { IMenuItem } from '@/components/WinMenu/utils/interface';
4
+ import { allProduceCodeList } from '../utils/const';
5
+
6
+ const productCodesStr = JSON.stringify(allProduceCodeList);
7
+
8
+ export const useUserMenu = () => {
9
+ const [state, setState] = useState<{
10
+ menuList: IMenuItem[];
11
+ pinnedMenuList: IMenuItem[];
12
+ }>({
13
+ menuList: [],
14
+ pinnedMenuList: [],
15
+ });
16
+
17
+ const queryData = useCallback(async () => {
18
+ if (productCodesStr) {
19
+ try {
20
+ setState({
21
+ menuList: await WinService.queryUserMenu(productCodesStr),
22
+ pinnedMenuList: await WinService.queryUserMenu(productCodesStr, true),
23
+ });
24
+ } catch (error) {
25
+ // CnMessage.error(error.message);
26
+ }
27
+ }
28
+ }, []);
29
+
30
+ useEffect(() => {
31
+ queryData();
32
+ }, [queryData]);
33
+
34
+ return { userMenu: state, refreshUserMenu: queryData };
35
+ };
@@ -0,0 +1,100 @@
1
+ import { IMenuItem } from './utils/interface';
2
+ import { MAX_PINNED_LENGTH } from './utils/const';
3
+ import { LogoBox } from './components/LogoBox';
4
+ import { PinnedMenuBox } from './components/PinnedMenuBox';
5
+ import { styled } from 'styled-components';
6
+ import { UserBox } from './components/UserBox';
7
+ import { ExtraBox } from './components/ExtraBox';
8
+ import { FullMenuBox } from './components/FullMenuBox';
9
+ import { CnMessage } from '@cainiaofe/cn-ui';
10
+ import { WinService } from './services/WinService';
11
+ import { useUserMenu } from './hooks/useUserMenu';
12
+ import { useUserInfo } from './hooks/useUserInfo';
13
+ import React, { useState } from 'react';
14
+ import { menuConfigMap } from './utils/map';
15
+ import { getDefaultMenuBizTypeByHref } from './utils/tool';
16
+ import { PinDialog } from './components/PinDialog';
17
+
18
+ export * from './utils/tool';
19
+ export * from './utils/map';
20
+ export * from './hooks/useUserMenu';
21
+
22
+ export const MenuContext = React.createContext(getDefaultMenuBizTypeByHref());
23
+
24
+ export const WinMenu = () => {
25
+ const [curMenuBizType, setCurMenuBizType] = useState(
26
+ getDefaultMenuBizTypeByHref(),
27
+ );
28
+ const { title, logo, productCodes, downloadCenterUrl } =
29
+ menuConfigMap.get(curMenuBizType) ?? {};
30
+ const {
31
+ userMenu: { menuList, pinnedMenuList },
32
+ refreshUserMenu,
33
+ } = useUserMenu();
34
+ const userInfo = useUserInfo();
35
+ const [showDialog, setShowDialog] = useState(false);
36
+ const [operateItem, setOperateItem] = useState<IMenuItem>();
37
+ const canPin = pinnedMenuList.length < MAX_PINNED_LENGTH;
38
+
39
+ const handleCloseDialog = () => {
40
+ setShowDialog(false);
41
+ setOperateItem(undefined);
42
+ };
43
+
44
+ // 处理钉
45
+ const handlePinned = async (data: IMenuItem) => {
46
+ try {
47
+ if (data.pinned) {
48
+ // 取消钉
49
+ await WinService.unPinMenu(data.menuCode);
50
+ } else {
51
+ await WinService.pinMenu(data.menuCode);
52
+ }
53
+ refreshUserMenu();
54
+ } catch (error) {
55
+ CnMessage.error(error.message);
56
+ }
57
+ };
58
+
59
+ // 查验钉
60
+ const handleCheckPinned = (data: IMenuItem) => {
61
+ if (!canPin && !data.pinned) {
62
+ setOperateItem(data);
63
+ setShowDialog(true);
64
+ } else {
65
+ handlePinned(data);
66
+ }
67
+ };
68
+
69
+ return (
70
+ <MenuContext.Provider value={curMenuBizType}>
71
+ <NavWrapper>
72
+ <FullMenuBox data={menuList} onPinned={handleCheckPinned} />
73
+ <LogoBox src={logo} text={title} />
74
+ <PinnedMenuBox data={pinnedMenuList} />
75
+ <ExtraBox data={menuList} downloadCenterUrl={downloadCenterUrl} />
76
+ <UserBox userInfo={userInfo} />
77
+ <PinDialog
78
+ show={showDialog}
79
+ operateItem={operateItem}
80
+ pinnedMenuList={pinnedMenuList}
81
+ onConfirmPin={handlePinned}
82
+ onClose={handleCloseDialog}
83
+ />
84
+ </NavWrapper>
85
+ </MenuContext.Provider>
86
+ );
87
+ };
88
+
89
+ export const NavWrapper = styled.div`
90
+ background-color: #000;
91
+ height: 64px;
92
+ max-height: 64px;
93
+ display: grid;
94
+ grid: auto-flow / auto auto 1fr auto auto;
95
+ place-items: center normal;
96
+ position: relative;
97
+ padding: 0 20px;
98
+ gap: 40px;
99
+ z-index: 100;
100
+ `;
@@ -0,0 +1,79 @@
1
+ import { IMenuItem, IUserInfo } from '@/components/WinMenu/utils/interface';
2
+ import { winRequest } from './request';
3
+ import { getDefaultMenuBizTypeByHref, handleCnResult } from '../utils/tool';
4
+ import { MenuBizType } from '../utils/enum';
5
+
6
+ export class WinService {
7
+ /**
8
+ * 全部有权限菜单树
9
+ */
10
+ public static async queryUserMenu(productCodes: string, pinned?: boolean) {
11
+ const data = handleCnResult(
12
+ await winRequest<IMenuItem[]>({
13
+ url: '/menu/queryUserMenu',
14
+ method: 'POST',
15
+ data: {
16
+ startMenuCode: 'dwork_menu',
17
+ productCodes: JSON.parse(productCodes),
18
+ pinned,
19
+ fullUrl: getDefaultMenuBizTypeByHref() === MenuBizType.VISION,
20
+ },
21
+ }),
22
+ );
23
+
24
+ return data;
25
+ }
26
+
27
+ /**
28
+ * 钉住菜单
29
+ * @param menuCode
30
+ * @returns
31
+ */
32
+ public static async pinMenu(menuCode: string) {
33
+ const data = handleCnResult<boolean>(
34
+ await winRequest({
35
+ url: '/menu/pinMenu',
36
+ method: 'POST',
37
+ data: {
38
+ menuCode,
39
+ },
40
+ }),
41
+ );
42
+
43
+ return data;
44
+ }
45
+
46
+ /**
47
+ * 用户取消钉住菜单
48
+ * @param menuCode
49
+ * @returns
50
+ */
51
+ public static async unPinMenu(menuCode: string) {
52
+ const data = handleCnResult(
53
+ await winRequest<boolean>({
54
+ url: '/menu/unPinMenu',
55
+ method: 'POST',
56
+ data: {
57
+ menuCode,
58
+ },
59
+ }),
60
+ );
61
+
62
+ return data;
63
+ }
64
+
65
+ /**
66
+ * 查询当前登录用户信息
67
+ * @returns
68
+ */
69
+ public static async queryLoginInfo() {
70
+ const data = handleCnResult(
71
+ await winRequest<IUserInfo>({
72
+ url: '/menu/queryLoginInfo',
73
+ method: 'POST',
74
+ }),
75
+ );
76
+
77
+ return data;
78
+ }
79
+ }
@@ -0,0 +1,53 @@
1
+ import cnRequest, { CnRequestConfig } from '@alife/cn-request';
2
+ import { IResponse } from '../utils/interface';
3
+
4
+ const axiosConfig = {
5
+ withCredentials: true,
6
+ };
7
+
8
+ const cnOptions = {
9
+ turnOffLog: true,
10
+ loginCallback: () => {},
11
+ };
12
+
13
+ const request = cnRequest(axiosConfig, cnOptions);
14
+
15
+ request.interceptors.response.use(
16
+ (response) => {
17
+ const obj = response.data;
18
+ const { code, msg, success, errorMsg, errorCode } = obj;
19
+
20
+ if (code === '9999') {
21
+ return Promise.reject({
22
+ ...obj,
23
+ message: msg,
24
+ });
25
+ }
26
+
27
+ if (errorCode === '1000') {
28
+ const curHref = encodeURIComponent(
29
+ encodeURIComponent(window.parent.location.href),
30
+ );
31
+ location.href = errorMsg + curHref;
32
+ }
33
+
34
+ if (!success) {
35
+ return Promise.reject({
36
+ ...obj,
37
+ message: errorMsg,
38
+ });
39
+ }
40
+
41
+ return obj;
42
+ },
43
+ (err) => {
44
+ console.error('network error', err);
45
+ return Promise.reject(err);
46
+ },
47
+ );
48
+
49
+ export const winRequest = async <T>(config: CnRequestConfig) => {
50
+ const resp: IResponse<T> = (await request<IResponse<T>>(config)) as any;
51
+
52
+ return Promise.resolve(resp);
53
+ };
@@ -0,0 +1,80 @@
1
+ export const THEME = {
2
+ mainColor: 'var(--color-primary, #3379ff)',
3
+ defaultColor: '#272f3d',
4
+ };
5
+
6
+ export const allProduceCodeList = [
7
+ 'SMART_PARK',
8
+ 'WAREHOUSE_BUSINESS',
9
+ 'PLATFORM',
10
+ 'ASSET',
11
+ 'BOSS',
12
+ 'VISION',
13
+ 'COST',
14
+ ];
15
+
16
+ /**
17
+ * 最大钉数量
18
+ */
19
+ export const MAX_PINNED_LENGTH = 6;
20
+
21
+ export const GLOBAL_MENU_TITLE = '全局导航';
22
+
23
+ export const DEFAULT_LOGO =
24
+ 'https://img.alicdn.com/imgextra/i3/O1CN01vfE10325TsIKkgGes_!!6000000007528-2-tps-148-52.png';
25
+ /**
26
+ * Link
27
+ */
28
+ export const LINK =
29
+ 'https://img.alicdn.com/imgextra/i2/O1CN01IuML6l1oOyiuWwY2z_!!6000000005216-55-tps-4-8.svg';
30
+
31
+ export const selectImg =
32
+ 'https://img.alicdn.com/imgextra/i1/O1CN01dXAMby1yK4SMLiY4G_!!6000000006559-55-tps-16-16.svg';
33
+ export const noSelectImg =
34
+ 'https://img.alicdn.com/imgextra/i1/O1CN01cNSFHz1gte8TOXat1_!!6000000004200-55-tps-16-16.svg';
35
+
36
+ /**
37
+ * 球状语言LOGO
38
+ */
39
+ export const LANG_LOGO =
40
+ 'https://img.alicdn.com/imgextra/i3/O1CN01bp9Xxw1IxGfQSC63a_!!6000000000959-55-tps-16-16.svg';
41
+
42
+ /**
43
+ * 当前环境
44
+ */
45
+ export const env = location.hostname.endsWith('test')
46
+ ? 'daily'
47
+ : location.hostname.startsWith('pre')
48
+ ? 'pre'
49
+ : 'prod';
50
+
51
+ /**
52
+ * 获取登录地址
53
+ * @returns
54
+ */
55
+ export const getLoginUrl = () => {
56
+ const urls = {
57
+ daily: `https://cnlogin.cainiao.test/miniLogin?isNewLogin=true&showin=true&showdd=true&redirectURL=${window.location.href}`,
58
+ pre: `https://pre-cnlogin.cainiao.com/miniLogin?isNewLogin=true&showin=true&showdd=true&redirectURL=${window.location.href}`,
59
+ prod: `https://cnlogin.cainiao.com/miniLogin?isNewLogin=true&showin=true&showdd=true&redirectURL=${window.location.href}`,
60
+ };
61
+
62
+ return urls[env];
63
+ };
64
+
65
+ /**
66
+ * 获取退出登录地址
67
+ * @returns
68
+ */
69
+ export const getLogoutUrl = () => {
70
+ const urls = {
71
+ daily: `http://cnlogin.cainiao.test/logout?redirectURL=${window.location.href}`,
72
+ pre: `http://pre-cnlogin.cainiao.com/logout?redirectURL=${window.location.href}`,
73
+ prod: `http://cnlogin.cainiao.com/logout?redirectURL=${window.location.href}`,
74
+ };
75
+
76
+ return urls[env];
77
+ };
78
+
79
+ export const RELATED_SYSTEM_LOGO =
80
+ 'https://img.alicdn.com/imgextra/i2/O1CN01HGDION1WcZR2CtV7X_!!6000000002809-55-tps-15-16.svg';