@jiangood/open-admin 3.0.11 → 3.0.13

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
@@ -14,8 +14,9 @@
14
14
  "@ant-design/icons": "^6.0.0",
15
15
  "@tinymce/tinymce-react": "^6.0.0",
16
16
  "antd": "^6.0.0",
17
- "antd-img-crop": "^4.23.0",
18
17
  "axios": "^1.13.2",
18
+ "compressorjs": "^1.2.1",
19
+ "cropperjs": "^1.6.2",
19
20
  "dayjs": "^1.11.13",
20
21
  "lodash": "^4.17.23",
21
22
  "qs": "^6.14.0",
@@ -48,5 +49,5 @@
48
49
  "test:e2e": "playwright test",
49
50
  "test:e2e:ui": "playwright test --ui"
50
51
  },
51
- "version": "3.0.11"
52
+ "version": "3.0.13"
52
53
  }
@@ -281,8 +281,7 @@ export class DownloadModal extends React.Component<DownloadModalProps, ModalStat
281
281
  <div style={{padding: '20px 0'}}>
282
282
  {/* 文件名 */}
283
283
  <div style={{marginBottom: 16, fontSize: 15, fontWeight: 500, color: '#333'}}>
284
- <DownloadOutlined style={{marginRight: 8}}/>
285
- {fileName || '未知文件'}
284
+ 文件名:{fileName || '未知文件'}
286
285
  </div>
287
286
 
288
287
  {/* 下载中 */}
@@ -9,6 +9,7 @@ import './index.less'
9
9
  /** 通过 actionRef 暴露的表格操作 */
10
10
  export interface ProTableActionRef {
11
11
  reload: () => void;
12
+ clearSelection: () => void;
12
13
  }
13
14
 
14
15
  /** request 返回结构(Spring Data Page 序列化 + 扩展数据) */
@@ -122,7 +123,8 @@ export class ProTable<T = any> extends React.Component<ProTableProps<T>, ProTabl
122
123
  this.loadData()
123
124
  if (this.props.actionRef) {
124
125
  this.props.actionRef.current = {
125
- reload: () => this.loadData()
126
+ reload: () => this.loadData(),
127
+ clearSelection: () => this.setState({selectedRowKeys: [], selectedRows: []})
126
128
  }
127
129
  }
128
130
 
@@ -1,3 +1,4 @@
1
+ import {Spin} from 'antd';
1
2
  import React from 'react';
2
3
  import {Editor as TinyMceEditor} from '@tinymce/tinymce-react';
3
4
  import {UrlUtils} from '../../utils';
@@ -6,8 +7,8 @@ import type {FieldProps} from '../types';
6
7
  export interface FieldEditorProps extends FieldProps<string> {
7
8
  /** 编辑器高度,默认 300 */
8
9
  height?: number;
9
- /** 图片上传可见性,默认 public(富文本图片需公开访问) */
10
- visibility?: 'public' | 'private';
10
+ /** 是否公开免登录访问,默认 true(富文本图片需公开访问) */
11
+ isPublic?: boolean;
11
12
  }
12
13
 
13
14
  /**
@@ -15,18 +16,42 @@ export interface FieldEditorProps extends FieldProps<string> {
15
16
  *
16
17
  * 图片上传相关配置 https://www.tiny.cloud/docs/tinymce/7/image/
17
18
  */
