Files
mini-programs/src/pages/publishBall/publishForm.tsx
2025-08-23 15:14:37 +08:00

173 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from 'react'
import { View, Text } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { ImageUpload, Range, TimeSelector, TextareaTag, SelectStadium, NumberInterval, TitleInput, FormBasicInfo, FormSwitch } from '../../components'
import { type Stadium, type CoverImage } from '../../components/index.types'
import { FormFieldConfig, FieldType } from '../../config/formSchema/publishBallFormSchema'
import { PublishBallFormData } from '../../../types/publishBall';
import styles from './index.module.scss'
// 组件映射器
const componentMap = {
[FieldType.TEXT]: TitleInput,
[FieldType.TIMEINTERVAL]: TimeSelector,
[FieldType.RANGE]: Range,
[FieldType.TEXTAREATAG]: TextareaTag,
[FieldType.NUMBERINTERVAL]: NumberInterval,
[FieldType.UPLOADIMAGE]: ImageUpload,
[FieldType.ACTIVITYINFO]: FormBasicInfo,
[FieldType.CHECKBOX]: FormSwitch,
}
const PublishForm: React.FC<{
formData: PublishBallFormData,
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 handleCoverImagesChange = (images: CoverImage[]) => {
setCoverImages(images)
}
// 更新表单数据
const updateFormData = (key: keyof PublishBallFormData, value: any) => {
onChange(key, value)
}
// 处理场馆选择
const handleStadiumSelect = (stadium: Stadium | null) => {
setSelectedStadium(stadium)
if (stadium) {
updateFormData('location', stadium.name)
}
setShowStadiumSelector(false)
}
const renderSummary = (item: FormFieldConfig) => {
if (item.props?.showSummary) {
return <Text className={styles['section-summary']}>{item.props?.summary}</Text>
}
return null
}
// 提交表单
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'
})
}
return (
<View className={styles['publish-form']}>
<View className={styles['publish-ball__content']}>
{
optionsConfig.map((item) => {
const Component = componentMap[item.type]
const optionProps = {
...item.props,
...(item.key === 'additionalRequirements' ? { options: item.options } : {}),
...(item.props?.className ? { className: styles[item.props.className] } : {})
}
console.log(item.props?.className)
console.log(optionProps, item.label, formData[item.key]);
if (item.type === FieldType.UPLOADIMAGE) {
/* 活动封面 */
return <ImageUpload
images={coverImages}
onChange={handleCoverImagesChange}
{...item.props}
/>
}
if (item.type === FieldType.ACTIVITYINFO) {
return <>
<View className={styles['activity-description']}>
<Text className={styles['description-text']}>
2
</Text>
</View>
{/* 费用地点玩法区域 - 合并白色块 */}
<View className={styles['bg-section']}>
<FormBasicInfo
fee={formData.fee}
location={formData.location}
gameplay={formData.gameplay}
selectedStadium={selectedStadium}
children={item.children || []}
onFeeChange={(value) => updateFormData('fee', value)}
onLocationChange={(value) => updateFormData('location', value)}
onGameplayChange={(value) => updateFormData('gameplay', value)}
onStadiumSelect={() => setShowStadiumSelector(true)}
/>
</View>
</>
}
return (
<View className={styles['section-wrapper']}>
{
item.label && <View className={styles['section-title-wrapper']} >
<Text className={styles['section-title']}>{item.label}</Text>
{
item.props?.showSummary && <Text className={styles['section-summary']}>{renderSummary(item)}</Text>
}
</View>
}
<View className={styles['bg-section']}>
<Component
label={item.label}
value={formData[item.key]}
onChange={(value) => updateFormData(item.key as keyof PublishBallFormData, value)}
{...optionProps}
placeholder={item.placeholder}
/>
</View>
</View>
)
})
}
</View>
{/* 场馆选择弹窗 */}
<SelectStadium
visible={showStadiumSelector}
onClose={() => setShowStadiumSelector(false)}
onConfirm={handleStadiumSelect}
/>
</View>
)
}
export default PublishForm