Files
template-10579/src/pages/index/HeaderWithHook.tsx
赵忠林 ec252beb4b feat(pages): 添加管理页面功能和配置
- 创建 .editorconfig 文件统一代码风格配置
- 配置 .eslintrc 使用 taro/react 规则集
- 完善 .gitignore 忽略编译产物和敏感文件
- 添加 admin/article/add 页面实现文章管理功能
- 添加 dealer/apply/add 页面实现经销商申请功能
- 添加 dealer/bank/add 页面实现银行卡管理功能
- 添加 dealer/customer/add 页面实现客户管理功能
- 添加 user/address/add 页面实现用户地址管理功能
- 添加 user/chat/message/add 页面实现消息功能
- 添加 user/gift/add 页面实现礼品管理功能
- 配置各页面导航栏标题和样式
- 实现表单验证和数据提交功能
- 集成图片上传和头像选择功能
- 添加日期选择和数据校验逻辑
- 实现编辑和新增模式切换
- 集成用户权限和角色管理功能
2026-02-08 12:15:31 +08:00

222 lines
6.5 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 {useEffect, useState} from "react";
import Taro from '@tarojs/taro';
import {Button, Space} from '@nutui/nutui-react-taro'
import {TriangleDown} from '@nutui/icons-react-taro'
import {Popup, Avatar, NavBar} from '@nutui/nutui-react-taro'
import {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 { useUser } from '@/hooks/useUser';
import {handleInviteRelation} from "@/utils/invite";
import MySearch from "./MySearch";
import './Header.scss';
const Header = (props: any) => {
// 使用新的hooks
const {
loading: shopLoading,
getWebsiteName,
getWebsiteLogo
} = useShopInfo();
const {
user,
isLoggedIn,
loading: userLoading
} = useUser();
const [showBasic, setShowBasic] = useState(false)
const [statusBarHeight, setStatusBarHeight] = useState<number>()
const reload = async () => {
Taro.getSystemInfo({
success: (res) => {
setStatusBarHeight(res.statusBarHeight)
},
})
// 注意商店信息现在通过useShopInfo自动管理不需要手动获取
// 用户信息现在通过useUser自动管理不需要手动获取
// 如果需要获取openId可以在用户登录后处理
if (user && !user.openid) {
Taro.login({
success: (res) => {
getWxOpenId({code: res.code}).then(() => {
console.log('OpenId获取成功');
})
}
})
}
// 检查用户认证状态
if (user?.userId) {
// 获取组织信息
getOrganization(user.userId).then((data) => {
console.log('组织信息>>>', data)
}).catch(() => {
console.log('获取组织信息失败')
});
// 检查用户认证
myUserVerify({id: user.userId}).then((data) => {
console.log('认证信息>>>', data)
}).catch(() => {
console.log('获取认证信息失败')
});
}
}
// 获取手机号授权
const handleGetPhoneNumber = ({detail}: {detail: {code?: string, encryptedData?: string, iv?: string}}) => {
const {code, encryptedData, iv} = detail
Taro.login({
success: function (loginRes) {
if (code) {
Taro.request({
url: 'https://server.websoft.top/api/wx-login/loginByMpWxPhone',
method: 'POST',
data: {
authCode: loginRes.code,
code,
encryptedData,
iv,
notVerifyPhone: true,
refereeId: 0,
sceneType: 'save_referee',
tenantId: TenantId
},
success: async function (res) {
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)
// 处理邀请关系
if (res.data.data.user?.userId) {
try {
const inviteSuccess = await handleInviteRelation(res.data.data.user.userId)
if (inviteSuccess) {
Taro.showToast({
title: '邀请关系建立成功',
icon: 'success',
duration: 2000
})
}
} catch (error) {
console.error('处理邀请关系失败:', error)
}
}
// 重新加载小程序
Taro.reLaunch({
url: '/pages/index/index'
})
}
})
} else {
console.log('登录失败!')
}
}
})
}
useEffect(() => {
reload().then()
}, [])
// 显示加载状态
if (shopLoading || userLoading) {
return (
<div className={'fixed top-0 header-bg'} style={{
height: !props.stickyStatus ? '180px' : '148px',
}}>
<div style={{padding: '20px', textAlign: 'center', color: '#fff'}}>
...
</div>
</div>
);
}
return (
<>
<div className={'fixed top-0 header-bg'} style={{
height: !props.stickyStatus ? '180px' : '148px',
}}>
<MySearch/>
</div>
<NavBar
style={{marginTop: `${statusBarHeight}px`, marginBottom: '0px', backgroundColor: 'transparent'}}
onBackClick={() => {
}}
left={
!isLoggedIn ? (
<div style={{display: 'flex', alignItems: 'center'}}>
<Button style={{color: '#000'}} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
<Space>
<Avatar
size="22"
src={getWebsiteLogo()}
/>
<span style={{color: '#000'}}>{getWebsiteName()}</span>
</Space>
</Button>
<TriangleDown size={9}/>
</div>
) : (
<div style={{display: 'flex', alignItems: 'center', gap: '8px'}}>
<Avatar
size="22"
src={getWebsiteLogo()}
/>
<span className={'text-white'}>{getWebsiteName()}</span>
<TriangleDown className={'text-white'} size={9}/>
</div>
)}>
</NavBar>
<Popup
visible={showBasic}
position="bottom"
style={{width: '100%', height: '100%'}}
onClose={() => {
setShowBasic(false)
}}
>
<div style={{padding: '20px'}}>
<h3></h3>
<div>: {getWebsiteName()}</div>
<div>Logo: <img src={getWebsiteLogo()} alt="logo" style={{width: '50px', height: '50px'}} /></div>
<h3></h3>
<div>: {isLoggedIn ? '已登录' : '未登录'}</div>
{user && (
<>
<div>ID: {user.userId}</div>
<div>: {user.phone}</div>
<div>: {user.nickname}</div>
</>
)}
<button
onClick={() => setShowBasic(false)}
style={{marginTop: '20px', padding: '10px 20px'}}
>
</button>
</div>
</Popup>
</>
)
}
export default Header;