18
- export class FieldEditor extends React.Component<FieldEditorProps> {
19
+ export class FieldEditor extends React.Component<FieldEditorProps, {loading: boolean}> {
20
+ state = {loading: false};
21
+ private timer: number | undefined;
22
+
23
+ componentDidMount() {
24
+ this.timer = window.setTimeout(() => {
25
+ this.setState({loading: true});
26
+ }, 200);
27
+ }
28
+
29
+ componentWillUnmount() {
30
+ if (this.timer != null) {
31
+ window.clearTimeout(this.timer);
32
+ }
33
+ }
34
+
19
35
  render() {
20
- const visibility = this.props.visibility || 'public';
21
- const uploadUrl = UrlUtils.contextPath('/admin/sysFile/upload') + '?visibility=' + visibility;
36
+ const {loading} = this.state;
37
+ const isPublic = this.props.isPublic ?? true;
38
+ const uploadUrl = UrlUtils.contextPath('/admin/sysFile/upload') + '?isPublic=' + isPublic;
22
39
  const jsUrl = UrlUtils.contextPath('/admin/tinymce/tinymce.min.js');
23
40
  const {value, onChange, height} = this.props;
41
+ const editorHeight = height || 300;
24
42
 
25
43
  return (
26
- <TinyMceEditor
27
- value={value}
28
- tinymceScriptSrc={jsUrl}
29
- init={{
44
+ <div style={{position: 'relative', minHeight: loading ? editorHeight + 44 : undefined}}>
45
+ <TinyMceEditor
46
+ value={value}
47
+ tinymceScriptSrc={jsUrl}
48
+ onInit={() => {
49
+ if (this.timer != null) {
50
+ window.clearTimeout(this.timer);
51
+ }
52
+ this.setState({loading: false});
53
+ }}
54
+ init={{
30
55
  min_height: 300,
31
56
  language: 'zh_CN',
32
57
  height: height,
@@ -54,7 +79,28 @@ export class FieldEditor extends React.Component<FieldEditorProps> {
54
79
  onChange(content);
55
80
  }
56
81
  }}
57
- />
82
+ />
83
+ {loading && (
84
+ <div style={{
85
+ position: 'absolute',
86
+ top: 0,
87
+ left: 0,
88
+ right: 0,
89
+ bottom: 0,
90
+ minHeight: editorHeight + 44,
91
+ display: 'flex',
92
+ flexDirection: 'column',
93
+ alignItems: 'center',
94
+ justifyContent: 'center',
95
+ gap: 8,
96
+ background: '#fff',
97
+ zIndex: 1,
98
+ }}>
99
+ <Spin/>
100
+ <span style={{color: '#999'}}>编辑器加载中...</span>
101
+ </div>
102
+ )}
103
+ </div>
58
104
  );
59
105
  }
60
106
  }
@@ -1,6 +1,4 @@
1
1
  import React from "react";
2
- import ImgCrop from "antd-img-crop";
3
- import type {ImgCropProps} from "antd-img-crop";
4
2
  import {message, Modal, Upload} from "antd";
5
3
  import type {UploadChangeParam, UploadFile, UploadProps} from "antd";
6
4
  import { UploadOutlined } from "@ant-design/icons";
@@ -14,42 +12,34 @@ export type SysUploadFile = UploadFile & { objectName?: string };
14
12
  export interface FieldUploadFileProps extends FieldProps<string> {
15
13
  /** 最大上传数量,默认 1 */
16
14
  maxCount?: number;
17
- /** 是否启用上传前裁切图片 */
18
- cropImage?: boolean;
19
- /** 裁切配置(antd-img-crop 的 cropperProps) */
20
- cropperProps?: ImgCropProps['cropperProps'];
21
15
  /** 上传列表的内建样式,默认 picture-card */
22
16
  listType?: UploadProps['listType'];
23
17
  /** 接受的文件类型,如 image/* */
24
18
  accept?: string;
25
- /** 文件可见性,默认 public */
26
- visibility?: 'public' | 'private';
19
+ /** 是否公开免登录访问,默认 true(private 需登录) */
20
+ isPublic?: boolean;
27
21
  /** 文件列表变化回调(新增文件上传成功后才触发) */
28
22
  onFileChange?: (fileList: SysUploadFile[]) => void;
29
23
  }
30
24
 
31
25
  interface FieldUploadFileState {
32
26
  maxCount: number;
33
- cropImage: boolean;
34
27
  fileList: SysUploadFile[];
35
28
  /** 逗号分隔的文件 objectName */
36
29
  value: string | null;
37
30
  accept?: string;
38
- visibility?: 'public' | 'private';
31
+ isPublic?: boolean;
39
32
  }
40
33
 
41
34
  /**
42
- * 上传图片前裁切, 单张图片
43
- *
44
- * 可参考 react-easy-crop
35
+ * 通用文件上传(不含图片压缩/裁切,图片上传请使用 FieldUploadImage)
45
36
  */
46
37
  export class FieldUploadFile extends React.Component<FieldUploadFileProps, FieldUploadFileState & { errorTitle?: string; errorContent?: string; previewObjectName?: string }> {
47
38
 
48
39
  state: FieldUploadFileState & { errorTitle?: string; errorContent?: string; previewObjectName?: string } = {
49
40
  // 传入的参数
50
41
  maxCount: 1,
51
- cropImage: false,
52
- visibility: 'public',
42
+ isPublic: true,
53
43
 
54
44
  // 内部参数
55
45
  fileList: [],
@@ -65,8 +55,7 @@ export class FieldUploadFile extends React.Component<FieldUploadFileProps, Field
65
55
  componentDidUpdate(prevProps: FieldUploadFileProps) {
66
56
  const next: Partial<FieldUploadFileState> = {};
67
57
  if (this.props.maxCount !== prevProps.maxCount) next.maxCount = this.props.maxCount;
68
- if (this.props.cropImage !== prevProps.cropImage) next.cropImage = this.props.cropImage;
69
- if (this.props.visibility !== prevProps.visibility) next.visibility = this.props.visibility;
58
+ if (this.props.isPublic !== prevProps.isPublic) next.isPublic = this.props.isPublic;
70
59
 
71
60
  const prevValue = prevProps.value ?? null;
72
61
  const curValue = this.props.value ?? null;
@@ -142,12 +131,6 @@ export class FieldUploadFile extends React.Component<FieldUploadFileProps, Field
142
131
  };
143
132
 
144
133
  render() {
145
- if (this.state.cropImage) {
146
- return <ImgCrop cropperProps={this.props.cropperProps} modalTitle={'裁剪图片'} fillColor={null}>
147
- {this.getUpload()}
148
- </ImgCrop>;
149
- }
150
-
151
134
  return <>
152
135
  {this.getUpload()}
153
136
  <Modal open={!!this.state.errorTitle} title={this.state.errorTitle} okText="确定"
@@ -167,7 +150,7 @@ export class FieldUploadFile extends React.Component<FieldUploadFileProps, Field
167
150
 
168
151
  return <Upload
169
152
  action={UrlUtils.contextPath('/admin/sysFile/upload')}
170
- data={{visibility: this.state.visibility}}
153
+ data={{isPublic: this.state.isPublic}}
171
154
  listType={this.props.listType || 'picture-card'}
172
155
  fileList={fileList}
173
156
  onChange={this.handleChange}