feat(credit): 新增信用订单功能模块
- 添加信用订单创建页面,支持填写拖欠方、金额、年数等信息 - 实现附件上传功能,支持图片和文档文件上传预览 - 集成城市选择组件,方便用户选择所在地区 - 添加服务协议勾选确认机制 - 在app配置中注册信用订单相关路由 - 重构文件上传API,新增uploadFileByPath方法支持路径上传 - 更新发现页面,集成店铺网点查询和定位功能 - 实现下拉刷新和无限滚动加载更多网点数据 - 添加地图导航和电话拨打功能 - 优化网点列表显示,按距离排序并显示距离信息
This commit is contained in:
@@ -1,68 +1,164 @@
|
||||
import {useMemo, useState} from 'react'
|
||||
import Taro from '@tarojs/taro'
|
||||
import { useMemo, useRef, useState } from 'react'
|
||||
import Taro, { useDidShow } from '@tarojs/taro'
|
||||
import {Input, Text, View} from '@tarojs/components'
|
||||
import { Empty, InfiniteLoading, Loading, PullToRefresh } from '@nutui/nutui-react-taro'
|
||||
import {Search} from '@nutui/icons-react-taro'
|
||||
import { pageShopStore } from '@/api/shop/shopStore'
|
||||
import type { ShopStore } from '@/api/shop/shopStore/model'
|
||||
import { getCurrentLngLat } from '@/utils/location'
|
||||
import './find.scss'
|
||||
|
||||
type SiteItem = {
|
||||
id: string
|
||||
cityName: string
|
||||
address: string
|
||||
phone: string
|
||||
contact: string
|
||||
distanceMeter: number
|
||||
const PAGE_SIZE = 10
|
||||
|
||||
type LngLat = { lng: number; lat: number }
|
||||
type ShopStoreView = ShopStore & { __distanceMeter?: number }
|
||||
|
||||
const parseLngLat = (raw: string | undefined): LngLat | null => {
|
||||
const text = (raw || '').trim()
|
||||
if (!text) return null
|
||||
const parts = text.split(/[,\s]+/).filter(Boolean)
|
||||
if (parts.length < 2) return null
|
||||
const a = Number(parts[0])
|
||||
const b = Number(parts[1])
|
||||
if (!Number.isFinite(a) || !Number.isFinite(b)) return null
|
||||
|
||||
// Accept both "lng,lat" and "lat,lng".
|
||||
const looksLikeLngLat = Math.abs(a) <= 180 && Math.abs(b) <= 90
|
||||
const looksLikeLatLng = Math.abs(a) <= 90 && Math.abs(b) <= 180
|
||||
if (looksLikeLngLat) return { lng: a, lat: b }
|
||||
if (looksLikeLatLng) return { lng: b, lat: a }
|
||||
return null
|
||||
}
|
||||
|
||||
const MOCK_SITES: SiteItem[] = [
|
||||
{
|
||||
id: '1',
|
||||
cityName: '北京朝阳区网点',
|
||||
address: '地安门西大街(南门)',
|
||||
phone: '15878179339',
|
||||
contact: '刘先生',
|
||||
distanceMeter: 100
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
cityName: '兰州某某区网点',
|
||||
address: '地安门西大街(南门)',
|
||||
phone: '15878179339',
|
||||
contact: '黄先生',
|
||||
distanceMeter: 150
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
cityName: '合肥市某某区网点',
|
||||
address: '地安门西大街(南门)',
|
||||
phone: '15878179339',
|
||||
contact: '黄先生',
|
||||
distanceMeter: 250
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
cityName: '南宁市某某区网点',
|
||||
address: '广西壮族自治区南宁市良庆区五象新区五象大道403号富雅国际金融中心G1栋高层6006',
|
||||
phone: '15878179339',
|
||||
contact: '柳先生',
|
||||
distanceMeter: 1250
|
||||
}
|
||||
]
|
||||
const distanceMeters = (a: LngLat, b: LngLat) => {
|
||||
const toRad = (x: number) => (x * Math.PI) / 180
|
||||
const R = 6371000
|
||||
const dLat = toRad(b.lat - a.lat)
|
||||
const dLng = toRad(b.lng - a.lng)
|
||||
const lat1 = toRad(a.lat)
|
||||
const lat2 = toRad(b.lat)
|
||||
const sin1 = Math.sin(dLat / 2)
|
||||
const sin2 = Math.sin(dLng / 2)
|
||||
const h = sin1 * sin1 + Math.cos(lat1) * Math.cos(lat2) * sin2 * sin2
|
||||
return 2 * R * Math.asin(Math.min(1, Math.sqrt(h)))
|
||||
}
|
||||
|
||||
const formatDistance = (meter: number | undefined) => {
|
||||
if (!Number.isFinite(meter as number)) return ''
|
||||
const m = Math.max(0, Math.round(meter as number))
|
||||
if (m < 1000) return `${m}米`
|
||||
const km = m / 1000
|
||||
return `${km.toFixed(km >= 10 ? 0 : 1)}公里`
|
||||
}
|
||||
|
||||
const Find = () => {
|
||||
const [keyword, setKeyword] = useState<string>('')
|
||||
const [storeList, setStoreList] = useState<ShopStoreView[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
const [total, setTotal] = useState(0)
|
||||
const [userLngLat, setUserLngLat] = useState<LngLat | null>(null)
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
const key = keyword.trim()
|
||||
if (!key) return MOCK_SITES
|
||||
return MOCK_SITES.filter((it) => it.cityName.includes(key))
|
||||
}, [keyword])
|
||||
const pageRef = useRef(1)
|
||||
const latestListRef = useRef<ShopStoreView[]>([])
|
||||
const loadingRef = useRef(false)
|
||||
const coordsRef = useRef<LngLat | null>(null)
|
||||
|
||||
const onNavigate = (item: SiteItem) => {
|
||||
Taro.showToast({title: `导航至:${item.cityName}(示例)`, icon: 'none'})
|
||||
const viewList = useMemo<ShopStoreView[]>(() => {
|
||||
const me = userLngLat
|
||||
if (!me) return storeList
|
||||
|
||||
// Keep backend order; only attach distance for display.
|
||||
return storeList.map((s) => {
|
||||
const coords = parseLngLat(s.lngAndLat || s.location)
|
||||
if (!coords) return s
|
||||
return { ...s, __distanceMeter: distanceMeters(me, coords) }
|
||||
})
|
||||
}, [storeList, userLngLat])
|
||||
|
||||
const loadStores = async (isRefresh = true, keywordsOverride?: string) => {
|
||||
if (loadingRef.current) return
|
||||
loadingRef.current = true
|
||||
setLoading(true)
|
||||
|
||||
if (isRefresh) {
|
||||
pageRef.current = 1
|
||||
latestListRef.current = []
|
||||
setStoreList([])
|
||||
setHasMore(true)
|
||||
setTotal(0)
|
||||
}
|
||||
|
||||
try {
|
||||
if (!coordsRef.current) {
|
||||
const me = await getCurrentLngLat('为您展示附近网点,需要获取定位信息。')
|
||||
const lng = me ? Number(me.lng) : NaN
|
||||
const lat = me ? Number(me.lat) : NaN
|
||||
coordsRef.current = Number.isFinite(lng) && Number.isFinite(lat) ? { lng, lat } : null
|
||||
setUserLngLat(coordsRef.current)
|
||||
}
|
||||
|
||||
const currentPage = pageRef.current
|
||||
const kw = (keywordsOverride ?? keyword).trim()
|
||||
const res = await pageShopStore({
|
||||
page: currentPage,
|
||||
limit: PAGE_SIZE,
|
||||
keywords: kw || undefined
|
||||
})
|
||||
|
||||
const resList = res?.list || []
|
||||
const nextList = isRefresh ? resList : [...latestListRef.current, ...resList]
|
||||
latestListRef.current = nextList
|
||||
setStoreList(nextList)
|
||||
|
||||
const count = typeof res?.count === 'number' ? res.count : nextList.length
|
||||
setTotal(count)
|
||||
setHasMore(nextList.length < count)
|
||||
|
||||
if (resList.length > 0) {
|
||||
pageRef.current = currentPage + 1
|
||||
} else {
|
||||
setHasMore(false)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取网点列表失败:', e)
|
||||
Taro.showToast({ title: '获取网点失败', icon: 'none' })
|
||||
setHasMore(false)
|
||||
} finally {
|
||||
loadingRef.current = false
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
useDidShow(() => {
|
||||
loadStores(true).then()
|
||||
})
|
||||
|
||||
const onNavigate = (item: ShopStore) => {
|
||||
const coords = parseLngLat(item.lngAndLat || item.location)
|
||||
if (!coords) {
|
||||
Taro.showToast({ title: '网点暂无坐标,无法导航', icon: 'none' })
|
||||
return
|
||||
}
|
||||
Taro.openLocation({
|
||||
latitude: coords.lat,
|
||||
longitude: coords.lng,
|
||||
name: item.name || item.city || '网点',
|
||||
address: item.address || ''
|
||||
})
|
||||
}
|
||||
|
||||
const onCall = (phone: string | undefined) => {
|
||||
const p = (phone || '').trim()
|
||||
if (!p) {
|
||||
Taro.showToast({ title: '暂无联系电话', icon: 'none' })
|
||||
return
|
||||
}
|
||||
Taro.makePhoneCall({ phoneNumber: p })
|
||||
}
|
||||
|
||||
const onSearch = () => {
|
||||
Taro.showToast({title: '查询(示例)', icon: 'none'})
|
||||
loadStores(true).then()
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -84,44 +180,84 @@ const Find = () => {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className='siteList'>
|
||||
{filtered.map((item) => (
|
||||
<View key={item.id} className='siteCard'>
|
||||
<View className='siteCardInner'>
|
||||
<View className='siteInfo'>
|
||||
<View className='siteRow siteRowTop'>
|
||||
<Text className='siteLabel'>城市名称:</Text>
|
||||
<Text className='siteValue siteValueStrong'>{item.cityName}</Text>
|
||||
</View>
|
||||
<View className='siteDivider' />
|
||||
<View className='siteRow'>
|
||||
<Text className='siteLabel'>网点地址:</Text>
|
||||
<Text className='siteValue'>{item.address}</Text>
|
||||
</View>
|
||||
<View className='siteRow'>
|
||||
<Text className='siteLabel'>联系电话:</Text>
|
||||
<Text className='siteValue'>{item.phone}</Text>
|
||||
</View>
|
||||
<View className='siteRow'>
|
||||
<Text className='siteLabel'>联系人:</Text>
|
||||
<Text className='siteValue'>{item.contact}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className='siteSide' onClick={() => onNavigate(item)}>
|
||||
<View className='navArrow' />
|
||||
<Text className='distanceText'>距离{item.distanceMeter}米</Text>
|
||||
</View>
|
||||
<PullToRefresh onRefresh={() => loadStores(true)} headHeight={60}>
|
||||
<View style={{ height: 'calc(100vh)', overflowY: 'auto' }} id='store-scroll'>
|
||||
{viewList.length === 0 && !loading ? (
|
||||
<View className='emptyWrap'>
|
||||
<Empty description='暂无网点' style={{ backgroundColor: 'transparent' }} />
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
) : (
|
||||
<View className='siteList'>
|
||||
<InfiniteLoading
|
||||
target='store-scroll'
|
||||
hasMore={hasMore}
|
||||
onLoadMore={() => loadStores(false)}
|
||||
loadingText={
|
||||
<View className='emptyWrap'>
|
||||
<Loading />
|
||||
<Text className='emptyText' style={{ marginLeft: '8px' }}>
|
||||
加载中...
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
loadMoreText={
|
||||
<View className='emptyWrap'>
|
||||
<Text className='emptyText'>
|
||||
{viewList.length === 0 ? '暂无网点' : '没有更多了'}
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
>
|
||||
{viewList.map((item, idx) => {
|
||||
const name = item?.name || item?.city || item?.province || '网点'
|
||||
const contact = item?.managerName || '--'
|
||||
const distanceText = formatDistance(item?.__distanceMeter)
|
||||
return (
|
||||
<View key={String(item?.id ?? `${name}-${idx}`)} className='siteCard'>
|
||||
<View className='siteCardInner'>
|
||||
<View className='siteInfo'>
|
||||
<View className='siteRow siteRowTop'>
|
||||
<Text className='siteLabel'>网点名称:</Text>
|
||||
<Text className='siteValue siteValueStrong'>{name}</Text>
|
||||
</View>
|
||||
<View className='siteDivider' />
|
||||
<View className='siteRow'>
|
||||
<Text className='siteLabel'>网点地址:</Text>
|
||||
<Text className='siteValue'>{item?.address || '--'}</Text>
|
||||
</View>
|
||||
<View className='siteRow'>
|
||||
<Text className='siteLabel'>联系电话:</Text>
|
||||
<Text className='siteValue' onClick={() => onCall(item?.phone)}>
|
||||
{item?.phone || '--'}
|
||||
</Text>
|
||||
</View>
|
||||
<View className='siteRow'>
|
||||
<Text className='siteLabel'>联系人:</Text>
|
||||
<Text className='siteValue'>{contact}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{filtered.length === 0 && (
|
||||
<View className='emptyWrap'>
|
||||
<Text className='emptyText'>暂无网点</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<View className='siteSide' onClick={() => onNavigate(item)}>
|
||||
<View className='navArrow' />
|
||||
<Text className='distanceText'>
|
||||
{distanceText ? `距离${distanceText}` : '查看导航'}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</InfiniteLoading>
|
||||
|
||||
{total > 0 && (
|
||||
<View className='emptyWrap' style={{ paddingTop: '10rpx' }}>
|
||||
<Text className='emptyText'>共 {total} 个网点</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</PullToRefresh>
|
||||
|
||||
<View className='bottomSafe' />
|
||||
</View>
|
||||
|
||||
@@ -4,6 +4,7 @@ import iconShop from '@/assets/tabbar/shop.png'
|
||||
import iconFind from '@/assets/tabbar/find.png'
|
||||
import iconKefu from '@/assets/tabbar/kefu.png'
|
||||
import './index.scss'
|
||||
import navTo from "@/utils/common";
|
||||
|
||||
function Home() {
|
||||
useShareTimeline(() => {
|
||||
@@ -42,10 +43,6 @@ function Home() {
|
||||
|
||||
return (
|
||||
<View className='home'>
|
||||
<View className='welcomeCard'>
|
||||
<Text className='welcomeText'>欢迎来到易赊宝小程序~</Text>
|
||||
</View>
|
||||
|
||||
<View className='bannerCard'>
|
||||
<Swiper
|
||||
className='bannerSwiper'
|
||||
@@ -115,7 +112,7 @@ function Home() {
|
||||
</View>
|
||||
|
||||
<View className='ctaWrap'>
|
||||
<View className='ctaBtn' onClick={onDemand}>
|
||||
<View className='ctaBtn' onClick={() => navTo('/credit/order/add', true)}>
|
||||
<Text className='ctaBtnText'>发需求</Text>
|
||||
</View>
|
||||
<Text className='ctaHint'>提出您的述求,免费获取解决方案</Text>
|
||||
|
||||
@@ -333,27 +333,27 @@ const UserCard = forwardRef<any, any>((_, ref) => {
|
||||
)}
|
||||
</View>
|
||||
<View className={'py-2'}>
|
||||
<View className={'flex justify-around mt-1'}>
|
||||
<View className={'item flex justify-center flex-col items-center'}
|
||||
onClick={() => navTo('/user/ticket/index', true)}>
|
||||
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>水票</Text>
|
||||
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{ticketTotal}</Text>
|
||||
</View>
|
||||
<View className={'item flex justify-center flex-col items-center'}
|
||||
onClick={() => navTo('/user/coupon/index', true)}>
|
||||
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>优惠券</Text>
|
||||
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.coupons || 0}</Text>
|
||||
</View>
|
||||
<View className={'item flex justify-center flex-col items-center'}
|
||||
onClick={() => navTo('/user/wallet/wallet', true)}>
|
||||
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>余额</Text>
|
||||
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.balance || '0.00'}</Text>
|
||||
</View>
|
||||
<View className={'item flex justify-center flex-col items-center'}>
|
||||
<Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>积分</Text>
|
||||
<Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.points || 0}</Text>
|
||||
</View>
|
||||
</View>
|
||||
{/*<View className={'flex justify-around mt-1'}>*/}
|
||||
{/* <View className={'item flex justify-center flex-col items-center'}*/}
|
||||
{/* onClick={() => navTo('/user/ticket/index', true)}>*/}
|
||||
{/* <Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>水票</Text>*/}
|
||||
{/* <Text className={'text-xl text-white'} style={themeStyles.textColor}>{ticketTotal}</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* <View className={'item flex justify-center flex-col items-center'}*/}
|
||||
{/* onClick={() => navTo('/user/coupon/index', true)}>*/}
|
||||
{/* <Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>优惠券</Text>*/}
|
||||
{/* <Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.coupons || 0}</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* <View className={'item flex justify-center flex-col items-center'}*/}
|
||||
{/* onClick={() => navTo('/user/wallet/wallet', true)}>*/}
|
||||
{/* <Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>余额</Text>*/}
|
||||
{/* <Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.balance || '0.00'}</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/* <View className={'item flex justify-center flex-col items-center'}>*/}
|
||||
{/* <Text className={'text-xs text-gray-200'} style={themeStyles.textColor}>积分</Text>*/}
|
||||
{/* <Text className={'text-xl text-white'} style={themeStyles.textColor}>{data?.points || 0}</Text>*/}
|
||||
{/* </View>*/}
|
||||
{/*</View>*/}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -46,7 +46,12 @@ const UserFooter = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'text-center py-4 w-full text-gray-300'} onClick={onLoginByPhone}>
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
}} className={'text-center py-4 w-full text-gray-300'} onClick={onLoginByPhone}>
|
||||
<div className={'text-xs text-gray-400 py-1'}>当前版本:{Version}</div>
|
||||
<div className={'text-xs text-gray-400 py-1'}>Copyright © { new Date().getFullYear() } {Copyright}</div>
|
||||
</div>
|
||||
|
||||
@@ -3,12 +3,9 @@ import navTo from "@/utils/common";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {View, Button} from '@tarojs/components'
|
||||
import {
|
||||
ShieldCheck,
|
||||
Location,
|
||||
Tips,
|
||||
Ask,
|
||||
// Dongdong,
|
||||
People,
|
||||
Agenda,
|
||||
// AfterSaleService,
|
||||
Logout,
|
||||
Shop,
|
||||
@@ -38,7 +35,7 @@ const UserCell = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<View className="bg-white mx-4 mt-4 rounded-xl">
|
||||
<View className="bg-white mx-4 mt-4 rounded-xl" style={{backgroundColor: '#fff', width:'92%', position: 'fixed'}}>
|
||||
<View className="font-semibold text-gray-800 pt-4 pl-4">我的服务</View>
|
||||
<ConfigProvider>
|
||||
<Grid
|
||||
@@ -71,24 +68,22 @@ const UserCell = () => {
|
||||
</Grid.Item>
|
||||
)}
|
||||
|
||||
{(hasRole('staff') || hasRole('admin')) && (
|
||||
<Grid.Item text="门店订单" onClick={() => navTo('/user/store/orders/index', true)}>
|
||||
<View className="text-center">
|
||||
<View className="w-12 h-12 bg-orange-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
<Shop color="#f59e0b" size="20"/>
|
||||
</View>
|
||||
</View>
|
||||
</Grid.Item>
|
||||
)}
|
||||
|
||||
<Grid.Item text="配送地址" onClick={() => navTo('/user/address/index', true)}>
|
||||
<Grid.Item text="我的需求" onClick={() => navTo('/credit/order/index', true)}>
|
||||
<View className="text-center">
|
||||
<View className="w-12 h-12 bg-emerald-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
<Location color="#3b82f6" size="20"/>
|
||||
<View className="w-12 h-12 bg-orange-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
<Agenda color="#8b5cf6" size="20"/>
|
||||
</View>
|
||||
</View>
|
||||
</Grid.Item>
|
||||
|
||||
{/*<Grid.Item text="配送地址" onClick={() => navTo('/user/address/index', true)}>*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <View className="w-12 h-12 bg-emerald-50 rounded-xl flex items-center justify-center mx-auto mb-2">*/}
|
||||
{/* <Location color="#3b82f6" size="20"/>*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
{/*</Grid.Item>*/}
|
||||
|
||||
<Grid.Item text={'常见问题'} onClick={() => navTo('/user/help/index')}>
|
||||
<View className="text-center">
|
||||
<View className="w-12 h-12 bg-cyan-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
@@ -111,21 +106,21 @@ const UserCell = () => {
|
||||
</Button>
|
||||
</Grid.Item>
|
||||
|
||||
<Grid.Item text={'实名认证'} onClick={() => navTo('/user/userVerify/index', true)}>
|
||||
<View className="text-center">
|
||||
<View className="w-12 h-12 bg-green-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
<ShieldCheck color="#10b981" size="20"/>
|
||||
</View>
|
||||
</View>
|
||||
</Grid.Item>
|
||||
{/*<Grid.Item text={'实名认证'} onClick={() => navTo('/user/userVerify/index', true)}>*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <View className="w-12 h-12 bg-green-50 rounded-xl flex items-center justify-center mx-auto mb-2">*/}
|
||||
{/* <ShieldCheck color="#10b981" size="20"/>*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
{/*</Grid.Item>*/}
|
||||
|
||||
<Grid.Item text={'推广邀请'} onClick={() => navTo('/dealer/team/index', true)}>
|
||||
<View className="text-center">
|
||||
<View className="w-12 h-12 bg-purple-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
<People color="#8b5cf6" size="20"/>
|
||||
</View>
|
||||
</View>
|
||||
</Grid.Item>
|
||||
{/*<Grid.Item text={'推广邀请'} onClick={() => navTo('/dealer/team/index', true)}>*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <View className="w-12 h-12 bg-purple-50 rounded-xl flex items-center justify-center mx-auto mb-2">*/}
|
||||
{/* <People color="#8b5cf6" size="20"/>*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
{/*</Grid.Item>*/}
|
||||
|
||||
{/*<Grid.Item text={'我的邀请码'} onClick={() => navTo('/dealer/qrcode/index', true)}>*/}
|
||||
{/* <View className="text-center">*/}
|
||||
@@ -144,13 +139,13 @@ const UserCell = () => {
|
||||
{/*</Grid.Item>*/}
|
||||
|
||||
|
||||
<Grid.Item text={'关于我们'} onClick={() => navTo('/user/about/index')}>
|
||||
<View className="text-center">
|
||||
<View className="w-12 h-12 bg-amber-50 rounded-xl flex items-center justify-center mx-auto mb-2">
|
||||
<Tips className={'text-amber-500'} size="20"/>
|
||||
</View>
|
||||
</View>
|
||||
</Grid.Item>
|
||||
{/*<Grid.Item text={'关于我们'} onClick={() => navTo('/user/about/index')}>*/}
|
||||
{/* <View className="text-center">*/}
|
||||
{/* <View className="w-12 h-12 bg-amber-50 rounded-xl flex items-center justify-center mx-auto mb-2">*/}
|
||||
{/* <Tips className={'text-amber-500'} size="20"/>*/}
|
||||
{/* </View>*/}
|
||||
{/* </View>*/}
|
||||
{/*</Grid.Item>*/}
|
||||
|
||||
<Grid.Item text={'安全退出'} onClick={onLogout}>
|
||||
<View className="text-center">
|
||||
|
||||
@@ -14,6 +14,11 @@ function User() {
|
||||
|
||||
const userCardRef = useRef<any>()
|
||||
const themeStyles = useThemeStyles();
|
||||
// 仅覆盖个人中心页顶部背景为红色(不影响全局主题)
|
||||
const pagePrimaryBackground = {
|
||||
...themeStyles.primaryBackground,
|
||||
background: '#ff0000'
|
||||
}
|
||||
// TabBar 页在小程序里通常不会销毁;从“注册/申请”页返回时需要触发子组件重新初始化/拉取最新状态。
|
||||
const [dealerViewKey, setDealerViewKey] = useState(0)
|
||||
|
||||
@@ -42,7 +47,7 @@ function User() {
|
||||
headHeight={60}
|
||||
>
|
||||
{/* 装饰性背景 */}
|
||||
<View className={'h-64 w-full fixed top-0 z-0'} style={themeStyles.primaryBackground}>
|
||||
<View className={'h-64 w-full fixed top-0 z-0'} style={pagePrimaryBackground}>
|
||||
{/* 装饰性背景元素 - 小程序兼容版本 */}
|
||||
<View className="absolute w-32 h-32 rounded-full" style={{
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.1)',
|
||||
@@ -61,8 +66,6 @@ function User() {
|
||||
}}></View>
|
||||
</View>
|
||||
<UserCard ref={userCardRef}/>
|
||||
<UserOrder/>
|
||||
<IsDealer key={dealerViewKey}/>
|
||||
<UserGrid/>
|
||||
<UserFooter/>
|
||||
</PullToRefresh>
|
||||
|
||||
Reference in New Issue
Block a user