增加获取场馆、字典
This commit is contained in:
@@ -1,12 +1,28 @@
|
||||
import React, { useState } from 'react'
|
||||
import React, { useState, useCallback, useEffect } from 'react'
|
||||
import { View, Text, Input, Image, Picker } from '@tarojs/components'
|
||||
import PopupGameplay from '../PopupGameplay'
|
||||
import img from '@/config/images';
|
||||
import './FormBasicInfo.scss'
|
||||
import { FormFieldConfig } from '@/config/formSchema/publishBallFormSchema';
|
||||
import SelectStadium from '../SelectStadium/SelectStadium'
|
||||
import { Stadium } from '../SelectStadium/StadiumDetail'
|
||||
import './FormBasicInfo.scss'
|
||||
|
||||
type PlayGame = {
|
||||
play_type: string // 玩法类型
|
||||
price: number | string // 价格
|
||||
venue_id?: number | null // 场地id
|
||||
location_name?: string // 场地名称
|
||||
location?: string // 场地地址
|
||||
latitude?: string // 纬度
|
||||
longitude?: string // 经度
|
||||
court_type?: string // 场地类型 1: 室内 2: 室外
|
||||
court_surface?: string // 场地表面 1: 硬地 2: 红土 3: 草地
|
||||
venue_description_tag?: Array<string>[] // 场地描述标签
|
||||
venue_description?: string // 场地描述
|
||||
venue_image_list?: Array<string>[] // 场地图片
|
||||
}
|
||||
interface FormBasicInfoProps {
|
||||
value: any
|
||||
value: PlayGame
|
||||
onChange: (value: any) => void
|
||||
children: FormFieldConfig[]
|
||||
}
|
||||
@@ -17,20 +33,49 @@ const FormBasicInfo: React.FC<FormBasicInfoProps> = ({
|
||||
children
|
||||
}) => {
|
||||
const [gameplayVisible, setGameplayVisible] = useState(false)
|
||||
|
||||
const [showStadiumSelector, setShowStadiumSelector] = useState(false)
|
||||
const [playGame, setPlayGame] = useState<{label: string, value: string }[]>([])
|
||||
const handleGameplaySelect = () => {
|
||||
setGameplayVisible(true)
|
||||
}
|
||||
|
||||
const handleGameplayConfirm = (selectedGameplay: string) => {
|
||||
onGameplayChange(selectedGameplay)
|
||||
onChange({...value, [children[2].prop]: selectedGameplay})
|
||||
setGameplayVisible(false)
|
||||
}
|
||||
|
||||
const handleGameplayClose = () => {
|
||||
setGameplayVisible(false)
|
||||
}
|
||||
// 处理场馆选择
|
||||
const handleStadiumSelect = (stadium: Stadium | null) => {
|
||||
console.log(stadium,'stadiumstadium');
|
||||
const { address, name, latitude, longitude, court_type, court_surface, description, description_tag, venue_image_list} = stadium || {};
|
||||
onChange({...value,
|
||||
venue_id: stadium?.id,
|
||||
location_name: name,
|
||||
location: address,
|
||||
latitude,
|
||||
longitude,
|
||||
court_type,
|
||||
court_surface,
|
||||
venue_description: description,
|
||||
venue_description_tag: description_tag,
|
||||
venue_image_list
|
||||
})
|
||||
setShowStadiumSelector(false)
|
||||
}
|
||||
|
||||
const handleChange = useCallback((key: string, value: any) => {
|
||||
onChange({...value, [key]: value})
|
||||
}, [onChange])
|
||||
|
||||
useEffect(() => {
|
||||
if (children.length > 2) {
|
||||
const options = children[2]?.options || [];
|
||||
setPlayGame(options)
|
||||
}
|
||||
}, [children])
|
||||
const renderChildren = () => {
|
||||
return children.map((child: any, index: number) => {
|
||||
return <View className='form-item'>
|
||||
@@ -46,8 +91,8 @@ const FormBasicInfo: React.FC<FormBasicInfoProps> = ({
|
||||
placeholder='请输入'
|
||||
placeholderClass='title-placeholder'
|
||||
type='digit'
|
||||
value={value[child.key]}
|
||||
onInput={(e) => onChange(child.key, e.detail.value)}
|
||||
value={value[child.prop]}
|
||||
onInput={(e) => handleChange(child.prop, e.detail.value)}
|
||||
/>
|
||||
<Text className='unit'>元/每人</Text>
|
||||
</View>
|
||||
@@ -56,9 +101,9 @@ const FormBasicInfo: React.FC<FormBasicInfoProps> = ({
|
||||
{
|
||||
index === 1 && (<View className='form-wrapper'>
|
||||
<Text className='form-item-label'>{child.label}</Text>
|
||||
<View className='form-right-wrapper' onClick={() => {}}>
|
||||
<Text className={`right-text ${value[child.key] ? 'selected' : ''}`}>
|
||||
{value[child.key] ? value[child.key] : '请选择'}
|
||||
<View className='form-right-wrapper' onClick={() => setShowStadiumSelector(true)}>
|
||||
<Text className={`right-text ${value[child.prop] ? 'selected' : ''}`}>
|
||||
{value[child.prop] ? value[child.prop] : '请选择'}
|
||||
</Text>
|
||||
<Image src={img.ICON_ARROW_RIGHT} className='arrow'/>
|
||||
</View>
|
||||
@@ -68,8 +113,8 @@ const FormBasicInfo: React.FC<FormBasicInfoProps> = ({
|
||||
index === 2 && ( <View className='form-wrapper'>
|
||||
<Text className='form-item-label'>{child.label}</Text>
|
||||
<View className='form-right-wrapper' onClick={handleGameplaySelect}>
|
||||
<Text className={`right-text ${value[child.key] ? 'selected' : ''}`}>
|
||||
{value[child.key] ? value[child.key] : '请选择'}
|
||||
<Text className={`right-text ${value[child.prop] ? 'selected' : ''}`}>
|
||||
{value[child.prop] ? value[child.prop] : '请选择'}
|
||||
</Text>
|
||||
<Image src={img.ICON_ARROW_RIGHT} className='arrow'/>
|
||||
</View>
|
||||
@@ -81,15 +126,21 @@ const FormBasicInfo: React.FC<FormBasicInfoProps> = ({
|
||||
return (
|
||||
<View className='form-basic-info'>
|
||||
{/* 费用 */}
|
||||
{/* {renderChildren()} */}
|
||||
|
||||
{renderChildren()}
|
||||
{/* 玩法选择弹窗 */}
|
||||
{/* <PopupGameplay
|
||||
<PopupGameplay
|
||||
visible={gameplayVisible}
|
||||
onClose={handleGameplayClose}
|
||||
onConfirm={handleGameplayConfirm}
|
||||
selectedGameplay={value[children[2].key]}
|
||||
/> */}
|
||||
value={value[children[2].prop]}
|
||||
options={playGame}
|
||||
/>
|
||||
{/* 场馆选择弹窗 */}
|
||||
<SelectStadium
|
||||
visible={showStadiumSelector}
|
||||
onClose={() => setShowStadiumSelector(false)}
|
||||
onConfirm={handleStadiumSelect}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,20 +6,20 @@ import styles from './PopupGameplay.module.scss'
|
||||
interface PopupGameplayProps {
|
||||
visible: boolean
|
||||
onClose: () => void
|
||||
onConfirm: (selectedGameplay: string) => void
|
||||
selectedGameplay?: string
|
||||
onConfirm: (value: string) => void
|
||||
value?: string
|
||||
options?: { label: string, value: string }[]
|
||||
}
|
||||
|
||||
export default function PopupGameplay({ visible, onClose, onConfirm, selectedGameplay = '不限' }: PopupGameplayProps) {
|
||||
const [selectedOption, setSelectedOption] = useState(selectedGameplay)
|
||||
export default function PopupGameplay({ visible, onClose, onConfirm, value = '不限', options = [] }: PopupGameplayProps) {
|
||||
const [selectedOption, setSelectedOption] = useState(value)
|
||||
|
||||
const options = ['不限', '单打', '双打', '拉球']
|
||||
|
||||
useEffect(() => {
|
||||
if (visible && selectedGameplay) {
|
||||
setSelectedOption(selectedGameplay)
|
||||
if (visible && value) {
|
||||
setSelectedOption(value)
|
||||
}
|
||||
}, [visible, selectedGameplay])
|
||||
}, [visible, value])
|
||||
|
||||
const handleOptionSelect = (option: string) => {
|
||||
setSelectedOption(option)
|
||||
@@ -45,11 +45,11 @@ export default function PopupGameplay({ visible, onClose, onConfirm, selectedGam
|
||||
<View className={styles.optionsList}>
|
||||
{options.map((option) => (
|
||||
<View
|
||||
key={option}
|
||||
className={`${styles.optionItem} ${selectedOption === option ? styles.selected : ''}`}
|
||||
onClick={() => handleOptionSelect(option)}
|
||||
key={option.value}
|
||||
className={`${styles.optionItem} ${selectedOption === option.value ? styles.selected : ''}`}
|
||||
onClick={() => handleOptionSelect(option.value)}
|
||||
>
|
||||
<Text className={styles.optionText}>{option}</Text>
|
||||
<Text className={styles.optionText}>{option.label}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
@@ -134,7 +134,24 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stadium-item-loading{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
.loading-icon{
|
||||
color: #666;
|
||||
font-size: 30px;
|
||||
.nut-loading-icon{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.nut-loading-text{
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 场馆列表
|
||||
.stadium-list {
|
||||
flex: 1;
|
||||
@@ -172,6 +189,11 @@
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
display: flex;
|
||||
|
||||
.highlight-text {
|
||||
color: #007AFF;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
.stadium-address{
|
||||
display: flex;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import React, { useState } from 'react'
|
||||
import React, { useState, useRef, useEffect } from 'react'
|
||||
import { View, Text, Input, ScrollView, Image } from '@tarojs/components'
|
||||
import Taro from '@tarojs/taro'
|
||||
import StadiumDetail from './StadiumDetail'
|
||||
import { Loading } from '@nutui/nutui-react-taro'
|
||||
import StadiumDetail, { StadiumDetailRef } from './StadiumDetail'
|
||||
import { CommonPopup } from '../../../../components'
|
||||
import './SelectStadium.scss'
|
||||
import { getLocation } from '@/utils/locationUtils'
|
||||
import PublishService from '@/services/publishService'
|
||||
import images from '@/config/images'
|
||||
import './SelectStadium.scss'
|
||||
|
||||
export interface Stadium {
|
||||
id?: string
|
||||
@@ -21,17 +24,6 @@ interface SelectStadiumProps {
|
||||
onConfirm: (stadium: Stadium | null) => void
|
||||
}
|
||||
|
||||
const stadiumList: Stadium[] = [
|
||||
{ id: '1', name: '静安网球馆', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304},
|
||||
{ id: '2', name: '芦湾体育馆', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 },
|
||||
{ id: '3', name: '静安网球馆', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 },
|
||||
{ id: '4', name: '徐汇游泳中心', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 },
|
||||
{ id: '5', name: '汇龙新城小区', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 },
|
||||
{ id: '6', name: '翠湖御苑小区', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 },
|
||||
{ id: '7', name: '仁恒河滨花园网球场', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 },
|
||||
{ id: '8', name: 'Our Tennis 东江球场', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 },
|
||||
{ id: '9', name: '上海琦梦网球俱乐部', address: '浦东新区东园路18号', istance: '100米' , longitude: 121.4367, latitude: 31.2304 }
|
||||
]
|
||||
|
||||
const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
visible,
|
||||
@@ -41,6 +33,37 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
const [searchValue, setSearchValue] = useState('')
|
||||
const [selectedStadium, setSelectedStadium] = useState<Stadium | null>(null)
|
||||
const [showDetail, setShowDetail] = useState(false)
|
||||
const stadiumDetailRef = useRef<StadiumDetailRef>(null)
|
||||
const [stadiumList, setStadiumList] = useState<Stadium[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const initData = async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const location = await getLocation()
|
||||
if (location.latitude && location.longitude) {
|
||||
const res = await PublishService.getStadiumList({
|
||||
seachOption: {
|
||||
latitude: location.latitude,
|
||||
longitude: location.longitude
|
||||
}
|
||||
})
|
||||
if (res.code === 0 && res.data) {
|
||||
setStadiumList(res.data.rows || [])
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取场馆列表失败:', error)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
initData()
|
||||
}
|
||||
}, [visible])
|
||||
|
||||
if (!visible) return null
|
||||
|
||||
@@ -55,11 +78,6 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
setShowDetail(true)
|
||||
}
|
||||
|
||||
// 处理返回球馆列表
|
||||
const handleBackToList = () => {
|
||||
setShowDetail(false)
|
||||
setSelectedStadium(null)
|
||||
}
|
||||
|
||||
// 处理搜索框输入
|
||||
const handleSearchInput = (e: any) => {
|
||||
@@ -70,7 +88,6 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
const handleMapLocation = () => {
|
||||
Taro.chooseLocation({
|
||||
success: (res) => {
|
||||
console.log('选择位置成功:', res)
|
||||
setSelectedStadium({
|
||||
name: res.name,
|
||||
address: res.address,
|
||||
@@ -81,33 +98,26 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('选择位置失败:', err)
|
||||
Taro.showToast({
|
||||
title: '位置选择失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 处理确认
|
||||
const handleConfirm = (stadium: Stadium, venueType: string, groundMaterial: string, additionalInfo: string) => {
|
||||
// 这里可以处理球馆详情的信息
|
||||
console.log('球馆详情:', { stadium, venueType, groundMaterial, additionalInfo })
|
||||
onConfirm(stadium)
|
||||
setShowDetail(false)
|
||||
setSelectedStadium(null)
|
||||
setSearchValue('')
|
||||
}
|
||||
|
||||
// 处理球馆列表确认
|
||||
const handleListConfirm = () => {
|
||||
if (selectedStadium) {
|
||||
onConfirm(selectedStadium)
|
||||
const handleConfirm = () => {
|
||||
if (stadiumDetailRef.current) {
|
||||
const formData = stadiumDetailRef.current.getFormData()
|
||||
console.log('获取球馆表单数据:', formData)
|
||||
const { description, ...rest } = formData
|
||||
onConfirm({ ...rest, ...description })
|
||||
setSelectedStadium(null)
|
||||
setSearchValue('')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 处理取消
|
||||
const handleCancel = () => {
|
||||
onClose()
|
||||
@@ -117,25 +127,30 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
}
|
||||
|
||||
const handleItemLocation = (stadium: Stadium) => {
|
||||
console.log(stadium,'stadiumstadium');
|
||||
if(stadium.latitude && stadium.longitude){
|
||||
if (stadium.latitude && stadium.longitude) {
|
||||
Taro.openLocation({
|
||||
latitude: stadium.latitude,
|
||||
longitude: stadium.longitude,
|
||||
name: stadium.name,
|
||||
address: stadium.address,
|
||||
success: (res) => {
|
||||
console.log(res,'resres');
|
||||
console.log(res, 'resres')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const markSearchText = (text: string) => {
|
||||
return text.replace(searchValue, `<span style="color: #007AFF;">${searchValue}</span>`)
|
||||
if (!searchValue) return text
|
||||
return text.replace(
|
||||
new RegExp(searchValue, 'gi'),
|
||||
`<span class="highlight-text">${searchValue}</span>`
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 如果显示详情页面
|
||||
if (showDetail && selectedStadium) {
|
||||
return (
|
||||
@@ -146,14 +161,13 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
confirmText="确认"
|
||||
className="select-stadium-popup"
|
||||
onCancel={handleCancel}
|
||||
onConfirm={handleListConfirm}
|
||||
onConfirm={handleConfirm}
|
||||
position="bottom"
|
||||
round
|
||||
>
|
||||
<StadiumDetail
|
||||
ref={stadiumDetailRef}
|
||||
stadium={selectedStadium}
|
||||
onBack={handleBackToList}
|
||||
onConfirm={handleConfirm}
|
||||
/>
|
||||
</CommonPopup>
|
||||
)
|
||||
@@ -168,8 +182,6 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
cancelText="返回"
|
||||
confirmText="完成"
|
||||
className="select-stadium-popup"
|
||||
onCancel={handleCancel}
|
||||
onConfirm={handleListConfirm}
|
||||
position="bottom"
|
||||
round
|
||||
>
|
||||
@@ -215,47 +227,68 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 场馆列表 */}
|
||||
<ScrollView className='stadium-list' scrollY>
|
||||
{filteredStadiums.map((stadium) => (
|
||||
<View
|
||||
key={stadium.id}
|
||||
className={`stadium-item ${selectedStadium?.id === stadium.id ? 'selected' : ''}`}
|
||||
onClick={() => handleStadiumSelect(stadium)}
|
||||
>
|
||||
<View className='stadium-item-left'>
|
||||
<Image src={images.ICON_STADIUM} className='stadium-icon' />
|
||||
</View>
|
||||
<View className='stadium-item-right'>
|
||||
<View className='stadium-name' dangerouslySetInnerHTML={{ __html: markSearchText(stadium.name) }}></View>
|
||||
<View className='stadium-address' >
|
||||
<Text onClick={(e) => { e.stopPropagation(); handleItemLocation(stadium); }}>{stadium.istance} · </Text>
|
||||
<Text onClick={(e) => { e.stopPropagation(); handleItemLocation(stadium); }}>{stadium.address}</Text>
|
||||
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{
|
||||
loading ? (
|
||||
<View className='stadium-item-loading'>
|
||||
<Loading type="circular" className='loading-icon'>加载中</Loading>
|
||||
</View>
|
||||
))}
|
||||
{
|
||||
searchValue && (<View
|
||||
className={`stadium-item`}
|
||||
onClick={() => handleMapLocation()}
|
||||
>
|
||||
<View className='stadium-item-left'>
|
||||
<Image src={images.ICON_MAP_SEARCH} className='stadium-icon' />
|
||||
</View>
|
||||
<View className='stadium-item-right'>
|
||||
<View className='stadium-name'>没有找到球场?去地图定位</View>
|
||||
<View className='stadium-address'>
|
||||
<Text>腾讯地图</Text>
|
||||
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
||||
) : (
|
||||
<ScrollView className='stadium-list' scrollY>
|
||||
{filteredStadiums.map((stadium) => (
|
||||
<View
|
||||
key={stadium.id}
|
||||
className={`stadium-item ${selectedStadium?.id === stadium.id ? 'selected' : ''}`}
|
||||
onClick={() => handleStadiumSelect(stadium)}
|
||||
>
|
||||
<View className='stadium-item-left'>
|
||||
<Image src={images.ICON_STADIUM} className='stadium-icon' />
|
||||
</View>
|
||||
<View className='stadium-item-right'>
|
||||
<View className='stadium-name' dangerouslySetInnerHTML={{ __html: markSearchText(stadium.name) }}></View>
|
||||
<View className='stadium-address'>
|
||||
<Text
|
||||
className='stadium-distance'
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
handleItemLocation(stadium)
|
||||
}}
|
||||
>
|
||||
{stadium.istance} ·
|
||||
</Text>
|
||||
<Text
|
||||
className='stadium-address-text'
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
handleItemLocation(stadium)
|
||||
}}
|
||||
>
|
||||
{stadium.address}
|
||||
</Text>
|
||||
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
))}
|
||||
{searchValue && (
|
||||
<View className='stadium-item map-search-item' onClick={handleMapLocation}>
|
||||
<View className='stadium-item-left'>
|
||||
<Image src={images.ICON_MAP_SEARCH} className='stadium-icon' />
|
||||
</View>
|
||||
<View className='stadium-item-right'>
|
||||
<View className='stadium-name'>没有找到球场?去地图定位</View>
|
||||
<View className='stadium-address'>
|
||||
<Text className='map-search-text'>腾讯地图</Text>
|
||||
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>)
|
||||
}
|
||||
</ScrollView>
|
||||
)}
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
{/* 场馆列表 */}
|
||||
|
||||
</View>
|
||||
</CommonPopup>
|
||||
)
|
||||
|
||||
@@ -114,7 +114,6 @@
|
||||
border: 1px solid #e0e0e0;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React, { useState, useCallback } from 'react'
|
||||
import React, { useState, useCallback, forwardRef, useImperativeHandle } from 'react'
|
||||
import Taro from '@tarojs/taro'
|
||||
import { View, Text, Image } from '@tarojs/components'
|
||||
import images from '@/config/images'
|
||||
import './StadiumDetail.scss'
|
||||
import TextareaTag from '@/components/TextareaTag'
|
||||
import CoverImageUpload, { type CoverImage } from '@/components/ImageUpload'
|
||||
import { useDictionaryActions } from '@/store/dictionaryStore'
|
||||
import './StadiumDetail.scss'
|
||||
|
||||
export interface Stadium {
|
||||
id?: string
|
||||
@@ -13,45 +14,27 @@ export interface Stadium {
|
||||
longitude?: number
|
||||
latitude?: number
|
||||
istance?: string
|
||||
court_type?: string
|
||||
court_surface?: string
|
||||
description?: string
|
||||
description_tag?: string[]
|
||||
venue_image_list?: CoverImage[]
|
||||
}
|
||||
|
||||
interface StadiumDetailProps {
|
||||
stadium: Stadium
|
||||
onBack: () => void
|
||||
onConfirm: (stadium: Stadium, venueType: string, groundMaterial: string, additionalInfo: string) => void
|
||||
}
|
||||
|
||||
const stadiumInfo = [
|
||||
{
|
||||
label: '场地类型',
|
||||
options: ['室内', '室外', '室外雨棚'],
|
||||
prop: 'venueType',
|
||||
type: 'tags'
|
||||
},
|
||||
{
|
||||
label: '地面材质',
|
||||
options: ['硬地', '红土', '草地'],
|
||||
prop: 'groundMaterial',
|
||||
type: 'tags'
|
||||
},
|
||||
{
|
||||
label: '场地信息补充',
|
||||
options: ['1号场', '2号场', '3号场', '4号场', '有空调', '6号场','6号场'],
|
||||
prop: 'additionalInfo',
|
||||
type: 'textareaTag'
|
||||
},
|
||||
{
|
||||
label: '场地预定截图',
|
||||
options: ['有其他场地信息可备注'],
|
||||
prop: 'imagesList',
|
||||
type: 'image'
|
||||
}
|
||||
]
|
||||
// 定义暴露给父组件的方法接口
|
||||
export interface StadiumDetailRef {
|
||||
getFormData: () => any
|
||||
setFormData: (data: any) => void
|
||||
}
|
||||
|
||||
|
||||
// 公共的标题组件
|
||||
const SectionTitle: React.FC<{ title: string,prop: string }> = ({ title, prop }) => {
|
||||
console.log(prop,'propprop');
|
||||
if (prop === 'imagesList') {
|
||||
if (prop === 'venue_image_list') {
|
||||
return (
|
||||
<View className='section-title'>
|
||||
<Text>{title}</Text>
|
||||
@@ -78,21 +61,61 @@ const SectionContainer: React.FC<{ title: string; children: React.ReactNode, pro
|
||||
</View>
|
||||
)
|
||||
|
||||
const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||||
const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
|
||||
stadium,
|
||||
}) => {
|
||||
}, ref) => {
|
||||
const { getDictionaryValue } = useDictionaryActions()
|
||||
const court_type = getDictionaryValue('court_type') || []
|
||||
const court_surface = getDictionaryValue('court_surface') || []
|
||||
const supplementary_information = getDictionaryValue('supplementary_information') || []
|
||||
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({
|
||||
stadiumName: stadium.name,
|
||||
stadiumAddress: stadium.address,
|
||||
stadiumLongitude: stadium.longitude,
|
||||
stadiumLatitude: stadium.latitude,
|
||||
name: stadium.name,
|
||||
address: stadium.address,
|
||||
latitude: stadium.longitude,
|
||||
longitude: stadium.latitude,
|
||||
istance: stadium.istance,
|
||||
venueType: '室内',
|
||||
groundMaterial: '硬地',
|
||||
court_type: court_type[0] || '',
|
||||
court_surface: court_surface[0] || '',
|
||||
additionalInfo: '',
|
||||
imagesList: [] as CoverImage[]
|
||||
venue_image_list: [] as CoverImage[],
|
||||
description:{
|
||||
description: '',
|
||||
description_tag: []
|
||||
}
|
||||
})
|
||||
|
||||
// 暴露方法给父组件
|
||||
useImperativeHandle(ref, () => ({
|
||||
getFormData: () => formData,
|
||||
setFormData: (data: any) => setFormData(data)
|
||||
}), [formData, stadium])
|
||||
|
||||
|
||||
|
||||
const handleMapLocation = () => {
|
||||
@@ -101,10 +124,10 @@ const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||||
console.log(res,'resres');
|
||||
setFormData({
|
||||
...formData,
|
||||
stadiumName: res.name,
|
||||
stadiumAddress: res.address,
|
||||
stadiumLongitude: res.longitude,
|
||||
stadiumLatitude: res.latitude
|
||||
name: res.name,
|
||||
address: res.address,
|
||||
latitude: res.longitude,
|
||||
longitude: res.latitude
|
||||
})
|
||||
},
|
||||
fail: (err) => {
|
||||
@@ -122,10 +145,10 @@ const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||||
}, [])
|
||||
|
||||
const getSelectedByLabel = useCallback((label: string) => {
|
||||
if (label === '场地类型') return formData.venueType
|
||||
if (label === '地面材质') return formData.groundMaterial
|
||||
if (label === '场地类型') return formData.court_type
|
||||
if (label === '地面材质') return formData.court_surface
|
||||
return ''
|
||||
}, [formData.venueType, formData.groundMaterial])
|
||||
}, [formData.court_type, formData.court_surface])
|
||||
|
||||
|
||||
console.log(stadium,'stadiumstadium');
|
||||
@@ -140,10 +163,10 @@ const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||||
<Image src={images.ICON_STADIUM} className='stadium-icon' />
|
||||
</View>
|
||||
<View className='stadium-item-right'>
|
||||
<View className='stadium-name'>{formData.stadiumName}</View>
|
||||
<View className='stadium-name'>{formData.name}</View>
|
||||
<View className='stadium-address'>
|
||||
<Text>{formData.istance} · </Text>
|
||||
<Text>{formData.stadiumAddress}</Text>
|
||||
<Text>{formData.address}</Text>
|
||||
<Image src={images.ICON_ARRORW_SMALL} className='stadium-map-icon' />
|
||||
</View>
|
||||
</View>
|
||||
@@ -172,7 +195,7 @@ const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||||
<SectionContainer key={item.label} title={item.label} prop={item.prop}>
|
||||
<View className='textarea-tag-container'>
|
||||
<TextareaTag
|
||||
value={formData.additionalInfo}
|
||||
value={formData[item.prop]}
|
||||
onChange={(value) => updateFormData(item.prop, value)}
|
||||
placeholder='有其他场地信息可备注'
|
||||
options={(item.options || []).map((o) => ({ label: o, value: o }))}
|
||||
@@ -186,7 +209,7 @@ const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||||
return (
|
||||
<SectionContainer key={item.label} title={item.label} prop={item.prop}>
|
||||
<CoverImageUpload
|
||||
images={formData.imagesList}
|
||||
images={formData[item.prop]}
|
||||
onChange={(images) => updateFormData(item.prop, images)}
|
||||
/>
|
||||
</SectionContainer>
|
||||
@@ -197,6 +220,6 @@ const StadiumDetail: React.FC<StadiumDetailProps> = ({
|
||||
})}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default StadiumDetail
|
||||
@@ -0,0 +1,41 @@
|
||||
import React, { useState } from 'react'
|
||||
import { View, Text } from '@tarojs/components'
|
||||
import { Checkbox } from '@nutui/nutui-react-taro'
|
||||
import styles from './index.module.scss'
|
||||
interface FormSwitchProps {
|
||||
value: boolean
|
||||
onChange: (checked: boolean) => void
|
||||
subTitle: string
|
||||
wechatId?: string
|
||||
}
|
||||
|
||||
const FormSwitch: React.FC<FormSwitchProps> = ({ value, onChange, subTitle, wechatId }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<View className={styles['wechat-contact-section']}>
|
||||
<View className={styles['wechat-contact-item']}>
|
||||
<Checkbox
|
||||
className={styles['wechat-contact-checkbox']}
|
||||
checked={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<View className={styles['wechat-contact-content']}>
|
||||
<Text className={styles['wechat-contact-text']}>{subTitle}</Text>
|
||||
</View>
|
||||
</View>
|
||||
{
|
||||
wechatId && (
|
||||
<View className={styles['wechat-contact-id']}>
|
||||
<Text className={styles['wechat-contact-text']}>微信号: {wechatId.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3')}</Text>
|
||||
<View className={styles['wechat-contact-edit']}>修改</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormSwitch
|
||||
@@ -0,0 +1,91 @@
|
||||
.wechat-contact-section {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 10px 12px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
.wechat-contact-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 8px;
|
||||
.wechat-contact-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.wechat-contact-text {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-left: 4px;
|
||||
position: relative;
|
||||
.info-img{
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
.info-popover {
|
||||
position: absolute;
|
||||
bottom: 22px;
|
||||
left: -65px;
|
||||
width: 130px;
|
||||
padding:12px;
|
||||
background: rgba(57, 59, 68, 0.90);
|
||||
color: #fff;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
z-index: 1001;
|
||||
white-space: normal;
|
||||
word-break: normal;
|
||||
overflow-wrap: break-word;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
.info-popover::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
left: 68px; /* 对齐图标(宽12px),可按需微调 */
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid rgba(57, 59, 68, 0.90);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wechat-contact-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
.wechat-contact-id {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding-top: 4px;
|
||||
.wechat-contact-text {
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
}
|
||||
.wechat-contact-edit {
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
display: flex;
|
||||
padding: 2px 6px;
|
||||
align-items: center;
|
||||
font-weight: normal;
|
||||
border-radius: 100px;
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
src/pages/publishBall/components/WechatSwitch/index.ts
Normal file
1
src/pages/publishBall/components/WechatSwitch/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './WechatSwitch'
|
||||
@@ -34,9 +34,6 @@
|
||||
.activity-type-switch{
|
||||
padding: 4px 16px 0 16px;
|
||||
}
|
||||
.publish-form{
|
||||
|
||||
}
|
||||
|
||||
// 场次标题行
|
||||
.session-header {
|
||||
|
||||
@@ -12,7 +12,7 @@ import images from '@/config/images'
|
||||
|
||||
const defaultFormData: PublishBallFormData = {
|
||||
title: '',
|
||||
image_list: [],
|
||||
image_list: ['https://static-o.oss-cn-shenzhen.aliyuncs.com/images/tpbj/tpss10.jpg'],
|
||||
timeRange: {
|
||||
start_time: getNextHourTime(),
|
||||
end_time: getEndTime(getNextHourTime())
|
||||
@@ -31,21 +31,15 @@ const defaultFormData: PublishBallFormData = {
|
||||
venue_description: '',
|
||||
venue_image_list: [],
|
||||
},
|
||||
players: {
|
||||
current_players: 0,
|
||||
max_players: 0,
|
||||
},
|
||||
skill_level: {
|
||||
skill_level_max: 5.0,
|
||||
skill_level_min: 1.0,
|
||||
},
|
||||
players: [1, 4],
|
||||
skill_level: [1.0, 5.0],
|
||||
descriptionInfo: {
|
||||
description: '',
|
||||
description_tag: [],
|
||||
},
|
||||
is_substitute_supported: false,
|
||||
is_wechat_contact: false,
|
||||
wechat_contact: ''
|
||||
is_substitute_supported: true,
|
||||
is_wechat_contact: true,
|
||||
wechat_contact: '14223332214'
|
||||
}
|
||||
|
||||
const PublishBall: React.FC = () => {
|
||||
@@ -65,9 +59,11 @@ const PublishBall: React.FC = () => {
|
||||
|
||||
// 更新表单数据
|
||||
const updateFormData = (key: keyof PublishBallFormData, value: any, index: number) => {
|
||||
console.log(key, value, index, 'key, value, index');
|
||||
setFormData(prev => {
|
||||
const newData = [...prev]
|
||||
newData[index] = { ...newData[index], [key]: value }
|
||||
console.log(newData, 'newData');
|
||||
return newData
|
||||
})
|
||||
}
|
||||
@@ -132,30 +128,80 @@ const PublishBall: React.FC = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const validateFormData = (formData: PublishBallFormData) => {
|
||||
const { activityInfo, image_list, title } = formData;
|
||||
const { play_type, price, location_name } = activityInfo;
|
||||
if (!image_list.length) {
|
||||
Taro.showToast({
|
||||
title: `请上传活动封面`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (!title) {
|
||||
Taro.showToast({
|
||||
title: `请输入活动标题`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (!price) {
|
||||
Taro.showToast({
|
||||
title: `请输入费用`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (!play_type) {
|
||||
Taro.showToast({
|
||||
title: `请选择玩法类型`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
if (!location_name) {
|
||||
Taro.showToast({
|
||||
title: `请选择场地`,
|
||||
icon: 'none'
|
||||
})
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
// 基础验证
|
||||
|
||||
// TODO: 实现提交逻辑
|
||||
const res = await PublishService.createPersonal({
|
||||
"title": "周末网球约球",
|
||||
"venue_id": 1,
|
||||
"creator_id": 1,
|
||||
"game_date": "2024-06-15",
|
||||
"start_time": "14:00",
|
||||
"end_time": "16:00",
|
||||
"max_participants": 4,
|
||||
"current_participants": 2,
|
||||
"ntrp_level": "2.0-4.0",
|
||||
"play_style": "单打",
|
||||
"description": "周末约球,欢迎参加",
|
||||
})
|
||||
console.log(res);
|
||||
Taro.showToast({
|
||||
title: '发布成功',
|
||||
icon: 'success'
|
||||
})
|
||||
console.log(formData, 'formData');
|
||||
if (activityType === 'individual') {
|
||||
const isValid = validateFormData(formData[0])
|
||||
if (!isValid) {
|
||||
return
|
||||
}
|
||||
const { activityInfo, descriptionInfo, timeRange, players, skill_level, ...rest } = formData[0];
|
||||
const options = {
|
||||
...rest,
|
||||
...activityInfo,
|
||||
...descriptionInfo,
|
||||
...timeRange,
|
||||
max_players: players[1],
|
||||
current_players: players[0],
|
||||
skill_level_min: skill_level[0],
|
||||
skill_level_max: skill_level[1]
|
||||
}
|
||||
const res = await PublishService.createPersonal(options);
|
||||
if (res.code === 0 && res.data) {
|
||||
Taro.showToast({
|
||||
title: '发布成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} else {
|
||||
Taro.showToast({
|
||||
title: res.message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import React, { useState } from 'react'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { View, Text } from '@tarojs/components'
|
||||
|
||||
import Taro from '@tarojs/taro'
|
||||
import { ImageUpload, Range, TimeSelector, TextareaTag, NumberInterval, TitleTextarea, FormSwitch } from '../../components'
|
||||
import { SelectStadium } from './components/SelectStadium'
|
||||
import FormBasicInfo from './components/FormBasicInfo'
|
||||
import { type CoverImage } from '../../components/index.types'
|
||||
import { Stadium } from './components/SelectStadium'
|
||||
import { FormFieldConfig, FieldType } from '../../config/formSchema/publishBallFormSchema'
|
||||
import { PublishBallFormData } from '../../../types/publishBall';
|
||||
|
||||
import WechatSwitch from './components/WechatSwitch/WechatSwitch'
|
||||
import styles from './index.module.scss'
|
||||
import { useDictionaryActions } from '../../store/dictionaryStore'
|
||||
|
||||
// 组件映射器
|
||||
const componentMap = {
|
||||
@@ -22,6 +19,7 @@ const componentMap = {
|
||||
[FieldType.UPLOADIMAGE]: ImageUpload,
|
||||
[FieldType.ACTIVITYINFO]: FormBasicInfo,
|
||||
[FieldType.CHECKBOX]: FormSwitch,
|
||||
[FieldType.WECHATCONTACT]: WechatSwitch,
|
||||
}
|
||||
|
||||
const PublishForm: React.FC<{
|
||||
@@ -29,8 +27,9 @@ const PublishForm: React.FC<{
|
||||
onChange: (key: keyof PublishBallFormData, value: any, index?: number) => void,
|
||||
optionsConfig: FormFieldConfig[] }> = ({ formData, onChange, optionsConfig }) => {
|
||||
const [coverImages, setCoverImages] = useState<CoverImage[]>([])
|
||||
const [showStadiumSelector, setShowStadiumSelector] = useState(false)
|
||||
const [selectedStadium, setSelectedStadium] = useState<Stadium | null>(null)
|
||||
|
||||
// 字典数据相关
|
||||
const { getDictionaryValue } = useDictionaryActions()
|
||||
|
||||
// 处理封面图片变化
|
||||
const handleCoverImagesChange = (images: CoverImage[]) => {
|
||||
@@ -42,15 +41,47 @@ const PublishForm: React.FC<{
|
||||
onChange(key, value)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 处理场馆选择
|
||||
const handleStadiumSelect = (stadium: Stadium | null) => {
|
||||
setSelectedStadium(stadium)
|
||||
if (stadium) {
|
||||
updateFormData('location', stadium.name)
|
||||
// 获取字典选项
|
||||
const getDictionaryOptions = (key: string, defaultValue: any[] = []) => {
|
||||
const dictValue = getDictionaryValue(key, defaultValue)
|
||||
if (Array.isArray(dictValue)) {
|
||||
return dictValue.map(item => ({
|
||||
label: item.label || item.name || item.value || item,
|
||||
value: item.value || item.id || item
|
||||
}))
|
||||
}
|
||||
setShowStadiumSelector(false)
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
|
||||
// 动态生成表单配置,集成字典数据
|
||||
const getDynamicFormConfig = (): FormFieldConfig[] => {
|
||||
return optionsConfig.map(item => {
|
||||
// 如果是玩法选择,从字典获取选项
|
||||
if (item.prop === 'activityInfo' && item.children) {
|
||||
const playTypeOptions = getDictionaryOptions('game_play', item.children.find(child => child.prop === 'play_type')?.options)
|
||||
return {
|
||||
...item,
|
||||
children: item.children.map(child => {
|
||||
if (child.prop === 'play_type') {
|
||||
return { ...child, options: playTypeOptions }
|
||||
}
|
||||
return child
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是补充要求,从字典获取选项
|
||||
if (item.prop === 'descriptionInfo') {
|
||||
const descriptionOptions = getDictionaryOptions('publishing_requirements', [])
|
||||
return {
|
||||
...item,
|
||||
options: descriptionOptions
|
||||
}
|
||||
}
|
||||
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
const renderSummary = (item: FormFieldConfig) => {
|
||||
@@ -62,47 +93,23 @@ const PublishForm: React.FC<{
|
||||
|
||||
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
// 基础验证
|
||||
if (!formData.title.trim()) {
|
||||
Taro.showToast({
|
||||
title: '请输入活动标题',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (coverImages.length === 0) {
|
||||
Taro.showToast({
|
||||
title: '请至少上传一张活动封面',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 实现提交逻辑
|
||||
console.log('提交数据:', { coverImages, formData })
|
||||
|
||||
Taro.showToast({
|
||||
title: '发布成功',
|
||||
icon: 'success'
|
||||
})
|
||||
}
|
||||
// 获取动态表单配置
|
||||
const dynamicConfig = getDynamicFormConfig()
|
||||
|
||||
return (
|
||||
<View className={styles['publish-form']}>
|
||||
<View className={styles['publish-ball__content']}>
|
||||
{
|
||||
optionsConfig.map((item) => {
|
||||
dynamicConfig.map((item) => {
|
||||
const Component = componentMap[item.type]
|
||||
const optionProps = {
|
||||
...item.props,
|
||||
...(item.type === FieldType.TEXTAREATAG ? { options: item.options } : {}),
|
||||
...(item.props?.className ? { className: styles[item.props.className] } : {})
|
||||
...(item.props?.className ? { className: styles[item.props.className] } : {}),
|
||||
...(item.type === FieldType.WECHATCONTACT ? { wechatId: formData.wechat_contact } : {})
|
||||
}
|
||||
console.log(item.props?.className)
|
||||
console.log(optionProps, item.label, formData[item.key]);
|
||||
if (item.type === FieldType.UPLOADIMAGE) {
|
||||
/* 活动封面 */
|
||||
return <ImageUpload
|
||||
@@ -124,8 +131,8 @@ const PublishForm: React.FC<{
|
||||
<View className={styles['bg-section']}>
|
||||
<FormBasicInfo
|
||||
children={item.children || []}
|
||||
value={formData[item.key]}
|
||||
onChange={(value) => updateFormData(item.key as keyof PublishBallFormData, value)}
|
||||
value={formData[item.prop]}
|
||||
onChange={(value) => updateFormData(item.prop as keyof PublishBallFormData, value)}
|
||||
{...optionProps}
|
||||
/>
|
||||
</View>
|
||||
@@ -144,8 +151,8 @@ const PublishForm: React.FC<{
|
||||
<View className={styles['bg-section']}>
|
||||
<Component
|
||||
label={item.label}
|
||||
value={formData[item.key]}
|
||||
onChange={(value) => updateFormData(item.key as keyof PublishBallFormData, value)}
|
||||
value={formData[item.prop]}
|
||||
onChange={(value) => updateFormData(item.prop as keyof PublishBallFormData, value)}
|
||||
{...optionProps}
|
||||
placeholder={item.placeholder}
|
||||
/>
|
||||
@@ -156,13 +163,6 @@ const PublishForm: React.FC<{
|
||||
}
|
||||
</View>
|
||||
|
||||
{/* 场馆选择弹窗 */}
|
||||
<SelectStadium
|
||||
visible={showStadiumSelector}
|
||||
onClose={() => setShowStadiumSelector(false)}
|
||||
onConfirm={handleStadiumSelect}
|
||||
/>
|
||||
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user