|
|
@@ -1,5 +1,5 @@
|
|
|
-import React, { useEffect } from 'react'
|
|
|
-import { View, Text, ScrollView } from '@tarojs/components'
|
|
|
+import React, { useEffect, useState } from 'react'
|
|
|
+import { View, Text, ScrollView, Video } from '@tarojs/components'
|
|
|
import Taro from '@tarojs/taro'
|
|
|
import { useQuery } from '@tanstack/react-query'
|
|
|
import { PageContainer } from '@d8d/mini-shared-ui-components/components/page-container'
|
|
|
@@ -25,6 +25,10 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
const router = Taro.useRouter()
|
|
|
const talentId = router.params.id ? parseInt(router.params.id) : 0
|
|
|
|
|
|
+ // 视频播放器状态
|
|
|
+ const [showVideoPlayer, setShowVideoPlayer] = useState(false)
|
|
|
+ const [currentVideoUrl, setCurrentVideoUrl] = useState<string>('')
|
|
|
+
|
|
|
// 获取人才基本信息
|
|
|
const { data: talentDetail, isLoading: talentLoading, error: talentError } = useQuery({
|
|
|
queryKey: ['talentDetail', talentId],
|
|
|
@@ -271,6 +275,28 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
return `¥${amount.toLocaleString()}`
|
|
|
}
|
|
|
|
|
|
+ // 判断文件类型的辅助函数
|
|
|
+ const getFileType = (url: string): 'image' | 'video' | 'other' => {
|
|
|
+ // 从 URL 中提取文件扩展名
|
|
|
+ const urlLower = url.toLowerCase()
|
|
|
+ const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg']
|
|
|
+ const videoExtensions = ['.mp4', '.mov', '.avi', '.mkv', '.wmv', '.flv', '.m4v']
|
|
|
+
|
|
|
+ for (const ext of imageExtensions) {
|
|
|
+ if (urlLower.includes(ext)) {
|
|
|
+ return 'image'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const ext of videoExtensions) {
|
|
|
+ if (urlLower.includes(ext)) {
|
|
|
+ return 'video'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 'other'
|
|
|
+ }
|
|
|
+
|
|
|
// 打开文件URL的函数
|
|
|
const handleOpenFile = (url?: string, _fileName?: string) => {
|
|
|
if (!url) {
|
|
|
@@ -285,31 +311,65 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
// 在H5环境中使用window.open
|
|
|
if (process.env.TARO_ENV === 'h5') {
|
|
|
window.open(url, '_blank')
|
|
|
- } else {
|
|
|
- // 在小程序中使用Taro.openDocument
|
|
|
- Taro.downloadFile({
|
|
|
- url: url,
|
|
|
- success: (res) => {
|
|
|
- if (res.statusCode === 200) {
|
|
|
- Taro.openDocument({
|
|
|
- filePath: res.tempFilePath,
|
|
|
- showMenu: true,
|
|
|
- fail: (_err) => {
|
|
|
- Taro.showToast({
|
|
|
- title: '文件打开失败',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 在小程序中根据文件类型选择不同的处理方式
|
|
|
+ const fileType = getFileType(url)
|
|
|
+
|
|
|
+ switch (fileType) {
|
|
|
+ case 'image':
|
|
|
+ // 图片文件使用 Taro.previewImage 预览
|
|
|
+ Taro.previewImage({
|
|
|
+ current: url,
|
|
|
+ urls: [url]
|
|
|
+ })
|
|
|
+ break
|
|
|
+
|
|
|
+ case 'video':
|
|
|
+ // 视频文件使用弹窗播放器直接播放
|
|
|
+ setCurrentVideoUrl(url)
|
|
|
+ setShowVideoPlayer(true)
|
|
|
+ break
|
|
|
+
|
|
|
+ case 'other':
|
|
|
+ // 其他文件使用 Taro.openDocument
|
|
|
+ Taro.downloadFile({
|
|
|
+ url: url,
|
|
|
+ success: (res) => {
|
|
|
+ if (res.statusCode === 200) {
|
|
|
+ // 从 URL 或文件名中提取文件类型
|
|
|
+ const urlLower = url.toLowerCase()
|
|
|
+ let fileType = ''
|
|
|
+ const docTypes = ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.txt']
|
|
|
+ for (const type of docTypes) {
|
|
|
+ if (urlLower.includes(type)) {
|
|
|
+ fileType = type.replace('.', '')
|
|
|
+ break
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ Taro.openDocument({
|
|
|
+ filePath: res.tempFilePath,
|
|
|
+ fileType: (fileType || undefined) as Parameters<typeof Taro.openDocument>[0]['fileType'],
|
|
|
+ showMenu: true,
|
|
|
+ fail: (_err) => {
|
|
|
+ Taro.showToast({
|
|
|
+ title: '文件打开失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: (_err) => {
|
|
|
+ Taro.showToast({
|
|
|
+ title: '文件下载失败',
|
|
|
+ icon: 'none'
|
|
|
})
|
|
|
}
|
|
|
- },
|
|
|
- fail: (_err) => {
|
|
|
- Taro.showToast({
|
|
|
- title: '文件下载失败',
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
+ })
|
|
|
+ break
|
|
|
}
|
|
|
} catch (_error) {
|
|
|
Taro.showToast({
|
|
|
@@ -729,6 +789,44 @@ const TalentDetail: React.FC<TalentDetailProps> = () => {
|
|
|
)}
|
|
|
</ScrollView>
|
|
|
|
|
|
+ {/* 视频播放弹窗 */}
|
|
|
+ {showVideoPlayer && (
|
|
|
+ <View className="fixed inset-0 z-50 bg-black bg-opacity-75 flex items-center justify-center">
|
|
|
+ <View className="relative w-full max-w-lg mx-4">
|
|
|
+ {/* 关闭按钮 */}
|
|
|
+ <View
|
|
|
+ className="absolute -top-10 right-0 z-10 w-8 h-8 bg-white rounded-full flex items-center justify-center"
|
|
|
+ onClick={() => {
|
|
|
+ setShowVideoPlayer(false)
|
|
|
+ setCurrentVideoUrl('')
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Text className="i-heroicons-x-mark-20-solid text-gray-700 text-lg" />
|
|
|
+ </View>
|
|
|
+ {/* 视频播放器 */}
|
|
|
+ <Video
|
|
|
+ src={currentVideoUrl}
|
|
|
+ controls
|
|
|
+ autoplay
|
|
|
+ loop={false}
|
|
|
+ muted={false}
|
|
|
+ initialTime={0}
|
|
|
+ id="video-player"
|
|
|
+ className="w-full rounded-lg"
|
|
|
+ style={{ width: '100%', height: 'auto' }}
|
|
|
+ onEnded={() => {
|
|
|
+ // 视频播放结束后的处理(可选)
|
|
|
+ }}
|
|
|
+ onError={() => {
|
|
|
+ Taro.showToast({
|
|
|
+ title: '视频播放失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ )}
|
|
|
</PageContainer>
|
|
|
)
|
|
|
}
|