174 lines
5.4 KiB
TypeScript
174 lines
5.4 KiB
TypeScript
import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'
|
|
import { Image, View, Text, ScrollView, Button } from '@tarojs/components'
|
|
import Taro from '@tarojs/taro'
|
|
import img from '../../config/images'
|
|
import publishService from '../../services/publishService'
|
|
import { CommonPopup } from '../'
|
|
import emptyStatus from '../../static/emptyStatus/publish-empty.png'
|
|
|
|
import './upload-source-popup.scss'
|
|
|
|
type SourceType = 'history' | 'preset'
|
|
|
|
type ImageItem = {
|
|
id: string
|
|
url: string
|
|
tempFilePath?: string
|
|
}
|
|
|
|
interface UploadImageProps {
|
|
onAdd: (images: ImageItem[]) => void
|
|
}
|
|
|
|
export const sourceMap = new Map<SourceType, string>([
|
|
['history', '历史图库'],
|
|
['preset', '预设图库']
|
|
])
|
|
|
|
const checkImageSelected = (images: ImageItem[], image: ImageItem) => {
|
|
return images.some(item => item.id === image.id)
|
|
}
|
|
|
|
export default forwardRef(function UploadImage(props: UploadImageProps, ref) {
|
|
const {
|
|
onAdd = () => void 0,
|
|
} = props
|
|
const [visible, setVisible] = useState(false)
|
|
const [sourceType, setSourceType] = useState<SourceType>('history')
|
|
const [maxCount, setMaxCount] = useState(9)
|
|
const [images, setImages] = useState<ImageItem[]>([])
|
|
const [selectedImages, setSelectedImages] = useState<ImageItem[]>([])
|
|
|
|
const handleImageClick = (image: ImageItem) => {
|
|
if (checkImageSelected(selectedImages, image)) {
|
|
setSelectedImages(selectedImages.filter(item => item.id !== image.id))
|
|
} else if (!outOfMax) {
|
|
setSelectedImages([...selectedImages, image])
|
|
} else {
|
|
Taro.showToast({
|
|
title: `最多选择${maxCount}张图片`,
|
|
icon: 'none'
|
|
})
|
|
}
|
|
}
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
show: (sourceType: SourceType, maxCount: number) => {
|
|
setVisible(true)
|
|
setSourceType(sourceType)
|
|
setMaxCount(maxCount)
|
|
fetchImages()
|
|
}
|
|
}))
|
|
|
|
function fetchImages() {
|
|
publishService.getPictures({
|
|
pageOption: {
|
|
page: 1,
|
|
pageSize: 100,
|
|
},
|
|
seachOption: {
|
|
tag: '',
|
|
resource_type: 'image',
|
|
dateRange: [],
|
|
},
|
|
}).then(res => {
|
|
if (res.success) {
|
|
let start = 0
|
|
setImages(res.data.data.rows.map(item => ({
|
|
id: (Date.now() + start++).toString(),
|
|
url: item.thumbnail_url,
|
|
})))
|
|
} else {
|
|
// TODO: 显示错误信息
|
|
Taro.showToast({
|
|
title: res.message,
|
|
icon: 'none'
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
function onClose() {
|
|
setVisible(false)
|
|
setSelectedImages([])
|
|
setImages([])
|
|
setSourceType('history')
|
|
setMaxCount(9)
|
|
}
|
|
|
|
const handleConfirm = () => {
|
|
if (selectedImages.length > 0) {
|
|
onAdd(selectedImages)
|
|
setVisible(false)
|
|
} else {
|
|
Taro.showToast({
|
|
title: '请选择图片',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
}
|
|
|
|
const outOfMax = selectedImages.length >= maxCount
|
|
|
|
return (
|
|
<>
|
|
<CommonPopup
|
|
visible={visible}
|
|
onClose={onClose}
|
|
round
|
|
hideFooter
|
|
position='bottom'
|
|
zIndex={1001}
|
|
>
|
|
<View className="upload-popup">
|
|
<View className="upload-popup-title">{sourceMap.get(sourceType)}</View>
|
|
{/* TODO: 分页 加载更多 */}
|
|
{/* TODO: 图片加载失败 */}
|
|
{/* TODO: 图片加载中 */}
|
|
<ScrollView
|
|
scrollY
|
|
className="upload-popup-scroll-view"
|
|
>
|
|
{images.length > 0 ? (
|
|
<View className="upload-popup-image-list">
|
|
{images.map(item => {
|
|
const isSelected = checkImageSelected(selectedImages, item)
|
|
return (
|
|
<View className={`upload-popup-image-item ${outOfMax ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`} onClick={() => handleImageClick(item)}>
|
|
<Image className="upload-popup-image-item-image" src={item.url} />
|
|
<View className={`upload-popup-image-item-select ${isSelected ? 'selected' : ''}`}>
|
|
{isSelected ? (
|
|
<Image className="select-image-icon" src={img.ICON_CIRCLE_SELECT_ARROW} />
|
|
) : (
|
|
<Image className="select-image-icon" src={img.ICON_CIRCLE_UNSELECT} />
|
|
)}
|
|
</View>
|
|
</View>
|
|
)
|
|
})}
|
|
</View>
|
|
) : (
|
|
<View className="upload-popup-image-list-empty">
|
|
<Image className="upload-popup-image-list-empty-image" src={emptyStatus} />
|
|
<Text className="upload-popup-image-list-empty-text">暂无内容</Text>
|
|
</View>
|
|
)}
|
|
</ScrollView>
|
|
{images.length > 0 ? (
|
|
<View className="upload-popup-footer">
|
|
<Button className="upload-popup-footer-cancel" onClick={() => setVisible(false)}>取消</Button>
|
|
<Button className={`upload-popup-footer-confirm ${selectedImages.length > 0 ? 'active' : ''}`} type='primary' onClick={handleConfirm}>完成</Button>
|
|
</View>
|
|
) : (
|
|
<View className="upload-popup-footer">
|
|
<Button className="upload-popup-footer-cancel" onClick={() => setVisible(false)}>取消</Button>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</CommonPopup>
|
|
{/* <View className="upload-source-popup-text" onClick={() => setVisible(true)}>{sourceMap.get(sourceType)}选取</View> */}
|
|
</>
|
|
);
|
|
});
|