智能导入

This commit is contained in:
筱野
2025-09-18 21:39:05 +08:00
parent ffdb0bda26
commit c096d265ab
11 changed files with 508 additions and 96 deletions

View File

@@ -1,8 +1,11 @@
import React, { useState, useEffect } from 'react'
import { View, Text, Textarea, Image } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { Popup, Toast } from '@nutui/nutui-react-taro'
import { ConfigProvider, Loading, Popup, Toast } from '@nutui/nutui-react-taro'
import styles from './index.module.scss'
import uploadFiles from '@/services/uploadFiles'
import publishService from '@/services/publishService'
import { usePublishBallActions } from '@/store/publishBallStore'
import images from '@/config/images'
export interface AiImportPopupProps {
@@ -20,14 +23,21 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
}) => {
const [text, setText] = useState('')
const [uploadFailCount, setUploadFailCount] = useState(0)
const [loading, setLoading] = useState(false)
const [uploadLoading, setUploadLoading] = useState(false)
const maxFailCount = 3
// 当弹窗显示时,尝试获取剪切板内容
useEffect(() => {
if (visible) {
getClipboardData()
}
}, [visible])
// 获取 actions在组件顶层调用 Hook
const { setPublishData } = usePublishBallActions()
const textIdentification = async (text: string) => {
setLoading(true)
const res = await publishService.extract_tennis_activity({text})
console.log(res)
const {data} = res
navigateToPublishBall(data)
setLoading(false)
}
const getClipboardData = async () => {
try {
@@ -36,9 +46,10 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
setText(res.data)
Toast.show('toast', {
content: '有场读取了你的剪切板信息',
duration: 90,
duration: 2,
wordBreak:'break-word'
})
textIdentification(res.data)
// Taro.showToast({
// title: '已读取你的剪切板信息',
// icon: 'success',
@@ -48,7 +59,7 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
Taro.showToast({
title: '剪切板为空,请手动输入',
icon: 'none',
duration: 2000
duration: 2
})
}
} catch (error) {
@@ -56,11 +67,20 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
Taro.showToast({
title: '读取剪切板失败,请手动输入',
icon: 'error',
duration: 2000
duration: 2
})
}
}
const navigateToPublishBall = (data: any) => {
if (Array.isArray(data) && data.length > 0) {
setPublishData(data)
Taro.navigateTo({
url: '/publish_pages/publishBall/pages/publishBall?type=ai'
})
}
}
const handleTextChange = (e: any) => {
setText(e.detail.value)
}
@@ -76,12 +96,17 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
if (res.tempFiles && res.tempFiles.length > 0) {
// 这里可以调用图片识别API
console.log('选择的图片:', res.tempFiles[0])
// TODO: 实现图片识别逻辑
Taro.showToast({
title: '图片识别功能开发中',
icon: 'none'
})
setUploadLoading(false)
setLoading(true)
const res_upload = await uploadFiles.upload_oss_img(res.tempFiles[0].tempFilePath)
const {ossPath} = res_upload;
if (ossPath) {
setUploadLoading(true)
const publishData = await publishService.extract_tennis_activity_from_image({image_url: ossPath})
const {data} = publishData
navigateToPublishBall(data)
setLoading(false)
}
}
} catch (error) {
console.error('选择图片失败:', error)
@@ -93,20 +118,6 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
}
}
const handlePasteAndRecognize = () => {
if (!text.trim()) {
Taro.showToast({
title: '请输入球局信息',
icon: 'none'
})
return
}
if (onPasteAndRecognize) {
onPasteAndRecognize(text)
}
onClose()
}
const handleManualPublish = () => {
if (onManualPublish) {
@@ -144,9 +155,10 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
className={styles.textArea}
value={text}
onInput={handleTextChange}
placeholder="请输入球局信息..."
placeholder="在此「粘贴识别」或输入文本,智能拆分球局时间、费用、地点和其他信息,并帮你智能生成球局标题"
maxlength={100}
showConfirmBar={false}
placeholderClass={styles.textArea_placeholder}
autoHeight
/>
<View className={styles.charCount}>
@@ -156,10 +168,12 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
{/* 图片识别按钮 */}
<View className={styles.imageRecognitionContainer}>
<View className={styles.imageRecognitionButton} onClick={handleImageRecognition}>
<Image src={images.ICON_UPLOAD} className={styles.cameraIcon} />
<View className={`${styles.imageRecognitionButton} ${uploadLoading ? styles.uploadLoadingContainer : ''}`} onClick={handleImageRecognition}>
{
uploadLoading ? (<Image src={images.ICON_UPLOAD_SUCCESS} className={styles.cameraIcon} />) : (<Image src={images.ICON_UPLOAD_IMG} className={styles.cameraIcon} />)
}
<Text className={styles.imageRecognitionText}></Text>
<Text className={styles.imageRecognitionDesc}>/</Text>
<Text className={styles.imageRecognitionDesc}>{uploadLoading ? '已上传 1 张图片' : '支持订场截图/小红书笔记截图等图片'}</Text>
</View>
</View>
@@ -170,9 +184,22 @@ const AiImportPopup: React.FC<AiImportPopupProps> = ({
<Text className={styles.manualButtonText}></Text>
</View>
)}
<View className={styles.pasteButton} onClick={handlePasteAndRecognize}>
<Image src={images.ICON_PLUS} className={styles.clipboardIcon} />
<Text className={styles.pasteButtonText}></Text>
<View className={styles.pasteButton} onClick={getClipboardData}>
{
loading ? (
<View className={styles.loadingContainer}>
<ConfigProvider theme={{ nutuiLoadingIconColor: '#fff', nutuiLoadingIconSize: '20px' }}>
<Loading type="circular" />
</ConfigProvider>
<Text className={styles.pasteButtonText}></Text>
</View>
) : (
<>
<Image src={images.ICON_COPY} className={styles.clipboardIcon} />
<Text className={styles.pasteButtonText}></Text>
</>
)
}
</View>
</View>
</View>