@jiangood/open-admin 3.0.15 → 3.1.1

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 (82) hide show
  1. package/package.json +15 -2
  2. package/src/framework/biz/OrgTree.tsx +10 -6
  3. package/src/framework/biz/PermActions.tsx +5 -3
  4. package/src/framework/biz/RoleTree.tsx +10 -6
  5. package/src/framework/biz/index.tsx +1 -0
  6. package/src/framework/components/ContextMenu/index.tsx +17 -1
  7. package/src/framework/components/DownloadModal/index.tsx +40 -33
  8. package/src/framework/components/DrawerForm/index.tsx +108 -0
  9. package/src/framework/components/FormModal/index.tsx +16 -9
  10. package/src/framework/components/NamedIcon/index.tsx +2 -2
  11. package/src/framework/components/OrgSwitcher/index.tsx +6 -7
  12. package/src/framework/components/PageLoading/index.tsx +3 -3
  13. package/src/framework/components/ProTable/index.tsx +28 -25
  14. package/src/framework/components/ValueType/index.tsx +1 -1
  15. package/src/framework/components/index.ts +1 -0
  16. package/src/framework/config/themeConfig.ts +5 -5
  17. package/src/framework/fields/BaseRemoteSelect/index.tsx +23 -21
  18. package/src/framework/fields/FieldBoolean/index.tsx +6 -6
  19. package/src/framework/fields/FieldDate/index.tsx +10 -10
  20. package/src/framework/fields/FieldDateRange/index.tsx +20 -20
  21. package/src/framework/fields/FieldDictSelect/index.tsx +2 -2
  22. package/src/framework/fields/FieldEditor/index.tsx +1 -1
  23. package/src/framework/fields/FieldNumberRange/index.tsx +16 -17
  24. package/src/framework/fields/FieldPercent/index.tsx +2 -2
  25. package/src/framework/fields/FieldRemoteSelect/index.tsx +4 -4
  26. package/src/framework/fields/FieldRemoteTree/index.tsx +1 -1
  27. package/src/framework/fields/FieldRemoteTreeCascader/index.tsx +1 -1
  28. package/src/framework/fields/FieldRemoteTreeSelect/index.tsx +1 -1
  29. package/src/framework/fields/FieldSysOrgTree/index.tsx +1 -1
  30. package/src/framework/fields/FieldSysOrgTreeSelect/index.tsx +1 -1
  31. package/src/framework/fields/FieldTable/index.tsx +15 -13
  32. package/src/framework/fields/FieldTableSelect/index.tsx +5 -5
  33. package/src/framework/fields/FieldUploadFile/index.tsx +3 -3
  34. package/src/framework/fields/FieldUploadImage/index.tsx +31 -29
  35. package/src/framework/fields/types.ts +0 -2
  36. package/src/framework/router/PageFrame.tsx +1 -1
  37. package/src/framework/router/matcher.ts +2 -2
  38. package/src/framework/utils/ArrayUtils.ts +2 -2
  39. package/src/framework/utils/DateUtils.ts +1 -1
  40. package/src/framework/utils/{system/DictUtils.ts → DictUtils.ts} +1 -1
  41. package/src/framework/utils/EventBus.ts +7 -7
  42. package/src/framework/utils/HttpClient.ts +283 -0
  43. package/src/framework/utils/{system/PageUtils.ts → PageUtils.ts} +4 -4
  44. package/src/framework/utils/{system/PermUtils.ts → PermUtils.ts} +3 -3
  45. package/src/framework/utils/StringUtils.ts +10 -8
  46. package/src/framework/utils/TreeUtils.ts +3 -3
  47. package/src/framework/utils/UrlUtils.ts +2 -2
  48. package/src/framework/utils/index.ts +4 -1
  49. package/src/framework/views/ViewApproveStatus/index.tsx +1 -2
  50. package/src/framework/views/ViewBoolean/index.tsx +4 -1
  51. package/src/framework/views/ViewFile/index.tsx +4 -4
  52. package/src/framework/views/ViewImage/index.tsx +2 -2
  53. package/src/framework/views/ViewPassword/index.tsx +3 -2
  54. package/src/framework/views/ViewText/index.tsx +12 -3
  55. package/src/framework/views/types.ts +2 -4
  56. package/src/layouts/admin/AdminTabs.jsx +9 -0
  57. package/src/layouts/admin/AdminTabs.less +2 -2
  58. package/src/layouts/admin/HeaderRight.jsx +8 -7
  59. package/src/layouts/admin/TabLayout.jsx +2 -2
  60. package/src/layouts/admin/index.jsx +15 -11
  61. package/src/layouts/admin/index.less +16 -1
  62. package/src/layouts/index.tsx +24 -18
  63. package/src/pages/404.jsx +1 -1
  64. package/src/pages/article/$code.jsx +4 -4
  65. package/src/pages/index.jsx +1 -1
  66. package/src/pages/public/login.jsx +34 -27
  67. package/src/pages/public/test.jsx +1 -1
  68. package/src/pages/standalone/forceUpdatePwd.jsx +9 -7
  69. package/src/pages/system/article/index.jsx +9 -8
  70. package/src/pages/system/dict/index.jsx +19 -16
  71. package/src/pages/system/file/index.jsx +9 -9
  72. package/src/pages/system/job/index.jsx +17 -17
  73. package/src/pages/system/log/index.jsx +5 -7
  74. package/src/pages/system/org/index.jsx +31 -18
  75. package/src/pages/system/role/index.jsx +13 -12
  76. package/src/pages/system/role/rolePerm.jsx +25 -21
  77. package/src/pages/system/user/index.jsx +35 -33
  78. package/src/pages/system/user/userPerm.jsx +12 -12
  79. package/src/pages/userCenter/index.jsx +11 -9
  80. package/src/pages/userCenter/permView.jsx +7 -7
  81. package/src/framework/utils/system/HttpUtils.ts +0 -97
  82. package/src/framework/utils/system/index.ts +0 -4
