215 lines
8.6 KiB
TypeScript
215 lines
8.6 KiB
TypeScript
import { Button, Checkbox, CheckboxGroup, Input, Radio, RadioGroup, Text, Textarea, View } from '@tarojs/components'
|
||
import Taro from '@tarojs/taro'
|
||
import { useState } from 'react'
|
||
import './index.scss'
|
||
|
||
type ServiceType = 'new' | 'update'
|
||
|
||
type ApplicationForm = {
|
||
serviceType: ServiceType
|
||
storeName: string
|
||
storeAddress: string
|
||
contactName: string
|
||
contactPhone: string
|
||
description: string
|
||
}
|
||
|
||
type FormErrors = Partial<Record<keyof ApplicationForm | 'agreement', string>>
|
||
|
||
const INITIAL_FORM: ApplicationForm = {
|
||
serviceType: 'new',
|
||
storeName: '',
|
||
storeAddress: '',
|
||
contactName: '',
|
||
contactPhone: '',
|
||
description: '',
|
||
}
|
||
|
||
const PHONE_PATTERN = /^1[3-9]\d{9}$/
|
||
|
||
const validateForm = (form: ApplicationForm, agreed: boolean) => {
|
||
const errors: FormErrors = {}
|
||
|
||
if (!form.storeName.trim()) errors.storeName = '请输入门店名称'
|
||
if (!form.storeAddress.trim()) errors.storeAddress = '请输入门店地址'
|
||
if (!form.contactName.trim()) errors.contactName = '请输入联系人姓名'
|
||
|
||
if (!form.contactPhone.trim()) {
|
||
errors.contactPhone = '请输入联系电话'
|
||
} else if (!PHONE_PATTERN.test(form.contactPhone.trim())) {
|
||
errors.contactPhone = '请输入正确的手机号码'
|
||
}
|
||
|
||
if (!form.description.trim()) errors.description = '请描述需要办理的内容'
|
||
if (!agreed) errors.agreement = '请阅读并同意隐私政策和服务说明'
|
||
|
||
return errors
|
||
}
|
||
|
||
export default function Landing () {
|
||
const [form, setForm] = useState<ApplicationForm>(INITIAL_FORM)
|
||
const [agreed, setAgreed] = useState(false)
|
||
const [errors, setErrors] = useState<FormErrors>({})
|
||
|
||
const updateField = <K extends keyof ApplicationForm>(field: K, value: ApplicationForm[K]) => {
|
||
setForm((current) => ({ ...current, [field]: value }))
|
||
setErrors((current) => ({ ...current, [field]: undefined }))
|
||
}
|
||
|
||
const showPolicy = (type: 'privacy' | 'service') => {
|
||
const isPrivacy = type === 'privacy'
|
||
|
||
Taro.showModal({
|
||
title: isPrivacy ? '隐私政策' : '服务说明',
|
||
content: isPrivacy
|
||
? '您填写的信息仅用于本次门店标注服务的联系与确认,我们将妥善保护您的个人信息。'
|
||
: '提交申请后,工作人员将在服务时间内联系您核对资料。具体办理结果以实际审核情况为准。',
|
||
showCancel: false,
|
||
confirmText: '我知道了',
|
||
})
|
||
}
|
||
|
||
const handleSubmit = () => {
|
||
const validationErrors = validateForm(form, agreed)
|
||
const firstError = Object.values(validationErrors)[0]
|
||
|
||
setErrors(validationErrors)
|
||
|
||
if (firstError) {
|
||
Taro.showToast({ title: firstError, icon: 'none' })
|
||
return
|
||
}
|
||
|
||
Taro.showModal({
|
||
title: '提交成功',
|
||
content: '您的申请已提交,工作人员将在服务时间内联系您确认。',
|
||
showCancel: false,
|
||
confirmText: '我知道了',
|
||
})
|
||
}
|
||
|
||
return (
|
||
<View className='landing-page'>
|
||
<View className='landing-page__intro'>
|
||
<Text className='landing-page__title'>门店企业标注,在线提交</Text>
|
||
<Text className='landing-page__description'>
|
||
提供门店新增标注、信息修改等企业服务,提交资料后由工作人员联系确认。
|
||
</Text>
|
||
<Text className='landing-page__notice'>第三方企业服务,非地图平台官方服务</Text>
|
||
</View>
|
||
|
||
<View className='landing-page__form'>
|
||
<View className='landing-page__field'>
|
||
<Text className='landing-page__label'>办理类型</Text>
|
||
<RadioGroup
|
||
className='landing-page__service-types'
|
||
onChange={(event) => updateField('serviceType', event.detail.value as ServiceType)}
|
||
>
|
||
<View className={`landing-page__service-type ${form.serviceType === 'new' ? 'landing-page__service-type--selected' : ''}`}>
|
||
<Radio className='landing-page__radio' value='new' checked={form.serviceType === 'new'} color='#07c160'>新增标注</Radio>
|
||
</View>
|
||
<View className={`landing-page__service-type ${form.serviceType === 'update' ? 'landing-page__service-type--selected' : ''}`}>
|
||
<Radio className='landing-page__radio' value='update' checked={form.serviceType === 'update'} color='#07c160'>信息修改</Radio>
|
||
</View>
|
||
</RadioGroup>
|
||
</View>
|
||
|
||
<View className='landing-page__field'>
|
||
<Text className='landing-page__label'>门店名称</Text>
|
||
<Input
|
||
className={`landing-page__input ${errors.storeName ? 'landing-page__input--error' : ''}`}
|
||
value={form.storeName}
|
||
maxlength={50}
|
||
placeholder='请输入营业执照上的门店名称'
|
||
placeholderClass='landing-page__placeholder'
|
||
onInput={(event) => updateField('storeName', event.detail.value)}
|
||
/>
|
||
{errors.storeName && <Text className='landing-page__error'>{errors.storeName}</Text>}
|
||
</View>
|
||
|
||
<View className='landing-page__field'>
|
||
<Text className='landing-page__label'>门店地址</Text>
|
||
<Input
|
||
className={`landing-page__input ${errors.storeAddress ? 'landing-page__input--error' : ''}`}
|
||
value={form.storeAddress}
|
||
maxlength={100}
|
||
placeholder='请输入完整经营地址'
|
||
placeholderClass='landing-page__placeholder'
|
||
onInput={(event) => updateField('storeAddress', event.detail.value)}
|
||
/>
|
||
{errors.storeAddress && <Text className='landing-page__error'>{errors.storeAddress}</Text>}
|
||
</View>
|
||
|
||
<View className='landing-page__field'>
|
||
<Text className='landing-page__label'>联系人</Text>
|
||
<Input
|
||
className={`landing-page__input ${errors.contactName ? 'landing-page__input--error' : ''}`}
|
||
value={form.contactName}
|
||
maxlength={30}
|
||
placeholder='请输入联系人姓名'
|
||
placeholderClass='landing-page__placeholder'
|
||
onInput={(event) => updateField('contactName', event.detail.value)}
|
||
/>
|
||
{errors.contactName && <Text className='landing-page__error'>{errors.contactName}</Text>}
|
||
</View>
|
||
|
||
<View className='landing-page__field'>
|
||
<Text className='landing-page__label'>联系电话</Text>
|
||
<Input
|
||
className={`landing-page__input ${errors.contactPhone ? 'landing-page__input--error' : ''}`}
|
||
value={form.contactPhone}
|
||
type='number'
|
||
maxlength={11}
|
||
placeholder='请输入手机号码'
|
||
placeholderClass='landing-page__placeholder'
|
||
onInput={(event) => updateField('contactPhone', event.detail.value)}
|
||
/>
|
||
{errors.contactPhone && <Text className='landing-page__error'>{errors.contactPhone}</Text>}
|
||
</View>
|
||
|
||
<View className='landing-page__field'>
|
||
<Text className='landing-page__label'>补充说明</Text>
|
||
<Textarea
|
||
className={`landing-page__textarea ${errors.description ? 'landing-page__input--error' : ''}`}
|
||
value={form.description}
|
||
maxlength={300}
|
||
placeholder='请描述需要办理的内容'
|
||
placeholderClass='landing-page__placeholder'
|
||
onInput={(event) => updateField('description', event.detail.value)}
|
||
/>
|
||
{errors.description && <Text className='landing-page__error'>{errors.description}</Text>}
|
||
</View>
|
||
</View>
|
||
|
||
<CheckboxGroup
|
||
className='landing-page__agreement'
|
||
onChange={(event) => {
|
||
setAgreed(event.detail.value.includes('agreed'))
|
||
setErrors((current) => ({ ...current, agreement: undefined }))
|
||
}}
|
||
>
|
||
<Checkbox className='landing-page__checkbox' value='agreed' checked={agreed} color='#07c160' />
|
||
<Text className='landing-page__agreement-text'>我已阅读并同意</Text>
|
||
<Text className='landing-page__link' onClick={() => showPolicy('privacy')}>《隐私政策》</Text>
|
||
<Text className='landing-page__agreement-text'>和</Text>
|
||
<Text className='landing-page__link' onClick={() => showPolicy('service')}>《服务说明》</Text>
|
||
</CheckboxGroup>
|
||
{errors.agreement && <Text className='landing-page__agreement-error'>{errors.agreement}</Text>}
|
||
|
||
<Button
|
||
className='landing-page__submit'
|
||
hoverClass='landing-page__submit--pressed'
|
||
onClick={handleSubmit}
|
||
>
|
||
提交申请
|
||
</Button>
|
||
|
||
<View className='landing-page__footer'>
|
||
<Text>服务时间:工作日 9:00-18:00</Text>
|
||
<Text>客服电话:400-800-1234</Text>
|
||
<Text>第三方企业服务,请根据实际需求自愿提交</Text>
|
||
</View>
|
||
</View>
|
||
)
|
||
}
|