时里院子市集
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

243 lines
7.7 KiB

import {useEffect, useState} from "react";
import Taro from '@tarojs/taro';
import {Button, Space, Sticky} from '@nutui/nutui-react-taro'
import {TriangleDown} from '@nutui/icons-react-taro'
import {Avatar, NavBar} from '@nutui/nutui-react-taro'
import {getUserInfo, getWxOpenId} from "@/api/layout";
import {TenantId} from "@/config/app";
import {getOrganization} from "@/api/system/organization";
import {myUserVerify} from "@/api/system/userVerify";
import { useShopInfo } from '@/hooks/useShopInfo';
import {handleInviteRelation, getStoredInviteParams} from "@/utils/invite";
import {View,Text} from '@tarojs/components'
import MySearch from "./MySearch";
import './Header.scss';
const Header = (props: any) => {
// 使用新的useShopInfo Hook
const {
getWebsiteName,
getWebsiteLogo
} = useShopInfo();
const [IsLogin, setIsLogin] = useState<boolean>(true)
const [statusBarHeight, setStatusBarHeight] = useState<number>()
const [stickyStatus, setStickyStatus] = useState<boolean>(false)
const reload = async () => {
Taro.getSystemInfo({
success: (res) => {
setStatusBarHeight(res.statusBarHeight)
},
})
// 注意:商店信息现在通过useShopInfo自动管理,不需要手动获取
// 获取用户信息
getUserInfo().then((data) => {
if (data) {
setIsLogin(true);
console.log('用户信息>>>', data.phone)
// 保存userId
Taro.setStorageSync('UserId', data.userId)
// 获取openId
if (!data.openid) {
Taro.login({
success: (res) => {
getWxOpenId({code: res.code}).then(() => {
})
}
})
}
// 是否已认证
if (data.certification) {
Taro.setStorageSync('Certification', '1')
}
// 机构ID
Taro.setStorageSync('OrganizationId', data.organizationId)
// 父级机构ID
if (Number(data.organizationId) > 0) {
getOrganization(Number(data.organizationId)).then(res => {
Taro.setStorageSync('OrganizationParentId', res.parentId)
})
}
// 管理员
const isKdy = data.roles?.findIndex(item => item.roleCode == 'admin')
if (isKdy != -1) {
Taro.setStorageSync('RoleName', '管理')
Taro.setStorageSync('RoleCode', 'admin')
return false;
}
// 注册用户
const isUser = data.roles?.findIndex(item => item.roleCode == 'user')
if (isUser != -1) {
Taro.setStorageSync('RoleName', '注册用户')
Taro.setStorageSync('RoleCode', 'user')
return false;
}
}
}).catch(() => {
setIsLogin(false);
console.log('未登录')
});
// 认证信息
myUserVerify({status: 1}).then(data => {
if (data?.realName) {
Taro.setStorageSync('RealName', data.realName)
}
})
}
/* 获取用户手机号 */
const handleGetPhoneNumber = ({detail}: {detail: {code?: string, encryptedData?: string, iv?: string}}) => {
const {code, encryptedData, iv} = detail
// 防重复登录检查
const loginKey = 'login_in_progress'
const loginInProgress = Taro.getStorageSync(loginKey)
if (loginInProgress && Date.now() - loginInProgress < 5000) { // 5秒内防重
return
}
// 标记登录开始
Taro.setStorageSync(loginKey, Date.now())
// 获取存储的邀请参数
const inviteParams = getStoredInviteParams()
const refereeId = inviteParams?.inviter ? parseInt(inviteParams.inviter) : 0
Taro.login({
success: function () {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
code,
encryptedData,
iv,
notVerifyPhone: true,
refereeId: refereeId, // 使用解析出的推荐人ID
sceneType: 'save_referee',
tenantId: TenantId
},
header: {
'content-type': 'application/json',
TenantId
},
success: async function (res) {
// 清除登录防重标记
Taro.removeStorageSync('login_in_progress')
if (res.data.code == 1) {
Taro.showToast({
title: res.data.message,
icon: 'error',
duration: 2000
})
return false;
}
// 登录成功
Taro.setStorageSync('access_token', res.data.data.access_token)
Taro.setStorageSync('UserId', res.data.data.user.userId)
setIsLogin(true)
// 处理邀请关系
if (res.data.data.user?.userId) {
try {
await handleInviteRelation(res.data.data.user.userId)
} catch (error) {
console.error('处理邀请关系失败:', error)
}
}
// 重新加载小程序
Taro.reLaunch({
url: '/pages/index/index'
})
},
fail: function() {
// 清除登录防重标记
Taro.removeStorageSync('login_in_progress')
}
})
} else {
console.log('登录失败!')
}
}
})
}
// 处理粘性布局状态变化
const onStickyChange = (isSticky: boolean) => {
setStickyStatus(isSticky)
console.log('Header 粘性状态:', isSticky ? '已固定' : '取消固定')
}
// 获取小程序系统信息
const getSystemInfo = () => {
const systemInfo = Taro.getSystemInfoSync()
// 状态栏高度 + 导航栏高度 (一般为44px)
return (systemInfo.statusBarHeight || 0) + 44
}
useEffect(() => {
reload().then()
}, [])
return (
<>
<Sticky
threshold={0}
onChange={onStickyChange}
style={{
zIndex: 1000,
backgroundColor: stickyStatus ? '#03605c' : 'transparent',
transition: 'background-color 0.3s ease',
}}
>
<View className={'header-bg'} style={{
height: !stickyStatus ? '180px' : `${(statusBarHeight || 0) + 44}px`,
paddingBottom: !stickyStatus ? '12px' : '0px'
}}>
{/* 只在非吸顶状态下显示搜索框 */}
{!stickyStatus && <MySearch statusBarHeight={statusBarHeight} />}
</View>
<NavBar
style={{
marginTop: `${statusBarHeight}px`,
marginBottom: '0px',
backgroundColor: 'transparent'
}}
onBackClick={() => {
}}
left={
!IsLogin ? (
<View style={{display: 'flex', alignItems: 'center'}}>
<Button style={{color: '#ffffff'}} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
<Space>
<Avatar
size="22"
src={getWebsiteLogo()}
/>
<Text style={{color: '#ffffff'}}>{getWebsiteName()}</Text>
<TriangleDown size={9} className={'text-white'}/>
</Space>
</Button>
</View>
) : (
<View style={{display: 'flex', alignItems: 'center', gap: '8px'}}>
<Avatar
size="22"
src={getWebsiteLogo()}
/>
<Text className={'text-white'}>{getWebsiteName()}</Text>
<TriangleDown className={'text-white'} size={9}/>
</View>
)}>
{/*<QRLoginButton />*/}
</NavBar>
</Sticky>
</>
)
}
export default Header