@@ -4,16 +4,16 @@ import {BaseRemoteSelect} from '../BaseRemoteSelect';
4
4
  import type {SelectProps} from "antd/es/select";
5
5
  import type {FieldProps} from '../types';
6
6
 
7
- interface FieldRemoteSelectProps extends Omit<SelectProps, 'value' | 'onChange' | 'mode'>, FieldProps<any> {
7
+ interface FieldRemoteSelectProps extends Omit<SelectProps, 'value' | 'onChange' | 'mode'>, FieldProps<unknown> {
8
8
  url: string;
9
9
  debounceTime?: number;
10
10
  multiple?: boolean;
11
- paramsProcessor?: (params: any) => any;
12
- responseProcessor?: (response: any) => any;
11
+ paramsProcessor?: (params: Record<string, unknown>) => Record<string, unknown>;
12
+ responseProcessor?: (response: unknown) => unknown;
13
13
  }
14
14
 
15
15
  export class FieldRemoteSelect extends BaseRemoteSelect<FieldRemoteSelectProps> {
16
- static defaultProps = {
16
+ static readonly defaultProps = {
17
17
  placeholder: '请搜索选择',
18
18
  };
19
19
 
@@ -20,7 +20,7 @@ export class FieldRemoteTree extends BaseRemoteSelect {
20
20
  <Tree
21
21
  multiple
22
22
  checkable
23
- onCheck={(checkedInfo) => this.props.onChange && this.props.onChange(checkedInfo.checked)}
23
+ onCheck={(checkedInfo) => this.props.onChange?.(checkedInfo.checked)}
24
24
  checkedKeys={this.props.value}
25
25
  treeData={this.state.data}
26
26
  defaultExpandAll
@@ -28,7 +28,7 @@ export class FieldRemoteTreeCascader extends BaseRemoteSelect {
28
28
  <Cascader
29
29
  options={data}
30
30
  onChange={(arr) => {
31
- onChange && onChange(arr[arr.length - 1]);
31
+ onChange?.(arr[arr.length - 1]);
32
32
  }}
33
33
  value={arr}
34
34
  fieldNames={{ label: 'title', value: 'key' }}
@@ -4,7 +4,7 @@ import { StringUtils } from '../../utils';
4
4
  import { BaseRemoteSelect } from '../BaseRemoteSelect';
5
5
 
6
6
  export class FieldRemoteTreeSelect extends BaseRemoteSelect {
7
- static defaultProps = {
7
+ static readonly defaultProps = {
8
8
  treeDefaultExpandAll: true,
9
9
  };
10
10
 
@@ -10,7 +10,7 @@ interface FieldSysOrgTreeProps extends FieldProps<string[]> {
10
10
  }
11
11
 
12
12
  export class FieldSysOrgTree extends React.Component<FieldSysOrgTreeProps> {
13
- static defaultProps = {
13
+ static readonly defaultProps = {
14
14
  type: 'dept',
15
15
  };
16
16
 
@@ -8,7 +8,7 @@ interface FieldSysOrgTreeSelectProps extends FieldProps<string | string[]> {
8
8
 
9
9
  export class FieldSysOrgTreeSelect extends React.Component<FieldSysOrgTreeSelectProps> {
10
10
 
11
- static defaultProps = {
11
+ static readonly defaultProps = {
12
12
  type: 'dept',
13
13
  };
14
14
 
@@ -16,12 +16,12 @@ export interface FieldTableColumn {
16
16
  /** 列宽 */
17
17
  width?: number | string;
18
18
  /** 自定义渲染(返回的组件会被注入 value/onChange) */
19
- render?: (value: any, record: Record<string, any>, index: number) => React.ReactElement;
19
+ render?: (value: unknown, record: Record<string, unknown>, index: number) => React.ReactElement;
20
20
  /** 其余 antd Table 列属性 */
21
- [key: string]: any;
21
+ [key: string]: unknown;
22
22
  }
23
23
 
24
- export interface FieldTableProps extends FieldProps<Record<string, any>[]> {
24
+ export interface FieldTableProps extends FieldProps<Record<string, unknown>[]> {
25
25
  /** 列配置(操作列由组件自动追加) */
26
26
  columns: FieldTableColumn[];
27
27
  /** 容器样式 */
@@ -29,7 +29,7 @@ export interface FieldTableProps extends FieldProps<Record<string, any>[]> {
29
29
  }
30
30
 
31
31
  interface FieldTableState {
32
- dataSource: Record<string, any>[];
32
+ dataSource: Record<string, unknown>[];
33
33
  }
34
34
 
35
35
  /**
@@ -84,13 +84,13 @@ export class FieldTable extends React.Component<FieldTableProps, FieldTableState
84
84
  dataSource: []
85
85
  };
86
86
 
87
- onCellChange = (index: number, dataIndex: string | undefined, e: any) => {
87
+ onCellChange = (index: number, dataIndex: string | undefined, e: unknown) => {
88
88
  const {dataSource} = this.state;
89
89
  const row = dataSource[index];
90
90
 
91
- let v = e;
91
+ let v: unknown = e;
92
92
  if (e != null && typeof e === 'object' && 'target' in e) {
93
- v = e.target.value;
93
+ v = (e as {target: {value: unknown}}).target.value;
94
94
  }
95
95
 
96
96
  const next = [...dataSource];
@@ -104,25 +104,27 @@ export class FieldTable extends React.Component<FieldTableProps, FieldTableState
104
104
  this.setState({dataSource}, this.notifyParent);
105
105
  };
106
106
 
107
- remove = (record: Record<string, any>) => {
107
+ remove = (record: Record<string, unknown>) => {
108
108
  const {dataSource} = this.state;
109
109
  this.setState({dataSource: dataSource.filter(item => item !== record)}, this.notifyParent);
110
110
  };
111
111
 
112
112
  notifyParent = () => {
113
113
  const {dataSource} = this.state;
114
- this.props.onChange && this.props.onChange(dataSource);
114
+ this.props.onChange?.(dataSource);
115
115
  };
116
116
 
117
+ renderFooter = () => <Button type='dashed'
118
+ icon={<PlusOutlined/>}
119
+ onClick={this.add}>增加一行
120
+ </Button>;
121
+
117
122
  render() {
118
123
  return <div className='edit-table' style={this.props.style}>
119
124
  <Table columns={this.columns}
120
125
  dataSource={this.state.dataSource}
121
126
  size='small'
122
- footer={() => <Button type='dashed'
123
- icon={<PlusOutlined/>}
124
- onClick={this.add}>增加一行
125
- </Button>}
127
+ footer={this.renderFooter}
126
128
  pagination={false}
127
129
  >
128
130
 
@@ -2,14 +2,14 @@ import React from "react";
2
2
  import {Button, Select} from "antd";
3
3
  import type {TableColumnsType} from "antd";
4
4
  import {ProTable} from "../../components";
5
- import {HttpUtils} from "../../utils";
5
+ import {HttpClient} from "../../utils";
6
6
  import type {FieldProps} from '../types';
7
7
 
8
8
  export interface FieldTableSelectProps extends FieldProps<string> {
9
9
  /** 数据加载地址 */
10
10
  url: string;
11
11
  /** 表格列配置(操作列由组件自动追加) */
12
- columns: TableColumnsType<Record<string, any>>;
12
+ columns: TableColumnsType<Record<string, unknown>>;
13
13
  /** 占位文本,默认 请搜索选择 */
14
14
  placeholder?: string;
15
15
  }
@@ -26,7 +26,7 @@ interface FieldTableSelectState {
26
26
  */
27
27
  export class FieldTableSelect extends React.Component<FieldTableSelectProps, FieldTableSelectState> {
28
28
 
29
- static defaultProps = {
29
+ static readonly defaultProps = {
30
30
  placeholder: '请搜索选择',
31
31
  };
32
32
 
@@ -62,13 +62,13 @@ export class FieldTableSelect extends React.Component<FieldTableSelectProps, Fie
62
62
  label: record.name,
63
63
  open: false
64
64
  });
65
- this.props.onChange && this.props.onChange(record.id);
65
+ this.props.onChange?.(record.id);
66
66
  }}>选择</Button>;
67
67
  }
68
68
  }]}
69
69
  request={(params) => {
70
70
  params.selected = this.props.value;
71
- return HttpUtils.get(this.props.url, params);
71
+ return HttpClient.get(this.props.url, params);
72
72
  }}>
73
73
  </ProTable>;
74
74
  };
@@ -88,7 +88,7 @@ export class FieldUploadFile extends React.Component<FieldUploadFileProps, Field
88
88
  if (f.response) { // 新上传的
89
89
  const ajaxResult = f.response;
90
90
  if (ajaxResult.success) {
91
- const {objectName, name} = ajaxResult.data;
91
+ const {objectName} = ajaxResult.data;
92
92
  f.objectName = objectName;
93
93
  objectNames.push(objectName);
94
94
  } else {
@@ -102,9 +102,9 @@ export class FieldUploadFile extends React.Component<FieldUploadFileProps, Field
102
102
  return objectNames;
103
103
  }
104
104
 
105
- handleChange = ({fileList, event, file}: UploadChangeParam<SysUploadFile>) => {
105
+ handleChange = ({fileList, file}: UploadChangeParam<SysUploadFile>) => {
106
106
  const rs = file.response;
107
- if (rs != null && rs.success === false) {
107
+ if (rs?.success === false) {
108
108
  this.setState({errorTitle: '上传失败', errorContent: rs.message});
109
109
  return;
110
110
  }
@@ -4,9 +4,7 @@ import {DeleteOutlined, EyeOutlined, PlusOutlined} from "@ant-design/icons";
4
4
  import Compressor from "compressorjs";
5
5
  import Cropper from "cropperjs";
6
6
  import "cropperjs/dist/cropper.css";
7
- import {HttpUtils} from "../../utils";
8
- import {ObjectUtils} from "../../utils";
9
- import {UrlUtils} from "../../utils";
7
+ import {HttpClient, ObjectUtils, UrlUtils} from "../../utils";
10
8
  import type {FieldProps} from '../types';
11
9
 
12
10
  export interface FieldUploadImageProps extends FieldProps<string> {
@@ -93,7 +91,7 @@ function readDims(url: string): Promise<Dims> {
93
91
 
94
92
  function compressToFile(source: Blob, options: {maxWidth?: number; maxHeight?: number; width?: number; height?: number; quality?: number}): Promise<File> {
95
93
  return new Promise((resolve, reject) => {
96
- new Compressor(source, {
94
+ new Compressor(source, { // NOSONAR (typescript:S1848) — compressorjs 通过构造函数副作用异步压缩,回调内 resolve/reject,实例无需保留
97
95
  maxWidth: options.maxWidth,
98
96
  maxHeight: options.maxHeight,
99
97
  width: options.width,
@@ -141,9 +139,9 @@ async function compressToTarget(source: Blob, maxWidth: number | undefined, targ
141
139
  return best;
142
140
  }
143
141
 
144
- export class FieldUploadImage extends React.Component<FieldUploadImageProps, FieldUploadImageState> {
142
+ export class FieldUploadImage extends React.Component<FieldUploadImageProps, FieldUploadImageState> { // NOSONAR: state 构造器中按 props 初始化,无法全部 readonly
145
143
 
146
- state: FieldUploadImageState = {
144
+ state: FieldUploadImageState = { // NOSONAR: 构造器中按 props 初始化,无法 readonly
147
145
  // 传入的参数
148
146
  maxCount: 1,
149
147
  thumbWidth: 300,
@@ -169,10 +167,10 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
169
167
  constructor(props: FieldUploadImageProps) {
170
168
  super(props);
171
169
  ObjectUtils.copyPropertyIfPresent(props, this.state);
172
- if (this.props.value) this.state.objectNames = this.props.value.split(',');
170
+ if (props.value) this.state.objectNames = props.value.split(',');
173
171
  }
174
172
 
175
- componentDidUpdate(prevProps: FieldUploadImageProps, prevState: FieldUploadImageState) {
173
+ componentDidUpdate(prevProps: FieldUploadImageProps, prevState: FieldUploadImageState) { // NOSONAR: 顺序同步多个 props 到 state,拆分反而更难读
176
174
  const next: Partial<FieldUploadImageState> = {};
177
175
  if (this.props.maxCount !== prevProps.maxCount) next.maxCount = this.props.maxCount;
178
176
  if (this.props.thumbWidth !== prevProps.thumbWidth) next.thumbWidth = this.props.thumbWidth;
@@ -199,7 +197,7 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
199
197
  if (prevState.cropRatio !== this.state.cropRatio && this.cropperRef) {
200
198
  if (!this.state.cropRatio) {
201
199
  const box = this.cropperRef.getCropBoxData();
202
- this.cropperRef.setAspectRatio(NaN);
200
+ this.cropperRef.setAspectRatio(Number.NaN);
203
201
  this.cropperRef.setCropBoxData(box);
204
202
  } else {
205
203
  this.cropperRef.setAspectRatio(this.state.cropRatio.width / this.state.cropRatio.height);
@@ -229,7 +227,7 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
229
227
  const init = () => {
230
228
  if (this.cropperRef) this.cropperRef.destroy();
231
229
  this.cropperRef = new Cropper(el, {
232
- aspectRatio: this.state.cropRatio ? this.state.cropRatio.width / this.state.cropRatio.height : NaN,
230
+ aspectRatio: this.state.cropRatio ? this.state.cropRatio.width / this.state.cropRatio.height : Number.NaN,
233
231
  viewMode: 1,
234
232
  autoCropArea: 0.85,
235
233
  dragMode: 'move',
@@ -293,7 +291,7 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
293
291
  this.previewUrlsRef = [cUrl];
294
292
  this.setState({preview: {cUrl, cFile, cSize: cFile.size, cdims}, tool: undefined});
295
293
  message.success(`已压缩:${cdims.width} x ${cdims.height} / ${formatSize(cFile.size)}`);
296
- } catch (e) {
294
+ } catch {
297
295
  message.error('压缩失败');
298
296
  }
299
297
  };
@@ -320,7 +318,7 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
320
318
  this.setState({originalDims: dims});
321
319
  // 默认展示原图,不做压缩处理,用户可点击「压缩」按钮手动压缩
322
320
  await this.loadOriginalPreview(file, url, dims);
323
- } catch (e) {
321
+ } catch {
324
322
  message.error('读取图片失败');
325
323
  this.closeModal();
326
324
  return;
@@ -365,22 +363,34 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
365
363
  fd.append('file', this.state.preview.cFile);
366
364
  fd.append('thumb', tFile);
367
365
  fd.append('isPublic', String(this.state.isPublic));
368
- const rs = await HttpUtils.post('admin/sysFile/uploadImage', fd);
369
- const newNames = [...this.state.objectNames, rs.objectName];
370
- this.setState({objectNames: newNames});
371
- this.props.onChange?.(newNames.join(','));
366
+ const rs = await HttpClient.post('admin/sysFile/uploadImage', fd, null, {toastError: false});
367
+ this.setState(
368
+ (prevState) => ({objectNames: [...prevState.objectNames, rs.data.objectName]}),
369
+ () => this.props.onChange?.(this.state.objectNames.join(','))
370
+ );
372
371
  this.closeModal();
373
372
  } catch (e) {
374
- message.error(HttpUtils.extractErrorMessage(e));
373
+ message.error(HttpClient.errToMsg(e));
375
374
  } finally {
376
375
  this.setState({uploading: false});
377
376
  }
378
377
  };
379
378
 
380
379
  private removeImage = (name: string) => {
381
- const newNames = this.state.objectNames.filter((n) => n !== name);
382
- this.setState({objectNames: newNames});
383
- this.props.onChange?.(newNames.join(','));
380
+ this.setState(
381
+ (prevState) => ({objectNames: prevState.objectNames.filter((n) => n !== name)}),
382
+ () => this.props.onChange?.(this.state.objectNames.join(','))
383
+ );
384
+ };
385
+
386
+ private renderCanvas = (preview, canvasImg, originalUrl) => {
387
+ if (this.state.tool === 'crop') {
388
+ return <img key="crop-canvas" ref={this.imgRef} src={preview?.cUrl || originalUrl} style={{maxWidth: '100%', maxHeight: '100%'}} alt="待裁切"/>;
389
+ }
390
+ if (canvasImg?.url) {
391
+ return <img src={canvasImg.url} style={{maxWidth: '100%', maxHeight: '100%'}} alt="预览"/>;
392
+ }
393
+ return <div style={{color: '#999'}}>生成中...</div>;
384
394
  };
385
395
 
386
396
  render() {
@@ -479,13 +489,7 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
479
489
  flex: 1, minHeight: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
480
490
  background: '#f5f5f5', borderRadius: 8, border: '1px dashed #d9d9d9', position: 'relative', overflow: 'hidden',
481
491
  }}>
482
- {tool === 'crop' ? (
483
- <img key="crop-canvas" ref={this.imgRef} src={preview?.cUrl || originalUrl} style={{maxWidth: '100%', maxHeight: '100%'}} alt="待裁切"/>
484
- ) : canvasImg?.url ? (
485
- <img src={canvasImg.url} style={{maxWidth: '100%', maxHeight: '100%'}} alt="预览"/>
486
- ) : (
487
- <div style={{color: '#999'}}>生成中...</div>
488
- )}
492
+ {this.renderCanvas(preview, canvasImg, originalUrl)}
489
493
  </div>
490
494
  </div>
491
495
 
@@ -506,7 +510,6 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
506
510
  {tool !== 'crop' && <Divider style={{margin: '0 0 12px'}}/>}
507
511
  <div style={{fontWeight: 600, marginBottom: 8}}>{tool === 'crop' ? '裁切信息' : '图片信息'}</div>
508
512
  {tool === 'crop' ? (
509
- <>
510
513
  <Radio.Group
511
514
  value={cropRatio ? formatRatio(cropRatio.width, cropRatio.height) : 'free'}
512
515
  onChange={(e) => {
@@ -521,7 +524,6 @@ export class FieldUploadImage extends React.Component<FieldUploadImageProps, Fie
521
524
  </Radio>
522
525
  ))}
523
526
  </Radio.Group>
524
- </>
525
527
  ) : (
526
528
  <>
527
529
  {canvasImg && (
@@ -1,5 +1,3 @@
1
- import React from 'react';
2
-
3
1
  /**
4
2
  * 通用字段组件属性接口
5
3
  * @template T - value 的类型
@@ -10,7 +10,7 @@ interface PageFrameProps {
10
10
  }
11
11
 
12
12
  export class PageFrame extends React.Component<PageFrameProps> {
13
- componentRef = React.createRef<any>();
13
+ componentRef = React.createRef<{onShow?: () => void}>();
14
14
 
15
15
  componentDidMount() {
16
16
  this.callOnShowIfActive();
@@ -6,7 +6,7 @@ function safeDecodeURIComponent(s: string): string {
6
6
 
7
7
  export interface RouteDef {
8
8
  path: string;
9
- component: ComponentType<any>;
9
+ component: ComponentType<unknown>;
10
10
  }
11
11
 
12
12
  interface InternalRoute extends RouteDef {
@@ -14,7 +14,7 @@ interface InternalRoute extends RouteDef {
14
14
  }
15
15
 
16
16
  export interface MatchResult {
17
- component: ComponentType<any>;
17
+ component: ComponentType<unknown>;
18
18
  params: Record<string, string>;
19
19
  }
20
20
 
@@ -1,6 +1,6 @@
1
1
  export class ArrayUtils {
2
2
  static contains<T>(arr: T[], item: T): boolean {
3
- return arr.indexOf(item) !== -1;
3
+ return arr.includes(item);
4
4
  }
5
5
 
6
6
  static containsAny<T>(arr: T[], ...items: T[]): boolean {
@@ -10,7 +10,7 @@ export class ArrayUtils {
10
10
  return false;
11
11
  }
12
12
 
13
- static maxBy<T extends Record<K, any>, K extends keyof T>(arr: T[], key: K): T | undefined {
13
+ static maxBy<T extends Record<K, unknown>, K extends keyof T>(arr: T[], key: K): T | undefined {
14
14
  if (arr == null || arr.length === 0) return undefined;
15
15
  let maxElement: T | undefined = undefined;
16
16
  let maxValue = -Infinity;
@@ -62,7 +62,7 @@ export class DateUtils {
62
62
  static friendlyTotalTime(time: number | string | null): string | null {
63
63
  if (time == null || time === '-') return null;
64
64
  let seconds: number;
65
- if (typeof time === 'string') seconds = parseInt(time, 10) / 1000;
65
+ if (typeof time === 'string') seconds = Number.parseInt(time, 10) / 1000;
66
66
  else seconds = time / 1000;
67
67
  seconds = Math.floor(seconds);
68
68
  if (seconds < 60) return seconds + '秒';
@@ -1,4 +1,4 @@
1
- import {GlobalData} from '../../GlobalData';
1
+ import {GlobalData} from '../GlobalData';
2
2
  import {Tag} from 'antd';
3
3
  import React from 'react';
4
4
 
@@ -1,14 +1,14 @@
1
- type EventCallback = (...args: any[]) => void;
1
+ type EventCallback = (...args: unknown[]) => void;
2
2
 
3
3
  interface EventEntry {
4
4
  fn: EventCallback & { __callback?: EventCallback };
5
- ctx?: any;
5
+ ctx?: unknown;
6
6
  }
7
7
 
8
8
  export class EventBus {
9
9
  private static __stack: Record<string, EventEntry[]> = {};
10
10
 
11
- static on<T extends any[] = []>(name: string, callback: (...args: T) => void, ctx?: any): () => void {
11
+ static on<T extends unknown[] = []>(name: string, callback: (...args: T) => void, ctx?: unknown): () => void {
12
12
  if (!EventBus.__stack[name]) {
13
13
  EventBus.__stack[name] = [];
14
14
  }
@@ -16,9 +16,9 @@ export class EventBus {
16
16
  return () => EventBus.off(name, callback);
17
17
  }
18
18
 
19
- static once<T extends any[] = []>(name: string, callback: (...args: T) => void, ctx?: any): () => void {
19
+ static once<T extends unknown[] = []>(name: string, callback: (...args: T) => void, ctx?: unknown): () => void {
20
20
  const unsubscribe = () => EventBus.off(name, callback);
21
- const listener: EventEntry['fn'] = (...args: any[]) => {
21
+ const listener: EventEntry['fn'] = (...args: unknown[]) => {
22
22
  EventBus.off(name, listener);
23
23
  callback.apply(ctx, args);
24
24
  };
@@ -28,7 +28,7 @@ export class EventBus {
28
28
  return unsubscribe;
29
29
  }
30
30
 
31
- static emit<T extends any[] = []>(name: string, ...args: T): void {
31
+ static emit<T extends unknown[] = []>(name: string, ...args: T): void {
32
32
  const list = EventBus.__stack[name];
33
33
  if (list !== undefined) {
34
34
  list.slice(0).forEach(entry => {
@@ -37,7 +37,7 @@ export class EventBus {
37
37
  }
38
38
  }
39
39
 
40
- static off<T extends any[] = []>(name: string, callback?: (...args: T) => void): void {
40
+ static off<T extends unknown[] = []>(name: string, callback?: (...args: T) => void): void {
41
41
  const list = EventBus.__stack[name];
42
42
  if (list === undefined) return;
43
43
  if (callback === undefined) {