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