| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import { useState } from 'react'
- import { View, Image } from '@tarojs/components'
- import Taro from '@tarojs/taro'
- import { cn } from '../utils/cn'
- interface AvatarUploadProps {
- currentAvatar?: string
- onUploadSuccess?: (result: any) => void
- onUploadError?: (error: Error) => void
- size?: number
- editable?: boolean
- }
- export function AvatarUpload({
- currentAvatar,
- onUploadSuccess,
- onUploadError,
- size = 96,
- editable = true
- }: AvatarUploadProps) {
- const [uploading, setUploading] = useState(false)
- const [progress, setProgress] = useState(0)
- const handleChooseImage = async () => {
- if (!editable || uploading) return
- // 简化版本:只显示提示,不实际处理上传
- Taro.showToast({
- title: '头像上传功能需要在项目中实现',
- icon: 'none'
- })
- // 调用错误回调,提示需要实现
- onUploadError?.(new Error('头像上传功能需要在项目中实现,请参考原mini项目中的minio工具'))
- }
- const avatarSize = size
- return (
- <View
- className="relative inline-block"
- onClick={handleChooseImage}
- >
- <View
- className={cn(
- "relative overflow-hidden rounded-full",
- "border-4 border-white shadow-lg",
- editable && "cursor-pointer active:scale-95 transition-transform duration-150",
- uploading && "opacity-75"
- )}
- style={{ width: avatarSize, height: avatarSize }}
- >
- <Image
- src={currentAvatar || 'https://images.unsplash.com/photo-1494790108755-2616b612b786?w=160&h=160&fit=crop&crop=face'}
- mode="aspectFill"
- className="w-full h-full"
- />
- {uploading && (
- <View className="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center">
- <View className="text-white text-xs">{progress}%</View>
- </View>
- )}
- </View>
- {editable && !uploading && (
- <View
- className={cn(
- "absolute -bottom-1 -right-1",
- "w-8 h-8 bg-blue-500 rounded-full",
- "flex items-center justify-center shadow-md",
- "border-2 border-white"
- )}
- >
- <View className="i-heroicons-camera-20-solid w-4 h-4 text-white" />
- </View>
- )}
- {uploading && (
- <View
- className={cn(
- "absolute -bottom-1 -right-1",
- "w-8 h-8 bg-gray-500 rounded-full",
- "flex items-center justify-center shadow-md",
- "border-2 border-white"
- )}
- >
- <View className="i-heroicons-arrow-path-20-solid w-4 h-4 text-white animate-spin" />
- </View>
- )}
- </View>
- )
- }
|