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 export async function imgPicker(params: PickerAssetParams): Promise export async function imgPicker( params: PickerUriParams | PickerAssetParams ): Promise { 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