feat: add image picker utility and integrate image upload in DynamicForm component

This commit is contained in:
imeepos
2026-01-26 13:04:14 +08:00
parent 3fd445bb6e
commit 01865d94c2
5 changed files with 194 additions and 23 deletions

82
lib/imgPicker.ts Normal file
View File

@@ -0,0 +1,82 @@
import * as ImagePicker from 'expo-image-picker'
import Toast from '@/components/ui/Toast'
// 定义图片选择器参数类型
type PickerBaseParams = Omit<
ImagePicker.ImagePickerOptions,
'mediaTypes' | 'allowsMultipleSelection' | 'selectionLimit'
> & {
/** 最大选择图片数量,默认 1 */
maxImages?: number
/** 媒体类型,默认仅图片 */
type?: ImagePicker.MediaTypeOptions
}
type PickerUriParams = PickerBaseParams & {
/** 返回类型uri 返回字符串数组 */
resultType?: 'uri'
}
type PickerAssetParams = PickerBaseParams & {
/** 返回类型asset 返回完整资源对象 */
resultType: 'asset'
}
/**
* 图片选择器工具
* 直接打开系统相册选择图片
*
* @example
* // 选择单张图片,返回 URI
* const [uri] = await imgPicker({ maxImages: 1 })
*
* // 选择多张图片,返回 URI 数组
* const uris = await imgPicker({ maxImages: 9 })
*
* // 返回完整资源对象(包含宽高等信息)
* const assets = await imgPicker({ maxImages: 1, resultType: 'asset' })
*/
export async function imgPicker(params: PickerUriParams): Promise<string[]>
export async function imgPicker(params: PickerAssetParams): Promise<ImagePicker.ImagePickerAsset[]>
export async function imgPicker(
params: PickerUriParams | PickerAssetParams
): Promise<string[] | ImagePicker.ImagePickerAsset[]> {
const {
maxImages = 1,
type = ImagePicker.MediaTypeOptions.Images,
resultType = 'uri',
...rest
} = params
const isMultiple = maxImages > 1
// 请求相册权限
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync()
if (status !== 'granted') {
Toast.show('请开启相册权限')
throw new Error('请开启相册权限')
}
// 打开相册选择图片
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: type,
quality: 0.9,
allowsMultipleSelection: isMultiple,
selectionLimit: maxImages,
...rest,
})
// 用户取消选择
if (result.canceled || !result.assets?.length) {
throw new Error('未选择任何图片')
}
// 根据 resultType 返回不同格式
if (resultType === 'uri') {
return result.assets.map((asset) => asset.uri)
}
return result.assets
}
export default imgPicker