1
+ import { useEffect , useState , useContext } from 'react' ;
2
+ import { matchPath , generatePath } from 'react-router' ;
3
+
4
+ import ConsoleRegion from './index' ;
5
+ import { getActiveId } from './cookies' ;
6
+ import { determineRegionId } from './determineRegionId' ;
7
+ import { RegionContext } from '../context/RegionContext' ;
8
+ import { IConsoleContextRegionProp } from '../types/index' ;
9
+
10
+
11
+ const hasRegionId = ( match ) => {
12
+ // eslint-disable-next-line no-prototype-builtins
13
+ return match . params && match . params . hasOwnProperty ( 'regionId' ) ;
14
+ }
15
+
16
+ export const reroute = ( props : IConsoleContextRegionProp < { regionId ?: string } > , nextRegionId : string ) => {
17
+ const { history, match, location } = props ;
18
+ if ( match && match . path && hasRegionId ( match ) ) {
19
+ const { path, params } = match ;
20
+
21
+ if ( nextRegionId === params . regionId ) {
22
+ return ;
23
+ }
24
+
25
+ const nextPath = generatePath ( path , {
26
+ ...( params || { } ) ,
27
+ regionId : nextRegionId
28
+ } ) ;
29
+ const suff = location . pathname . slice ( match . url . length ) ;
30
+
31
+ history [ props . region ?. historyAction || 'push' ] ( {
32
+ pathname : match . isExact ? nextPath : `${ nextPath } /${ suff } ` . replace ( '//' , '/' ) ,
33
+ search : location . search ,
34
+ hash : location . hash ,
35
+ } ) ;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * 为了适配新版本的 region, 但是由于
41
+ * @param props
42
+ * @returns
43
+ */
44
+ const useRcRegionProps = ( props : IConsoleContextRegionProp < { regionId ?: string } > ) => {
45
+ const { consoleBase, match, location, region : regionConfig = { } } = props ;
46
+ const { regionList, regionbarVisiblePaths = [ ] , globalVisiblePaths = [ ] } = regionConfig ;
47
+ // 默认 Region = 路由的Region > Cookie 的 region > Region 列表中第一个 > 用户指定默认Region >'cn-hangzhou'
48
+ const [ currentRegionId , setCurrentRegionId ] = useState < string > ( '' ) ;
49
+ const regionContext = useContext ( RegionContext ) ;
50
+
51
+ // 设置内存变量中的 Id, 也设置设置临时变量中的 ID
52
+ const setRegionIdWithMemo = ( regionId : string ) => {
53
+ // @ts -ignore
54
+ window . __XCONSOLE_CURRENT_REGION_ID__ = regionId ;
55
+
56
+ // 兼容旧版本的应用
57
+ regionContext . setActiveRegionId ( regionId ) ;
58
+
59
+ setCurrentRegionId ( regionId ) ;
60
+ }
61
+
62
+ /**
63
+ * 处理路由
64
+ */
65
+ useEffect ( ( ) => {
66
+ // 如果 regionId 不在 region 列表重定向到 regionId 上
67
+ const regionId = determineRegionId ( match . params . regionId , currentRegionId , regionList ) ;
68
+
69
+ if ( currentRegionId !== regionId ) {
70
+ setRegionIdWithMemo ( regionId )
71
+ return reroute ( props , regionId ) ;
72
+ }
73
+ } , [ match . params . regionId ] ) ;
74
+
75
+ const showGlobal = globalVisiblePaths . some ( ( globalPath ) => {
76
+ const matches = matchPath ( location . pathname , {
77
+ path : globalPath ,
78
+ exact : true ,
79
+ strict : true ,
80
+ } ) ;
81
+ if ( matches ) {
82
+ return true ;
83
+ }
84
+ return false ;
85
+ } )
86
+
87
+
88
+ const onRegionChange = ( id : string , regionName : string , correctedFrom ?: string ) => {
89
+ if ( correctedFrom ) {
90
+ return ;
91
+ }
92
+ const regionId = determineRegionId ( id , currentRegionId , regionList ) ;
93
+ if ( regionId !== currentRegionId ) {
94
+ reroute ( props , regionId ) ;
95
+ }
96
+ }
97
+
98
+ const regionsVisible = regionbarVisiblePaths . some ( ( showRegionPath ) => {
99
+ const matches = matchPath ( location . pathname , {
100
+ path : showRegionPath ,
101
+ exact : true ,
102
+ strict : true ,
103
+ } ) ;
104
+ return ! ! matches ;
105
+ } ) ;
106
+
107
+ return {
108
+ global : showGlobal ,
109
+ regions : regionList ,
110
+ visible : regionsVisible ,
111
+ regionId : currentRegionId ,
112
+ onChange : onRegionChange ,
113
+ // 为了兼容老版版本提供出去的 region context 的 value
114
+ region : {
115
+ ...( consoleBase || ConsoleRegion ) ,
116
+ getCurrentRegionId : ( ) : string => currentRegionId || determineRegionId ( match . params . regionId , getActiveId ( ) , regionList ) ,
117
+ setCurrentRegionId : setRegionIdWithMemo
118
+ }
119
+ }
120
+ }
121
+
122
+ export default useRcRegionProps ;
0 commit comments