import React, { useState, useCallback, forwardRef, useImperativeHandle, useEffect } from 'react'
import Taro from '@tarojs/taro'
import { View, Text, Image, ScrollView } from '@tarojs/components'
import images from '@/config/images'
import TextareaTag from '@/components/TextareaTag'
// import CoverImageUpload, { type CoverImage } from '@/components/ImageUpload'
import UploadCover, { type CoverImageValue } from '@/components/UploadCover'
import { useKeyboardHeight } from '@/store/keyboardStore'
import { useDictionaryActions } from '@/store/dictionaryStore'
import { normalize_address } from '@/utils/locationUtils'
import './StadiumDetail.scss'
export interface Stadium {
id?: string
venue_id?: string
name: string
address?: string
longitude?: number
latitude?: number
distance_km?: number | null
court_type?: string
court_surface?: string
description?: string
description_tag?: string[]
venue_image_list?: CoverImageValue[]
}
interface StadiumDetailProps {
stadium: Stadium
onAnyInput?: (value: boolean) => void
}
// 定义暴露给父组件的方法接口
export interface StadiumDetailRef {
getFormData: () => any
setFormData: (data: any) => void
}
// 公共的标题组件
const SectionTitle: React.FC<{ title: string,prop: string }> = ({ title, prop }) => {
if (prop === 'venue_image_list') {
return (
{title}
添加截图,平台会优先推荐
)
}
return (
{title}
)
}
// 公共的容器组件
const SectionContainer: React.FC<{ title: string; children: React.ReactNode, prop: string, type?: string }> = ({ title, children, prop, type }) => (
{children}
)
const StadiumDetail = forwardRef(({
stadium,
onAnyInput
}, ref) => {
const [openPicker, setOpenPicker] = useState(false); //为了解决上传图片时按钮样式问题
const [scrollTop, setScrollTop] = useState(0);
const { getDictionaryValue } = useDictionaryActions()
const court_type = getDictionaryValue('court_type') || []
const court_surface = getDictionaryValue('court_surface') || []
const supplementary_information = getDictionaryValue('supplementary_information') || []
// 使用全局键盘状态
const { keyboardHeight, isKeyboardVisible, addListener, initializeKeyboardListener } = useKeyboardHeight()
const stadiumInfo = [
{
label: '场地类型',
options: court_type,
prop: 'court_type',
type: 'tags'
},
{
label: '地面材质',
options: court_surface,
prop: 'court_surface',
type: 'tags'
},
{
label: '场地信息补充',
options: supplementary_information,
prop: 'description',
type: 'textareaTag'
},
{
label: '场地预定截图',
options: ['有其他场地信息可备注'],
prop: 'venue_image_list',
type: 'image'
}
]
const [formData, setFormData] = useState({
name: stadium.name,
address: stadium.address,
latitude: stadium.latitude,
longitude: stadium.longitude,
istance: stadium.distance_km,
court_type: court_type[0] || '',
court_surface: court_surface[0] || '',
additionalInfo: '',
venue_image_list: [] as CoverImageValue[],
description:{
description: '',
description_tag: []
},
venue_id: stadium.id
})
// 暴露方法给父组件
useImperativeHandle(ref, () => ({
getFormData: () => formData,
setFormData: (data: any) => setFormData(data)
}), [formData, stadium])
const calculateDistance = (distance_km: number | null) => {
if (!distance_km) return ''
if (distance_km && distance_km > 1) {
return distance_km.toFixed(1) + 'km'
}
return (distance_km * 1000).toFixed(0) + 'm'
}
const handleMapLocation = () => {
Taro.chooseLocation({
success: (res) => {
console.log(res,'resres');
setFormData({
...formData,
name: res.name,
address: normalize_address(res.address || ''),
latitude: res.latitude,
longitude: res.longitude,
istance: null
})
},
fail: (err: { errMsg: string }) => {
console.warn('选择位置失败:', err)
const { errMsg } = err || {};
if (!errMsg.includes('fail cancel')) {
Taro.showToast({
title: errMsg,
icon: "none",
});
}
}
})
}
const updateFormData = useCallback((prop: string, value: any) => {
setFormData(prev => ({ ...prev, [prop]: value }))
}, [])
const getSelectedByLabel = useCallback((label: string) => {
if (label === '场地类型') return formData.court_type
if (label === '地面材质') return formData.court_surface
return ''
}, [formData.court_type, formData.court_surface])
// 使用全局键盘状态监听
useEffect(() => {
// 初始化全局键盘监听器
initializeKeyboardListener()
// 添加本地监听器
const removeListener = addListener((height, visible) => {
console.log('AiImportPopup 收到键盘变化:', height, visible)
})
return () => {
removeListener()
}
}, [initializeKeyboardListener, addListener])
const changeTextarea = (value: boolean) => {
if (value) {
// 先滚动到底部
setScrollTop(140);
// 使用 setTimeout 确保滚动后再更新 openPicker
}
}
const changePicker = (value:boolean) => {
setOpenPicker(value);
}
console.log(stadium,'stadiumstadium');
// 计算滚动区域的最大高度
const scrollMaxHeight = isKeyboardVisible
? `calc(100vh - ${keyboardHeight+40}px)`
: '60vh'
return (
{/* 已选球场 */}
handleMapLocation()}
>
{formData.name}
{calculateDistance(formData.istance || null) + ' · '}
{formData.address}
{stadiumInfo.map((item) => {
if (item.type === 'tags') {
const selected = getSelectedByLabel(item.label)
return (
{item.options.map((opt) => (
updateFormData(item.prop, opt)}
>
{opt}
))}
)
}
if (item.type === 'textareaTag') {
return (
{
updateFormData(item.prop, value)
}}
// onBlur={() => {
// }}
onFocus={() => {
changeTextarea(true)
}}
placeholder='有其他场地信息可备注'
options={(item.options || []).map((o) => ({ label: o, value: o }))}
/>
)
}
if (item.type === 'image') {
return (
{
if (value instanceof Function) {
const newValue = value(formData[item.prop])
updateFormData(item.prop, newValue)
} else {
updateFormData(item.prop, value)
}
}}
maxCount={9}
source={['album', 'history']}
align='left'
tag="screenshot"
/>
)
}
return null
})}
)
})
export default StadiumDetail