cfel-base-components 2.6.5 → 2.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cfel-base-components",
3
- "version": "2.6.5",
3
+ "version": "2.6.6",
4
4
  "description": "cfel-base-components",
5
5
  "main": "/src/index.tsx",
6
6
  "types": "src/index.d.ts",
@@ -10,36 +10,57 @@ instance.interceptors.request.use(
10
10
  (config: any) => {
11
11
  config.headers = {
12
12
  ...config.headers,
13
- 'Accept-Language': currentLanguage,
13
+ 'Accept-Language': currentLanguage
14
14
  } as AxiosRequestHeaders
15
15
 
16
16
  config.params = {
17
17
  ...config.params,
18
- productCode: (window as any)?.g_config?.productCode,
18
+ productCode: (window as any)?.g_config?.productCode
19
19
  }
20
20
 
21
21
  return config
22
22
  },
23
- (error: any) => Promise.reject(error),
23
+ (error: any) => Promise.reject(error)
24
24
  )
25
25
 
26
26
  instance.interceptors.response.use(
27
27
  //状态码为2xx的时候执行
28
28
  (response: any) => {
29
+ //如果返回值是blob,则直接返回
30
+ if (response.data instanceof Blob) {
31
+ return response
32
+ }
33
+
29
34
  const { data = {} } = response
30
35
  const { success, content, errorCode, errorMsg } = data
31
36
 
32
37
  if (!success) {
33
38
  notification.error({
34
- message: errorMsg,
39
+ message: errorMsg
35
40
  })
36
- return Promise.reject(data)
41
+ return Promise.reject(response)
37
42
  }
38
43
 
39
44
  return content
40
45
  },
41
46
  //状态码不为2xx的时候执行
42
47
  (error: any) => {
48
+ // 如果是业务错误(在响应拦截器中已处理),直接返回
49
+ // 检查是否是业务错误:reject 的是 response 对象,且 success === false
50
+ if (error.data && error.data.success === false) {
51
+ // 业务错误已经在响应拦截器中显示了 errorMsg,这里直接返回
52
+ return Promise.reject(error)
53
+ }
54
+ // 兼容旧的判断方式
55
+ if (
56
+ error.data &&
57
+ error.response &&
58
+ error.response.status >= 200 &&
59
+ error.response.status < 300
60
+ ) {
61
+ return Promise.reject(error)
62
+ }
63
+
43
64
  const { response = {} } = error
44
65
  const { status } = response
45
66
 
@@ -58,18 +79,21 @@ instance.interceptors.response.use(
58
79
  '服务器发生错误,请检查服务器。' = 500,
59
80
  '网关错误。' = 502,
60
81
  '服务不可用,服务器暂时过载或维护。' = 503,
61
- '网关超时。' = 504,
82
+ '网关超时。' = 504
62
83
  }
63
84
 
64
85
  notification.error({
65
- message: response?.data?.errorMsg || CodeMessage[status] || '服务暂不可用,请检查网络',
86
+ message: response?.data?.errorMsg || CodeMessage[status] || '服务暂不可用,请检查网络'
66
87
  })
67
88
  // 如果后端在非2xx响应中也返回了业务 errorCode,处理 PRODUCT_NOT_REGISTRY
68
89
  const respData = response?.data || {}
69
- if ((respData && respData.errorCode === 'PRODUCT_NOT_REGISTRY') || respData.errorCode === 'ACCESS_DENIED') {
90
+ if (
91
+ (respData && respData.errorCode === 'PRODUCT_NOT_REGISTRY') ||
92
+ respData.errorCode === 'ACCESS_DENIED'
93
+ ) {
70
94
  if (typeof (window as any).showProductNotRegisteredOverlay === 'function') {
71
95
  ;(window as any).showProductNotRegisteredOverlay({
72
- onAction: () => {},
96
+ onAction: () => {}
73
97
  })
74
98
  } else {
75
99
  if (!(window as any).__PRODUCT_NOT_REGISTRY_SHOWN__) {
@@ -77,7 +101,7 @@ instance.interceptors.response.use(
77
101
  Modal.warning({
78
102
  title: '产品未开通',
79
103
  content: '当前产品未开通或产品编码错误,请联系管理员或检查产品编码。',
80
- okText: '知道了',
104
+ okText: '知道了'
81
105
  })
82
106
  }
83
107
  }
@@ -86,7 +110,7 @@ instance.interceptors.response.use(
86
110
  }
87
111
 
88
112
  return Promise.reject(error)
89
- },
113
+ }
90
114
  )
91
115
 
92
116
  export default instance
@@ -101,13 +125,20 @@ export function request<T = any>(config: Parameters<typeof instance.request>[0])
101
125
  /**
102
126
  * GET 请求,支持类型推断
103
127
  */
104
- export function get<T = any>(url: string, config?: Omit<Parameters<typeof instance.get>[1], 'url'>) {
128
+ export function get<T = any>(
129
+ url: string,
130
+ config?: Omit<Parameters<typeof instance.get>[1], 'url'>
131
+ ) {
105
132
  return instance.get<T, T>(url, config)
106
133
  }
107
134
 
108
135
  /**
109
136
  * POST 请求,支持类型推断
110
137
  */
111
- export function post<T = any>(url: string, data?: any, config?: Omit<Parameters<typeof instance.post>[2], 'url' | 'data'>) {
138
+ export function post<T = any>(
139
+ url: string,
140
+ data?: any,
141
+ config?: Omit<Parameters<typeof instance.post>[2], 'url' | 'data'>
142
+ ) {
112
143
  return instance.post<T, T>(url, data, config)
113
144
  }
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from 'react'
1
+ import React, { useEffect, useState, ReactNode } from 'react'
2
2
  import { Layout, List, Menu, MenuProps, Popover } from 'antd'
3
3
  import UserCard from './user-card'
4
4
  import RcMenu, { SubMenu, MenuItem } from 'rc-menu'
@@ -41,6 +41,8 @@ export interface LiosLayoutlProps {
41
41
  logoutUrl?: string
42
42
  switchTenantUrl?: string
43
43
  defaultOpenKeys?: string[]
44
+ /** 自定义用户信息卡片内容(将完全替换内置的 UserCard) */
45
+ userCard?: ReactNode
44
46
  isHideHeader?: boolean //是否隐藏header
45
47
  onCollapse?: (value: boolean) => void
46
48
  type?: string
@@ -64,6 +66,7 @@ export default function LiosLayout(props: LiosLayoutlProps) {
64
66
  amountInfo,
65
67
  myWalletInfoAction,
66
68
  myLoginInfoAction,
69
+ userCard,
67
70
  isHideHeader,
68
71
  onCollapse,
69
72
  type,
@@ -500,7 +503,16 @@ export default function LiosLayout(props: LiosLayoutlProps) {
500
503
  <Popover
501
504
  placement="bottom"
502
505
  content={
503
- <UserCard myWalletInfo={myWalletInfo} MyLoginInfo={MyLoginInfo} amountInfo={amountInfo} customAction={customAction} isCopied={isCopied} copyTextToClipboard={copyTextToClipboard} />
506
+ userCard ?? (
507
+ <UserCard
508
+ myWalletInfo={myWalletInfo}
509
+ MyLoginInfo={MyLoginInfo}
510
+ amountInfo={amountInfo}
511
+ customAction={customAction}
512
+ isCopied={isCopied}
513
+ copyTextToClipboard={copyTextToClipboard}
514
+ />
515
+ )
504
516
  }
505
517
  arrow={false}
506
518
  trigger="click"
@@ -22,19 +22,28 @@ interface CustomType {
22
22
  hrefUrl: string;
23
23
  historyAction?: any;
24
24
  }
25
- interface MyWalletInfoType {
25
+ export interface MyWalletInfoType {
26
26
  availableCashAmount: string;
27
27
  availableAmount: string;
28
28
  currency: string;
29
29
  }
30
- interface MyLoginInfoType {
30
+ export interface MyLoginInfoType {
31
31
  isAdmin: any;
32
32
  }
33
- interface AmountInfoType {
33
+ export interface AmountInfoType {
34
34
  residueNum: string;
35
35
  currencyCode: string;
36
36
  }
37
37
 
38
+ export interface UserCardProps {
39
+ myWalletInfo?: MyWalletInfoType;
40
+ MyLoginInfo?: MyLoginInfoType;
41
+ amountInfo?: AmountInfoType;
42
+ customAction?: CustomType | any;
43
+ isCopied?: Record<string, boolean>;
44
+ copyTextToClipboard?: (value: string, key: string) => void;
45
+ }
46
+
38
47
  const renderCurrency = (currency: string) => {
39
48
  switch (currency) {
40
49
  case "CNY":
@@ -55,18 +64,18 @@ export default function UserCard({
55
64
  customAction,
56
65
  isCopied,
57
66
  copyTextToClipboard,
58
- }: any) {
67
+ }: UserCardProps) {
59
68
  const { user, tenant, custom, switchTenantUrl, logoutUrl } = (window as any)
60
69
  ?.g_config;
61
70
 
62
71
  const { name, avatar, roleInfo, id, account, isMaster }: UserType =
63
72
  user || {};
64
73
 
65
- const { isCompleted, isAudited }: CustomType = custom || {};
74
+ const { isCompleted, isAudited }: Partial<CustomType> = custom || {};
75
+
76
+ const { isAdmin }: MyLoginInfoType = (MyLoginInfo || {}) as MyLoginInfoType;
66
77
 
67
- const { isAdmin }: MyLoginInfoType = MyLoginInfo || {};
68
-
69
- const { residueNum, currencyCode }: AmountInfoType = amountInfo || {};
78
+ const { residueNum, currencyCode }: AmountInfoType = (amountInfo || {}) as AmountInfoType;
70
79
 
71
80
  const UserCard = () => {
72
81
  return (
@@ -94,7 +103,7 @@ export default function UserCard({
94
103
  <div
95
104
  className={isCopied?.['id'] ? "lios-iconDone" : "lios-icon"}
96
105
  onClick={() => {
97
- copyTextToClipboard(id, 'id');
106
+ copyTextToClipboard && copyTextToClipboard(id, 'id');
98
107
  }}
99
108
  >
100
109
  {isCopied?.['id'] ? "已复制" : <CopyOutlined/>}
@@ -108,7 +117,7 @@ export default function UserCard({
108
117
  <div
109
118
  className={isCopied?.['account'] ? "lios-iconDone" : "lios-icon"}
110
119
  onClick={() => {
111
- copyTextToClipboard(account, 'account');
120
+ copyTextToClipboard && copyTextToClipboard(account, 'account');
112
121
  }}
113
122
  >
114
123
  {isCopied?.['account'] ? "已复制" : <CopyOutlined/>}
@@ -121,7 +130,7 @@ export default function UserCard({
121
130
  <div
122
131
  className={isCopied?.['tenantId'] ? "lios-iconDone" : "lios-icon"}
123
132
  onClick={() => {
124
- copyTextToClipboard(tenant?.id, 'tenantId');
133
+ copyTextToClipboard && copyTextToClipboard(tenant?.id, 'tenantId');
125
134
  }}
126
135
  >
127
136
  {isCopied?.['tenantId'] ? "已复制" : <CopyOutlined/>}
package/src/index.tsx CHANGED
@@ -1,4 +1,5 @@
1
1
  import LiosLayout, { LiosLayoutlProps } from './components/layout'
2
+ import UserCard, { UserCardProps } from './components/layout/user-card'
2
3
  import PageContainer from './components/base-component/PageContainer'
3
4
  import CopyRight from './components/base-component/CopyRight'
4
5
  import QueryFilter from './components/base-component/QueryFilter'
@@ -20,6 +21,8 @@ import { getUrlParams, downloadFile, timeFormatter } from './utils/index'
20
21
  export {
21
22
  LiosLayout,
22
23
  LiosLayoutlProps,
24
+ UserCard,
25
+ UserCardProps,
23
26
  CopyRight,
24
27
  PageContainer,
25
28
  QueryFilter,