- 个人信息页新增门店名称和门店地址展示,支持异步加载与只读显示 - 用户信息卡片整体改为绿色渐变背景,添加光晕和白色边框样式 - 新增升级VIP会员入口,突出展示并添加推荐标签 - 新建VIP会员升级页面,包含门店信息表单和VIP权益预览 - 提交升级申请调用新增api,支持状态检测表单只读 - 门店中心页面重构,简化订单管理,新增功能卡片及VIP审核入口 - 页面加载校验店员身份,非店员拒绝访问并提示 - 购物相关页面和组件全面支持VIP会员价格优先显示dealerPrice - 新增ShopDealerApply模型门店相关字段,丰富会员申请数据记录
209 lines
8.7 KiB
TypeScript
209 lines
8.7 KiB
TypeScript
import React, { useState, useEffect } from 'react'
|
||
import { View, Text, Input } from '@tarojs/components'
|
||
import Taro from '@tarojs/taro'
|
||
import { useUser } from '@/hooks/useUser'
|
||
import { addShopDealerApply, listShopDealerApply } from '@/api/shop/shopDealerApply'
|
||
import type { ShopDealerApply } from '@/api/shop/shopDealerApply/model'
|
||
|
||
definePageConfig({
|
||
navigationBarTitleText: '升级VIP会员',
|
||
})
|
||
|
||
const VipUpgradePage: React.FC = () => {
|
||
const { user, isLoggedIn } = useUser()
|
||
const [realName, setRealName] = useState('')
|
||
const [address, setAddress] = useState('')
|
||
const [loading, setLoading] = useState(false)
|
||
const [existingApply, setExistingApply] = useState<ShopDealerApply | null>(null)
|
||
|
||
useEffect(() => {
|
||
if (!isLoggedIn) {
|
||
Taro.navigateTo({ url: '/passport/login' })
|
||
return
|
||
}
|
||
if (user) {
|
||
// 门店名称和地址统一从 shop-dealer-apply 表读取
|
||
listShopDealerApply({ userId: (user as any)?.userId || (user as any)?.id })
|
||
.then(data => {
|
||
if (!data || data.length === 0) return
|
||
// 取最新一条申请记录(按 applyId 倒序)
|
||
const latest = [...data].sort((a, b) => (b.applyId || 0) - (a.applyId || 0))[0]
|
||
if (latest) {
|
||
setExistingApply(latest)
|
||
setRealName(latest.realName || '')
|
||
setAddress(latest.address || '')
|
||
}
|
||
})
|
||
.catch(() => {})
|
||
}
|
||
}, [user, isLoggedIn])
|
||
|
||
const handleSave = async () => {
|
||
if (!realName.trim()) {
|
||
Taro.showToast({ title: '请输入门店名称', icon: 'none' })
|
||
return
|
||
}
|
||
if (!address.trim()) {
|
||
Taro.showToast({ title: '请输入门店地址', icon: 'none' })
|
||
return
|
||
}
|
||
setLoading(true)
|
||
try {
|
||
await addShopDealerApply({
|
||
userId: (user as any)?.userId || (user as any)?.id,
|
||
realName: realName.trim(),
|
||
address: address.trim(),
|
||
applyType: 10, // 需后台审核
|
||
applyStatus: 10, // 待审核
|
||
} as ShopDealerApply)
|
||
Taro.showToast({ title: '提交成功,等待审核', icon: 'none' })
|
||
setTimeout(() => {
|
||
Taro.navigateBack()
|
||
}, 1500)
|
||
} catch (error) {
|
||
console.error('提交失败:', error)
|
||
Taro.showToast({ title: '提交失败,请重试', icon: 'none' })
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
// 待审核(10) 和 已通过(20) 时只读展示;已驳回(30) 允许编辑后重新提交
|
||
const isReadonly = existingApply?.applyStatus === 10 || existingApply?.applyStatus === 20
|
||
|
||
if (!isLoggedIn) return null
|
||
|
||
return (
|
||
<View className='min-h-screen bg-gray-50'>
|
||
{/* 顶部渐变背景 */}
|
||
<View className='pt-8 pb-12 px-5 rounded-b-3xl relative overflow-hidden'
|
||
style={{ background: 'linear-gradient(135deg, #15803d 0%, #22c55e 60%, #4ade80 100%)' }}
|
||
>
|
||
<View className='absolute -top-10 -right-10 w-40 h-40 rounded-full opacity-10' style={{ background: 'radial-gradient(circle, #ffffff, transparent)' }} />
|
||
<View className='absolute -bottom-6 -left-6 w-24 h-24 rounded-full opacity-15' style={{ background: 'radial-gradient(circle, #ffffff, transparent)' }} />
|
||
<View className='relative z-10 flex flex-col items-center'>
|
||
<View className='w-16 h-16 rounded-full bg-white bg-opacity-20 flex items-center justify-center mb-3'>
|
||
<Text className='text-3xl'>👑</Text>
|
||
</View>
|
||
<Text className='text-white text-xl font-bold'>升级VIP会员</Text>
|
||
<Text className='text-white text-opacity-80 text-sm mt-1'>
|
||
{existingApply?.applyStatus === 20 ? '恭喜您已是VIP会员' : '填写门店信息,申请VIP会员资格'}
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 状态提示 */}
|
||
{existingApply && (
|
||
<View className='mx-3 -mt-6 bg-white rounded-xl p-4 shadow-sm relative z-20 mb-3'>
|
||
<View className='flex items-start gap-3'>
|
||
<View className={`w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${
|
||
existingApply.applyStatus === 10 ? 'bg-amber-100' : 'bg-green-100'
|
||
}`}>
|
||
<Text className='text-sm'>{existingApply.applyStatus === 10 ? '⏳' : '✅'}</Text>
|
||
</View>
|
||
<View className='flex-1'>
|
||
<Text className='text-gray-800 text-sm font-medium block'>
|
||
{existingApply.applyStatus === 10 ? '审核中' : '审核通过'}
|
||
</Text>
|
||
<Text className='text-gray-500 text-xs mt-1 block leading-relaxed'>
|
||
{existingApply.applyStatus === 10
|
||
? '您的VIP申请正在审核中,请耐心等待。审核结果将通过消息通知您。'
|
||
: '恭喜!您的VIP会员申请已审核通过,现在可以享受全部VIP专属权益。'}
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)}
|
||
|
||
{/* 说明卡片 */}
|
||
{!existingApply && (
|
||
<View className='mx-3 -mt-6 bg-white rounded-xl p-4 shadow-sm relative z-20'>
|
||
<View className='flex items-start gap-3'>
|
||
<View className='w-8 h-8 rounded-full bg-green-100 flex items-center justify-center flex-shrink-0'>
|
||
<Text className='text-sm'>💡</Text>
|
||
</View>
|
||
<View className='flex-1'>
|
||
<Text className='text-gray-800 text-sm font-medium block'>温馨提示</Text>
|
||
<Text className='text-gray-500 text-xs mt-1 block leading-relaxed'>
|
||
请填写您的门店信息,提交后管理员将进行审核。审核通过后即可享受VIP会员专属权益,包括更高佣金、专属折扣等特权。
|
||
</Text>
|
||
</View>
|
||
</View>
|
||
</View>
|
||
)}
|
||
|
||
{/* 表单 */}
|
||
<View className={`${existingApply ? 'mt-3' : ''} mx-3 mt-3 bg-white rounded-xl overflow-hidden`}>
|
||
{/* 门店名称 */}
|
||
<View className='px-4 py-4 border-b border-gray-50'>
|
||
<Text className='text-sm text-gray-700 font-medium block mb-2'>门店名称 <Text className='text-red-500'>*</Text></Text>
|
||
<Input
|
||
className='w-full text-sm text-gray-800 bg-gray-50 rounded-lg px-3 py-3'
|
||
placeholder='请输入您的门店名称'
|
||
value={realName}
|
||
onInput={(e: any) => setRealName(e.detail.value)}
|
||
maxlength={50}
|
||
disabled={isReadonly}
|
||
/>
|
||
</View>
|
||
|
||
{/* 门店地址 */}
|
||
<View className='px-4 py-4'>
|
||
<Text className='text-sm text-gray-700 font-medium block mb-2'>门店地址 <Text className='text-red-500'>*</Text></Text>
|
||
<Input
|
||
className='w-full text-sm text-gray-800 bg-gray-50 rounded-lg px-3 py-3'
|
||
placeholder='请输入您的门店详细地址'
|
||
value={address}
|
||
onInput={(e: any) => setAddress(e.detail.value)}
|
||
maxlength={100}
|
||
disabled={isReadonly}
|
||
/>
|
||
</View>
|
||
</View>
|
||
|
||
{/* VIP权益预览 */}
|
||
<View className='mx-3 mt-4'>
|
||
<Text className='text-base font-medium text-gray-800 mb-3 block'>VIP会员专属权益</Text>
|
||
<View className='grid grid-cols-2 gap-3'>
|
||
{[
|
||
{ icon: '💎', title: '更高佣金', desc: '享受高额团队佣金' },
|
||
{ icon: '🎁', title: '专属折扣', desc: '购物享VIP专属价' },
|
||
{ icon: '⚡', title: '优先发货', desc: '订单优先处理配送' },
|
||
{ icon: '🎧', title: '专属客服', desc: '一对一VIP服务' },
|
||
].map(item => (
|
||
<View key={item.title} className='bg-white rounded-xl p-4 flex items-center gap-3'>
|
||
<View className='w-10 h-10 rounded-full bg-green-50 flex items-center justify-center flex-shrink-0'>
|
||
<Text className='text-lg'>{item.icon}</Text>
|
||
</View>
|
||
<View className='flex-1 min-w-0'>
|
||
<Text className='text-gray-800 text-sm font-medium block'>{item.title}</Text>
|
||
<Text className='text-gray-400 text-xs mt-0.5 block truncate'>{item.desc}</Text>
|
||
</View>
|
||
</View>
|
||
))}
|
||
</View>
|
||
</View>
|
||
|
||
{/* 提交按钮 */}
|
||
{!existingApply && (
|
||
<View className='mx-3 mt-6 mb-4'>
|
||
<View
|
||
className='w-full py-4 rounded-xl flex items-center justify-center active:opacity-90'
|
||
style={{ background: loading ? '#a3e635' : 'linear-gradient(135deg, #16a34a, #22c55e)' }}
|
||
onClick={loading ? undefined : handleSave}
|
||
>
|
||
<Text className='text-white text-base font-semibold'>
|
||
{loading ? '提交中...' : '提交申请'}
|
||
</Text>
|
||
</View>
|
||
<Text className='text-gray-400 text-xs mt-2 text-center block'>
|
||
提交后管理员将在1-3个工作日内审核
|
||
</Text>
|
||
</View>
|
||
)}
|
||
</View>
|
||
)
|
||
}
|
||
|
||
export default VipUpgradePage
|