StateBar.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import React from 'react';
  2. import { Space, Tooltip } from 'antd';
  3. import Quota from '../pages/security/Quota';
  4. import { useEffect } from 'react';
  5. import { useDispatch } from 'react-redux';
  6. import { setQuota } from '../states/security/quotaSlice';
  7. import { getQuota } from '../API/security/quotaActions';
  8. import { HddOutlined, WifiOutlined, FireOutlined } from '@ant-design/icons';
  9. import Icon from '@/components/Icon';
  10. import { useAppSelector } from '@/states/store';
  11. // 定义状态类型
  12. interface StatusBarProps {
  13. diskStatus: 'available' | 'warning' | 'unavailable'; // 磁盘状态
  14. batteryLevel: number; // 电量(0-100)
  15. wifiStrength: 0 | 1 | 2 | 3 | 4; // WiFi 信号强度
  16. heatCapacity: number; // 热容(0-100)
  17. }
  18. // 磁盘状态组件
  19. const DiskStatus: React.FC<{ status: StatusBarProps['diskStatus'] }> = ({
  20. status,
  21. }) => {
  22. let color: string;
  23. let title: string;
  24. switch (status) {
  25. case 'available':
  26. color = 'text-green-500'; // Tailwind 绿色
  27. title = '磁盘空间充足';
  28. break;
  29. case 'warning':
  30. color = 'text-yellow-500'; // Tailwind 黄色
  31. title = '磁盘空间警告';
  32. break;
  33. case 'unavailable':
  34. color = 'text-red-500'; // Tailwind 红色
  35. title = '磁盘不可用';
  36. break;
  37. default:
  38. color = 'text-gray-400';
  39. title = '未知状态';
  40. }
  41. return (
  42. <Tooltip title={title}>
  43. <HddOutlined className={`${color} text-[1em]`} />
  44. </Tooltip>
  45. );
  46. };
  47. // 电量组件
  48. const BatteryStatus: React.FC<{ level: number }> = ({ level }) => {
  49. const themeType = useAppSelector((state) => state.theme.themeType);
  50. const color =
  51. level <= 20
  52. ? 'text-red-500'
  53. : level <= 50
  54. ? 'text-yellow-500'
  55. : 'text-green-500';
  56. return (
  57. <Tooltip title={`电量: ${level}%`}>
  58. {/* <BarChartOutlined className={`${color} h-full`} /> */}
  59. <Icon
  60. module="module-device"
  61. name="battery-full"
  62. userId="base"
  63. theme={themeType}
  64. size="2x"
  65. state="normal"
  66. useAntdIcon={false}
  67. className={`${color} h-[1em] w-[1em]`}
  68. />
  69. </Tooltip>
  70. );
  71. };
  72. // WiFi 信号组件
  73. const WifiStatus: React.FC<{ strength: StatusBarProps['wifiStrength'] }> = ({
  74. strength,
  75. }) => {
  76. const colors = [
  77. 'text-gray-400', // 0格
  78. 'text-red-500', // 1格
  79. 'text-orange-500', // 2格
  80. 'text-yellow-500', // 3格
  81. 'text-green-500', // 4格
  82. ];
  83. const title = `WiFi 信号: ${strength} 格`;
  84. return (
  85. <Tooltip title={title}>
  86. <WifiOutlined
  87. className={`${colors[strength]} ${strength === 0 ? 'scale-75' : 'scale-100'} h-full`}
  88. />
  89. </Tooltip>
  90. );
  91. };
  92. // 热容组件
  93. const HeatCapacityStatus: React.FC<{ capacity: number }> = ({ capacity }) => {
  94. const color =
  95. capacity <= 30
  96. ? 'text-red-500 border-red-500'
  97. : capacity <= 60
  98. ? 'text-yellow-500 border-yellow-500'
  99. : 'text-green-500 border-green-500';
  100. return (
  101. <Tooltip title={`热容: ${capacity}%`}>
  102. {/* 火焰 */}
  103. <FireOutlined className={`${color}`} />
  104. </Tooltip>
  105. );
  106. };
  107. // 主状态栏组件
  108. const StatusBar: React.FC<StatusBarProps> = ({
  109. diskStatus,
  110. batteryLevel,
  111. wifiStrength,
  112. heatCapacity,
  113. }) => {
  114. const dispatch = useDispatch();
  115. useEffect(() => {
  116. const fetchQuota = async () => {
  117. try {
  118. const response = await getQuota();
  119. dispatch(
  120. setQuota({
  121. available: response.data.available,
  122. total: response.data.total,
  123. })
  124. );
  125. } catch (error) {
  126. dispatch(
  127. setQuota({
  128. available: 0,
  129. total: 0,
  130. })
  131. );
  132. console.error('Failed to fetch quota:', error);
  133. }
  134. };
  135. fetchQuota();
  136. const intervalId = setInterval(fetchQuota, 1000);
  137. return () => clearInterval(intervalId);
  138. }, [dispatch]);
  139. return (
  140. // <div className="flex justify-end p-2">
  141. <Space className="h-full">
  142. <Quota />
  143. <DiskStatus status={diskStatus} />
  144. <BatteryStatus level={batteryLevel} />
  145. <WifiStatus strength={wifiStrength} />
  146. <HeatCapacityStatus capacity={heatCapacity} />
  147. </Space>
  148. // </div>
  149. );
  150. };
  151. export default StatusBar;
  152. export type { StatusBarProps };
  153. export { DiskStatus, BatteryStatus, WifiStatus, HeatCapacityStatus };
  154. export type DiskStatusType = 'available' | 'warning' | 'unavailable';