ERPTurbo_Client/packages/app-client/src/components/biz/CustomTabBar.tsx
shenyifei cb24afa3ee feat(message): 实现消息中心功能并优化UI交互
- 集成消息服务API,实现消息列表分页加载功能
- 添加消息未读数量实时更新,每30秒自动刷新一次
- 实现消息标记已读、删除消息等操作功能
- 优化消息界面UI,支持无限滚动加载更多消息
- 添加消息内容预览和跳转到相关业务单据功能
- 在个人中心页面增加调试模式开关快捷入口
- 修复订单车辆组件中草帘价格验证逻辑问题
- 更新供应商称重模块,新增计价方式和定金支付验证
- 调整包装创建页面品牌选择样式布局
- 更新应用版本号至v0.0.76
- 集成经销商对账记录等相关业务服务模块
2026-01-15 16:26:15 +08:00

158 lines
4.3 KiB
TypeScript

import Taro from "@tarojs/taro";
import { useEffect, useMemo, useState } from "react";
import { View } from "@tarojs/components";
import { SafeArea, Tabbar } from "@nutui/nutui-react-taro";
import { globalStore } from "@/store/global-store";
import { CustomTheme, Icon } from "@/components";
import { business } from "@/services";
export default function CustomTabBar() {
const { tabBar, setTabBar } = globalStore((state: any) => state);
const [scaleFactor, setScaleFactor] = useState(1);
const [unreadCount, setUnreadCount] = useState(0);
const userRoleVO = globalStore((state: any) => state.userRoleVO);
useEffect(() => {
const appBaseInfo = Taro.getAppBaseInfo();
// @ts-ignore
const { fontSizeSetting, fontSizeScaleFactor } = appBaseInfo;
if (fontSizeScaleFactor == 1) {
setScaleFactor(fontSizeSetting / 17);
} else {
setScaleFactor(fontSizeScaleFactor);
}
}, []);
// 获取未读消息数量
const fetchUnreadCount = async () => {
try {
const { data } = await business.messageReceiver.getUnreadCount({
messageReceiverUnreadCountQry: {},
});
if (data.success && data.data !== undefined) {
setUnreadCount(data.data);
}
} catch (error) {
console.error("获取未读消息数量失败:", error);
}
};
// 初始化时获取未读消息数量
useEffect(() => {
fetchUnreadCount();
}, []);
// 每30秒刷新一次未读消息数量
useEffect(() => {
const timer = setInterval(() => {
fetchUnreadCount();
}, 30000); // 30秒
return () => clearInterval(timer);
}, []);
const tabBarList = useMemo(() => {
// 如果没有用户角色信息,默认显示所有菜单项
return [
{
pagePath: "/pages/main/index/index",
selectedIconPath: <Icon name={"house"} size={20 * scaleFactor} />,
iconPath: (
<Icon name={"house"} color={"#6B7280"} size={20 * scaleFactor} />
),
text: "工作台",
},
{
pagePath: "/pages/main/menu/index",
selectedIconPath: (
<Icon name={"clipboard-list"} size={20 * scaleFactor} />
),
iconPath: (
<Icon
name={"clipboard-list"}
color={"#6B7280"}
size={20 * scaleFactor}
/>
),
text: "菜单",
},
{
pagePath: "/pages/main/message/index",
selectedIconPath: <Icon name={"bell"} size={20 * scaleFactor} />,
iconPath: (
<Icon name={"bell"} color={"#6B7280"} size={20 * scaleFactor} />
),
text: "消息",
},
{
pagePath: "/pages/main/center/index",
selectedIconPath: <Icon name={"user"} size={20 * scaleFactor} />,
iconPath: (
<Icon name={"user"} color={"#6B7280"} size={20 * scaleFactor} />
),
text: "我的",
},
];
}, [scaleFactor, userRoleVO]);
useEffect(() => {
const selected = tabBarList.findIndex((item) => {
return (
Taro.getCurrentInstance().router?.path.indexOf(item.pagePath) !== -1
);
});
console.log("selected", selected);
setTabBar(selected);
}, [tabBarList, userRoleVO]);
const switchTab = async (index: number, pagePath: string) => {
setTabBar(index);
await Taro.switchTab({ url: pagePath });
};
return (
<CustomTheme>
<View
style={{
height: `calc(92rpx * ${scaleFactor})`,
}}
></View>
<SafeArea position={"bottom"} />
<Tabbar
fixed
safeArea
value={tabBar?.selected}
onSwitch={async (index) => {
await switchTab(index, tabBarList[index].pagePath);
}}
>
{tabBarList.map((item, index) => {
const isMessageTab = item.pagePath === "/pages/main/message/index";
return (
<Tabbar.Item
style={{
// @ts-ignore
"--nutui-badge-background-color": "#ff0f23",
}}
key={index}
icon={
tabBar?.selected === index
? item.selectedIconPath
: item.iconPath
}
value={isMessageTab ? unreadCount : undefined}
title={item.text}
/>
);
})}
</Tabbar>
</CustomTheme>
);
}