mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-30 02:48:55 +08:00
feat:图片上传支持配置占位图样式及其比例等 (#1665)
* feat:图片上传支持配置占位图样式及其比例等 * fix conflict * 更新snapshot * feat:表格中图片上传支持默认图片 * 增加fixedSize配置项支持用户自定义图片框尺寸 * 拆分fixedSize配置项 * 删除无用代码 Co-authored-by: 邓黔川 <dengqianchuan@baidu.com> Co-authored-by: dqc <qianchuan.deng@gmail.com>
This commit is contained in:
parent
9084267867
commit
8bdc387bd4
@ -115,36 +115,36 @@ exports[`Renderer:button-group 1`] = `
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
@ -267,36 +267,36 @@ exports[`Renderer:button-group:multiple clearable 1`] = `
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
@ -419,36 +419,36 @@ exports[`Renderer:button-group:multiple clearable 2`] = `
|
||||
class="resize-sensor"
|
||||
style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-expand"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0px; top: 0px; width: 10px; height: 10px;"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-shrink"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;"
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
style="position: absolute; left: 0; top: 0; width: 200%; height: 200%"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="resize-sensor-appear"
|
||||
style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;animation-name: apearSensor; animation-duration: 0.2s;"
|
||||
|
@ -1542,6 +1542,12 @@ exports[`Renderer:Wizard initApi reload 3`] = `
|
||||
<div
|
||||
class="a-Page-body"
|
||||
>
|
||||
<div
|
||||
class="a-Spinner-overlay"
|
||||
/>
|
||||
<div
|
||||
class="a-Spinner a-Spinner--overlay a-Spinner--lg"
|
||||
/>
|
||||
<div
|
||||
class="a-Panel a-Panel--default a-Wizard a-Wizard--horizontal"
|
||||
style="position: relative;"
|
||||
|
@ -160,25 +160,28 @@ order: 27
|
||||
|
||||
除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ---------------- | ------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| receiver | [API](../../../docs/types/api) | | 上传文件接口 |
|
||||
| accept | `string` | `.jpeg,.jpg,.png,.gif` | 支持的图片类型格式,请配置此属性为图片后缀,例如`.jpg,.png` |
|
||||
| maxSize | `number` | | 默认没有限制,当设置后,文件大小大于此值将不允许上传。单位为`B` |
|
||||
| maxLength | `number` | | 默认没有限制,当设置后,一次只允许上传指定数量文件。 |
|
||||
| multiple | `boolean` | `false` | 是否多选。 |
|
||||
| joinValues | `boolean` | `true` | [拼接值](./options#%E6%8B%BC%E6%8E%A5%E5%80%BC-joinvalues) |
|
||||
| extractValue | `boolean` | `false` | [提取值](./options#%E6%8F%90%E5%8F%96%E5%A4%9A%E9%80%89%E5%80%BC-extractvalue) |
|
||||
| delimeter | `string` | `,` | [拼接符](./options#%E6%8B%BC%E6%8E%A5%E7%AC%A6-delimiter) |
|
||||
| autoUpload | `boolean` | `true` | 否选择完就自动开始上传 |
|
||||
| hideUploadButton | `boolean` | `false` | 隐藏上传按钮 |
|
||||
| fileField | `string` | `file` | 如果你不想自己存储,则可以忽略此属性。 |
|
||||
| crop | `boolean`或`{"aspectRatio":""}` | | 用来设置是否支持裁剪。 |
|
||||
| crop.aspectRatio | `number` | | 裁剪比例。浮点型,默认 `1` 即 `1:1`,如果要设置 `16:9` 请设置 `1.7777777777777777` 即 `16 / 9`。。 |
|
||||
| crop.rotatable | `boolean` | `false` | 裁剪时是否可旋转 |
|
||||
| crop.scalable | `boolean` | `false` | 裁剪时是否可缩放 |
|
||||
| crop.viewMode | `number` | `1` | 裁剪时的查看模式,0 是无限制 |
|
||||
| limit | Limit | | 限制图片大小,超出不让上传。 |
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| ------------------ | ------------------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| receiver | [API](../../../docs/types/api) | | 上传文件接口 |
|
||||
| accept | `string` | `.jpeg,.jpg,.png,.gif` | 支持的图片类型格式,请配置此属性为图片后缀,例如`.jpg,.png` |
|
||||
| maxSize | `number` | | 默认没有限制,当设置后,文件大小大于此值将不允许上传。单位为`B` |
|
||||
| maxLength | `number` | | 默认没有限制,当设置后,一次只允许上传指定数量文件。 |
|
||||
| multiple | `boolean` | `false` | 是否多选。 |
|
||||
| joinValues | `boolean` | `true` | [拼接值](./options#%E6%8B%BC%E6%8E%A5%E5%80%BC-joinvalues) |
|
||||
| extractValue | `boolean` | `false` | [提取值](./options#%E6%8F%90%E5%8F%96%E5%A4%9A%E9%80%89%E5%80%BC-extractvalue) |
|
||||
| delimeter | `string` | `,` | [拼接符](./options#%E6%8B%BC%E6%8E%A5%E7%AC%A6-delimiter) |
|
||||
| autoUpload | `boolean` | `true` | 否选择完就自动开始上传 |
|
||||
| hideUploadButton | `boolean` | `false` | 隐藏上传按钮 |
|
||||
| fileField | `string` | `file` | 如果你不想自己存储,则可以忽略此属性。 |
|
||||
| crop | `boolean`或`{"aspectRatio":""}` | | 用来设置是否支持裁剪。 |
|
||||
| crop.aspectRatio | `number` | | 裁剪比例。浮点型,默认 `1` 即 `1:1`,如果要设置 `16:9` 请设置 `1.7777777777777777` 即 `16 / 9`。。 |
|
||||
| crop.rotatable | `boolean` | `false` | 裁剪时是否可旋转 |
|
||||
| crop.scalable | `boolean` | `false` | 裁剪时是否可缩放 |
|
||||
| crop.viewMode | `number` | `1` | 裁剪时的查看模式,0 是无限制 |
|
||||
| limit | Limit | | 限制图片大小,超出不让上传。 |
|
||||
| defaultImage | `string` | | 默认占位图地址 |
|
||||
| fixedSize | `boolean` | | 是否开启固定尺寸 |
|
||||
| fixedSizeClassName | `string` | | 开启固定尺寸时,根据此值控制展示尺寸。例如`h-30`,即图片框高为 h-30,最终上传图片根据此尺寸对应缩放。也可同时设置设置宽度的类名,例如`h-30 w-52`,若不设置宽度类名,则根据父元素尺寸自适应 |
|
||||
|
||||
### Limit 属性表
|
||||
|
||||
|
@ -788,6 +788,20 @@ export default {
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
type: 'image',
|
||||
name: 'image',
|
||||
inputClassName: 'w-52',
|
||||
label: '图片有默认占位图',
|
||||
defaultImage:
|
||||
'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3893101144,2877209892&fm=23&gp=0.jpg',
|
||||
fixedSize: true,
|
||||
fixedSizeClassName: 'h-32',
|
||||
thumbMode: 'contain'
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
type: 'image',
|
||||
name: 'imageCrop',
|
||||
|
@ -39,6 +39,22 @@
|
||||
height: px2rem(108px * 9 / 16);
|
||||
}
|
||||
|
||||
&-thumb--fixed-size {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&-thumb--fixed-size &-thumb {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
> img {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&-thumb--w-full > img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
|
@ -94,8 +94,9 @@
|
||||
width: px2rem(108px);
|
||||
height: px2rem(108px);
|
||||
display: none;
|
||||
top: px2rem(5px);
|
||||
left: px2rem(5px);
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -253,4 +254,15 @@
|
||||
line-height: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-fixed-size {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&-fixed-size &-itemOverlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
SchemaTokenizeableString,
|
||||
SchemaUrlPath
|
||||
} from '../../Schema';
|
||||
import {filter} from '../../utils/tpl';
|
||||
|
||||
/**
|
||||
* Image 图片上传控件
|
||||
@ -222,6 +223,21 @@ export interface ImageControlSchema extends FormBaseControl {
|
||||
autoFill?: {
|
||||
[propName: string]: SchemaTokenizeableString;
|
||||
};
|
||||
|
||||
/**
|
||||
* 默认图片地址
|
||||
*/
|
||||
defaultImage?: SchemaUrlPath;
|
||||
|
||||
/**
|
||||
* 是否开启固定尺寸
|
||||
*/
|
||||
fixedSize?: boolean;
|
||||
|
||||
/**
|
||||
* 固定尺寸的 CSS类名
|
||||
*/
|
||||
fixedSizeClassName?: SchemaClassName;
|
||||
}
|
||||
|
||||
let preventEvent = (e: any) => e.stopPropagation();
|
||||
@ -933,7 +949,7 @@ export default class ImageControl extends React.Component<
|
||||
Math.abs(width / height - limit.aspectRatio) > 0.01
|
||||
) {
|
||||
error = __(limit.aspectRatioLabel || 'Image.limitRatio', {
|
||||
ratio: limit.aspectRatio
|
||||
ratio: limit.aspectRatio.toFixed(2)
|
||||
});
|
||||
}
|
||||
|
||||
@ -1095,6 +1111,9 @@ export default class ImageControl extends React.Component<
|
||||
thumbMode,
|
||||
thumbRatio,
|
||||
reCropable,
|
||||
defaultImage,
|
||||
fixedSize,
|
||||
fixedSizeClassName,
|
||||
translate: __
|
||||
} = this.props;
|
||||
|
||||
@ -1170,12 +1189,17 @@ export default class ImageControl extends React.Component<
|
||||
? files.map((file, key) => (
|
||||
<div
|
||||
key={file.id || key}
|
||||
className={cx('ImageControl-item', {
|
||||
'is-uploaded': file.state !== 'uploading',
|
||||
'is-invalid':
|
||||
file.state === 'error' ||
|
||||
file.state === 'invalid'
|
||||
})}
|
||||
className={cx(
|
||||
'ImageControl-item',
|
||||
{
|
||||
'is-uploaded': file.state !== 'uploading',
|
||||
'is-invalid':
|
||||
file.state === 'error' ||
|
||||
file.state === 'invalid'
|
||||
},
|
||||
fixedSize ? 'ImageControl-fixed-size' : '',
|
||||
fixedSize ? fixedSizeClassName : ''
|
||||
)}
|
||||
>
|
||||
{file.state === 'invalid' ||
|
||||
file.state === 'error' ? (
|
||||
@ -1194,9 +1218,14 @@ export default class ImageControl extends React.Component<
|
||||
</a>
|
||||
|
||||
<a
|
||||
className={cx('ImageControl-retryBtn', {
|
||||
'is-disabled': disabled
|
||||
})}
|
||||
className={cx(
|
||||
'ImageControl-retryBtn',
|
||||
{
|
||||
'is-disabled': disabled
|
||||
},
|
||||
fixedSize ? 'ImageControl-fixed-size' : '',
|
||||
fixedSize ? fixedSizeClassName : ''
|
||||
)}
|
||||
onClick={this.handleRetry.bind(this, key)}
|
||||
>
|
||||
<Icon icon="retry" className="icon" />
|
||||
@ -1221,7 +1250,11 @@ export default class ImageControl extends React.Component<
|
||||
</a>
|
||||
<div
|
||||
key="info"
|
||||
className={cx('ImageControl-itemInfo')}
|
||||
className={cx(
|
||||
'ImageControl-itemInfo',
|
||||
fixedSize ? 'ImageControl-fixed-size' : '',
|
||||
fixedSize ? fixedSizeClassName : ''
|
||||
)}
|
||||
>
|
||||
<p>{__('File.uploading')}</p>
|
||||
<div className={cx('ImageControl-progress')}>
|
||||
@ -1242,7 +1275,10 @@ export default class ImageControl extends React.Component<
|
||||
<>
|
||||
<ImageComponent
|
||||
key="image"
|
||||
className={cx('ImageControl-image')}
|
||||
className={cx(
|
||||
'ImageControl-image',
|
||||
fixedSize ? 'Image-thumb--fixed-size' : ''
|
||||
)}
|
||||
onLoad={this.handleImageLoaded.bind(
|
||||
this,
|
||||
key
|
||||
@ -1333,14 +1369,29 @@ export default class ImageControl extends React.Component<
|
||||
{(multiple && (!maxLength || files.length < maxLength)) ||
|
||||
(!multiple && !files.length) ? (
|
||||
<label
|
||||
className={cx('ImageControl-addBtn', {
|
||||
'is-disabled': disabled
|
||||
})}
|
||||
className={cx(
|
||||
'ImageControl-addBtn',
|
||||
{
|
||||
'is-disabled': disabled
|
||||
},
|
||||
fixedSize ? 'ImageControl-fixed-size' : '',
|
||||
fixedSize ? fixedSizeClassName : ''
|
||||
)}
|
||||
onClick={this.handleSelect}
|
||||
data-tooltip={__(placeholder)}
|
||||
data-position="right"
|
||||
>
|
||||
<Icon icon="plus" className="icon" />
|
||||
{defaultImage ? (
|
||||
<ImageComponent
|
||||
key="upload-default-image"
|
||||
src={filter(defaultImage, this.props.data, '| raw')}
|
||||
className={cx(
|
||||
fixedSize ? 'Image-thumb--fixed-size' : ''
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<Icon icon="plus" className="icon" />
|
||||
)}
|
||||
|
||||
{isFocused ? (
|
||||
<span className={cx('ImageControl-pasteTip')}>
|
||||
|
Loading…
Reference in New Issue
Block a user