chore: 调整文件上传文件体积展示,转成 KB, MB 等展示,而不是字节 (#5328)

* chore: 调整文件上传文件体积展示,转成 KB, MB 等展示,而不是字节

* 落改了一个

* 修复正则错误

* 修复正则错误
This commit is contained in:
liaoxuezhi 2022-09-09 15:04:20 +08:00 committed by RUNZE LU
parent 157949f27c
commit be0ff2991e
8 changed files with 50 additions and 40 deletions

View File

@ -72,6 +72,26 @@ order: 21
想要限制多个类型,则用逗号分隔,例如:`.csv,.md`
## 限制文件大小
可以配置`maxSize`来限制文件大小
```schema: scope="body"
{
"type": "form",
"api": "/api/mock2/form/saveForm",
"body": [
{
"type": "input-file",
"name": "file",
"label": "不能上传超过 1M 的文件",
"maxSize": 1048576,
"receiver": "/api/upload/file"
}
]
}
```
## 手动上传
如果不希望 File 组件上传,可以配置 `asBlob` 或者 `asBase64`,采用这种方式后,组件不再自己上传了,而是直接把文件数据作为表单项的值,文件内容会在 Form 表单提交的接口里面一起带上。

View File

@ -170,7 +170,7 @@ export function formulaExec(
const curValue = value.trim(); // 剔除前后空格
// OpenFormulaExecEvalMode 为 true 时,非 ${ xxx } 格式也会尝试使用表达式运算器
if (OpenFormulaExecEvalMode && /^[0-9a-zA-z_]+$/.test(curValue)) {
if (OpenFormulaExecEvalMode && /^[0-9a-zA-Z_]+$/.test(curValue)) {
// 普通字符串类型(非表达式),先试一下从上下文中获取数据
const curValueTemp = FormulaExec['var'](curValue, data);
// 备注: 其他特殊格式,比如邮箱、日期

View File

@ -1,6 +1,6 @@
const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
export const prettyBytes = (num: number) => {
export const prettyBytes = (num: number, step = 1000) => {
if (!Number.isFinite(num)) {
throw new TypeError(`Expected a finite number, got ${typeof num}: ${num}`);
}
@ -16,10 +16,10 @@ export const prettyBytes = (num: number) => {
}
const exponent = Math.min(
Math.floor(Math.log(num) / Math.log(1000)),
Math.floor(Math.log(num) / Math.log(step)),
UNITS.length - 1
);
const numStr = Number((num / Math.pow(1000, exponent)).toPrecision(3));
const numStr = Number((num / Math.pow(step, exponent)).toPrecision(3));
const unit = UNITS[exponent];
return (neg ? '-' : '') + numStr + ' ' + unit;

View File

@ -130,12 +130,13 @@ register('de-DE', {
'File.failed': 'Fehlerhafte Dateien',
'File.invalidType': '{{files}} entspricht nicht Typ `{{accept}}`',
'File.maxSize':
'{{filename}} überschreitet die maximale Größe von {{maxsize}} (in Byte)',
'{{filename}} überschreitet die maximale Größe von {{maxSize}}',
'File.pause': 'Hochladen anhalten',
'File.repick': 'Erneut suswählen',
'File.result':
'Erfolgreich hochgeladene Dateien: {{uploaded}}, nicht hochgeladene Dateien: {{failed}}',
'File.retry': 'Wiederholen',
'File.sizeLimit': 'Die maximale Dateigröße ist {{maxSize}}',
'File.start': 'Hochladen beginnen',
'File.upload': 'Hochladen',
'Image.upload': 'Hochladen',

View File

@ -128,13 +128,13 @@ register('en-US', {
'File.invalidType': '{{files}} does not match type `{{accept}}`',
'File.maxLength': 'The maximum limit is {{maxLength}}',
'File.maxSize':
'{{filename}} you selected exceeds the maximum limit of {{maxsize}} (in bytes)',
'{{filename}} you selected exceeds the maximum limit of {{maxSize}}',
'File.pause': 'Pause uplaod',
'File.repick': 'Repick',
'File.result':
'Successfully uploaded {{uploaded}} files, failed to upload {{failed}} files',
'File.retry': 'Retry',
'File.sizeLimit': 'The maximum file size is {{maxSize}} B',
'File.sizeLimit': 'The maximum file size is {{maxSize}}',
'File.start': 'Start upload',
'File.upload': 'Upload',
'Image.upload': 'Upload image',

View File

@ -133,12 +133,12 @@ register('zh-CN', {
'File.invalidType': '{{files}} 不符合类型的 {{accept}} 的设定,请仔细检查',
'File.maxLength': '最多上传 {{maxLength}} 个文件',
'File.maxSize':
'{{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} (字节)的限制',
'{{filename}} 大小为 {{actualSize}} 超出了最大为 {{maxSize}} 的限制',
'File.pause': '暂停上传',
'File.repick': '重新选择',
'File.result': '已成功上传 {{uploaded}} 个文件,{{failed}} 个文件上传失败,',
'File.retry': '重试上传',
'File.sizeLimit': '文件大小不超过 {{maxSize}} B',
'File.sizeLimit': '文件大小不超过 {{maxSize}}',
'File.start': '开始上传',
'File.upload': '文件上传',
'Image.upload': '图片上传',

View File

@ -1,8 +1,7 @@
import React from 'react';
import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
import {FormItem, FormControlProps, prettyBytes} from 'amis-core';
import find from 'lodash/find';
import isPlainObject from 'lodash/isPlainObject';
import ImageControl from './InputImage';
import {Payload, ApiObject, ApiString, ActionObject} from 'amis-core';
import {qsstringify, createObject, guid, isEmpty} from 'amis-core';
import {
@ -21,8 +20,7 @@ import {
FormBaseControlSchema,
SchemaApi,
SchemaClassName,
SchemaTokenizeableString,
SchemaUrlPath
SchemaTokenizeableString
} from '../../Schema';
import merge from 'lodash/merge';
import omit from 'lodash/omit';
@ -515,8 +513,8 @@ export default class FileControl extends React.Component<FileProps, FileState> {
// this.props.env.alert(
// __('File.maxSize', {
// filename: file[nameField as keyof typeof file] || file.name,
// actualSize: ImageControl.formatFileSize(file.size),
// maxSize: ImageControl.formatFileSize(maxSize)
// actualSize: prettyBytes(file.size),
// maxSize: prettyBytes(maxSize)
// })
// );
file.state = 'invalid';
@ -1409,7 +1407,9 @@ export default class FileControl extends React.Component<FileProps, FileState> {
</div>
{maxSize ? (
<div className={cx('FileControl-sizeTip')}>
{__('File.sizeLimit', {maxSize})}
{__('File.sizeLimit', {
maxSize: prettyBytes(maxSize, 1024)
})}
</div>
) : null}
</div>
@ -1456,7 +1456,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
{maxSize && !drag ? (
<div className={cx('FileControl-sizeTip')}>
{__('File.sizeLimit', {maxSize})}
{__('File.sizeLimit', {maxSize: prettyBytes(maxSize, 1024)})}
</div>
) : null}
@ -1478,10 +1478,8 @@ export default class FileControl extends React.Component<FileProps, FileState> {
(maxSize && file.size > maxSize
? __('File.maxSize', {
filename: file.name,
actualSize: ImageControl.formatFileSize(
file.size
),
maxSize: ImageControl.formatFileSize(maxSize)
actualSize: prettyBytes(file.size, 1024),
maxSize: prettyBytes(maxSize, 1024)
})
: '')
: ''

View File

@ -1,5 +1,10 @@
import React, {Suspense} from 'react';
import {FormItem, FormControlProps, FormBaseControl} from 'amis-core';
import {
FormItem,
FormControlProps,
FormBaseControl,
prettyBytes
} from 'amis-core';
// import 'cropperjs/dist/cropper.css';
const Cropper = React.lazy(() => import('react-cropper'));
import DropZone from 'react-dropzone';
@ -341,20 +346,6 @@ export default class ImageControl extends React.Component<
dropCrop: true
};
static formatFileSize(
size: number | string,
units = [' B', ' KB', ' M', ' G']
) {
size = parseInt(size as string, 10) || 0;
while (size > 1024 && units.length > 1) {
size /= 1024;
units.shift();
}
return size.toFixed(2) + units[0];
}
static valueToFile(
value: string | object,
props?: ImageProps
@ -997,8 +988,8 @@ export default class ImageControl extends React.Component<
this.props.env.alert(
__('File.maxSize', {
filename: file.name,
actualSize: ImageControl.formatFileSize(file.size),
maxSize: ImageControl.formatFileSize(maxSize)
actualSize: prettyBytes(file.size, 1024),
maxSize: prettyBytes(maxSize, 1024)
})
);
return;
@ -1563,9 +1554,9 @@ export default class ImageControl extends React.Component<
</div>,
file.info.len ? (
<div key="size">
{ImageControl.formatFileSize(
{prettyBytes(
file.info.len
)}
, 1024)}
</div>
) : null
]