修复场站管理中编辑场站之后 侧边栏电站的显示信息 完善 home页面的天气信息

This commit is contained in:
mmc
2026-09-09 17:13:51 +08:00
parent 3797701d43
commit 5c0adefcc7
6 changed files with 165 additions and 29 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect } from 'react';
import { Outlet, useNavigate, useLocation } from 'react-router-dom';
import {
Layout, Menu, Button, Space, Select, Avatar, Card, Tag
@@ -15,7 +15,7 @@ import logo from '../assets/logo.png';
import { useSelector } from 'react-redux';
import { RootState, useAppDispatch } from '../store';
import { logout } from '../store/userSlice';
import { setCurrentStation, clearStation } from '../store/stationSlice';
import { setCurrentStation, clearStation, setStationList as setStoreStationList } from '../store/stationSlice';
import { getMenuList } from '../api/mune';
import { getStationByUserId } from '../api/stationManage';
import LanguageSwitcher from './LanguageSwitcher';
@@ -36,13 +36,19 @@ export default function AppLayout() {
const dispatch = useAppDispatch();
const { userInfo } = useSelector((state: RootState) => state.user);
const { currentStation, stationId } = useSelector((state: RootState) => state.station);
// 从 store 中同时取出 stationList(优先级最高,保证最新)
const { currentStation, stationId, stationList: storeStationList } = useSelector((state: RootState) => state.station);
// 真正用于展示和选择的列表:优先用 store 中的(StationManage 编辑后会同步),否则用本地接口的
const mergedStationList = storeStationList?.length ? storeStationList : stationList;
const getStationData = () => {
getStationByUserId().then(res => {
if (res.code === 200) {
const list = res.data || [];
setStationList(list);
// 同步到全局 store,确保各组件共享同一份最新列表
dispatch(setStoreStationList(list));
if (!currentStation && list.length > 0) {
dispatch(setCurrentStation(list[0]));
}
@@ -63,7 +69,9 @@ export default function AppLayout() {
};
const handleStationChange = (id: number) => {
const station = stationList.find(s => s.id === id);
// 优先从合并后的列表中取(包含 store 中最新编辑的数据),其次从本地 stationList
const station = mergedStationList.find(s => Number(s.id) === Number(id))
|| stationList.find(s => Number(s.id) === Number(id));
if (station) {
dispatch(setCurrentStation(station));
}
@@ -206,7 +214,7 @@ export default function AppLayout() {
value={stationId}
placeholder={t('layout.selectStation')}
onChange={handleStationChange}
options={stationList.map(s => ({ label: s.siteName, value: s.id }))}
options={mergedStationList.map(s => ({ label: s.siteName, value: s.id }))}
style={{
width: 'clamp(160px, 15vw, 220px)',
backgroundColor: '#0837a8',

View File

@@ -15,7 +15,12 @@ import { getOrgList } from '../../api/organization';
import { fetchPublishedLayers } from '../../lib/geoServer';
import { useSelector } from 'react-redux';
import { useAppDispatch, RootState } from '../../store';
import { setCurrentStation as setStoreStation } from '../../store/stationSlice';
import {
setCurrentStation as setStoreStation,
setStationList,
updateStationInList,
removeStationFromList,
} from '../../store/stationSlice';
import { useTranslation } from 'react-i18next';
const { Option } = Select;
@@ -96,12 +101,15 @@ export default function StationManage() {
};
getStationList(params).then(res => {
if (res.code === 200) {
setStationList(res.rows || []);
const list = res.rows || [];
setStationList(list);
setPagination({
...pagination,
total: res.total || res.rows?.length || 0
});
dispatch(setStationList(list));
}
});
};
@@ -193,11 +201,18 @@ export default function StationManage() {
saveSite(params).then(res => {
if (res.code === 200) {
messageApi.success(editRecord ? t('common.editSuccess') : t('common.addSuccess'));
getStationData();
// 编辑的场站若正是当前选中场站,则同步更新到 store(尤其 siteMapName)
if (editRecord && storeStation && editRecord.id === storeStation.id) {
dispatch(setStoreStation({ ...storeStation, ...params }));
// ========== 关键修复:同步更新全局 store ==========
// 优先使用接口返回的最新对象(res.data),否则回退到提交参数
const latestStation = { ...(editRecord || {}), ...params };
if (editRecord) {
// 编辑:更新 stationList 中对应项(slice 内部会自动同步 currentStation)
dispatch(updateStationInList(latestStation));
}
// ===================================================
getStationData();
setModalVisible(false);
} else {
messageApi.error(res.msg || t('common.saveFail'));
@@ -211,6 +226,8 @@ export default function StationManage() {
deleteSite([id]).then(res => {
if (res.code === 200) {
messageApi.success(t('common.deleteSuccess'));
// 同步从全局 store 中移除
dispatch(removeStationFromList(id));
getStationData();
} else {
messageApi.error(res.msg || t('common.deleteFail'));

View File

@@ -647,8 +647,8 @@ export default function DeviceOverviewPage() {
<Card title={<><SettingOutlined />{t('devices.fixed2EquipmentListFixed2')}</>} variant="borderless" style={{ borderRadius: 8, marginBottom: 8 }}>
<Table rowKey={(record) => record.id || record.serialNumber || record.device_sn} size="small" pagination={false}
columns={[
{ title: t('devices.fixed2EquipmentFixed2NameFixed2'), dataIndex: 'name', width: 140 },
{ title: t('common.type'), dataIndex: 'type', width: 90 },
{ title: t('devices.fixed2EquipmentFixed2NameFixed2'), dataIndex: 'name', width: 180 },
{ title: t('common.type'), dataIndex: 'type', },
{
title: t('workOrder.currentStatus'),
dataIndex: 'onlineStatus',
@@ -659,15 +659,16 @@ export default function DeviceOverviewPage() {
return <Tag color={color} style={{ margin: 0 }}>{text}</Tag>;
}
}, {
title: t('devices.abMode'), dataIndex: 'mode', width: 70, render: (text) => {
let color = 'default';
if (text === '作业中') color = 'processing';
if (text === t('devices.idle')) color = 'success';
if (text === '空闲中') color = 'success';
if (text === '现场调试') color = 'warning';
if (text === '远程调试') color = 'warning';
if (text === '固件升级中') color = 'error';
return <Tag color={color} style={{ margin: 0 }}>{text}</Tag>;
title: t('workOrder.currentStatus'), dataIndex: 'feStatus', width: 70, render: (text) => {
let color;
if (text == '1') color = 'processing';
if (text == '2') color = 'success';
if (text == '3') color = 'default'; // default 就是灰色标签
return <Tag color={color} style={{ margin: 0 }}>
{text == '1' ? "工作中" : text == '2' ? "空闲中" : "离线"}
</Tag>;
}
},
{

View File

@@ -464,6 +464,7 @@ const zh = {
execTime: '执行时间',
saveTask: '保存任务',
abMode: '自定义模式',
saveFail: '保存失败',
activatedTime: '已激活时间',
aiAction1: 'AI',

View File

@@ -89,18 +89,28 @@ export default function StationDashboard() {
report_time: "2026-03-27 12:35:08"
});
const weatherType = getWeatherType(weatherdata.weather);
// 请求天气
// 请求天气:按当前场站地址/经纬度动态定位
useEffect(() => {
console.log('当前电站信息:', currentStation);
const fetchWeather = async () => {
try {
const res = await getWeatherData();
setWeatherData(res);
const options = {} as any;
if (currentStation?.address) {
options.city = currentStation.address;
}
const res = await getWeatherData(options);
setWeatherData({
...res,
city: res?.city || currentStation?.siteName || '',
district: res?.district || '',
});
} catch (err) {
console.error("天气接口请求失败", err);
}
};
fetchWeather();
}, []);
}, [currentStation]);
// 模拟数据
const stationOverview = {
todayEnergy: 4752.0,

View File

@@ -10,9 +10,20 @@ const loadStationFromStorage = () => {
}
};
// 从 localStorage 加载场站列表(可选,加速首屏)
const loadStationListFromStorage = () => {
try {
const list = localStorage.getItem('stationList');
return list ? JSON.parse(list) : [];
} catch {
return [];
}
};
const initialState = {
currentStation: loadStationFromStorage(), // 当前选中场站(完整对象)
stationId: loadStationFromStorage()?.id || null, // 方便直接用 id
stationList: loadStationListFromStorage(), // 全局场站列表(用于跨组件共享最新数据)
};
const stationSlice = createSlice({
@@ -24,19 +35,107 @@ const stationSlice = createSlice({
state.currentStation = action.payload;
state.stationId = action.payload?.id || null;
localStorage.setItem('currentStation', JSON.stringify(action.payload));
// 同时更新 stationList 中对应项(保证列表也是最新)
if (action.payload?.id && state.stationList?.length) {
const idx = state.stationList.findIndex(s => Number(s.id) === Number(action.payload.id));
if (idx >= 0) {
state.stationList[idx] = { ...state.stationList[idx], ...action.payload };
localStorage.setItem('stationList', JSON.stringify(state.stationList));
}
}
},
// 设置全局场站列表
setStationList: (state, action) => {
state.stationList = action.payload || [];
localStorage.setItem('stationList', JSON.stringify(state.stationList));
// 如果当前 currentStation 在列表中,同步更新为列表中的最新版本
if (state.stationId && state.stationList?.length) {
const latest = state.stationList.find(s => Number(s.id) === Number(state.stationId));
if (latest) {
state.currentStation = latest;
localStorage.setItem('currentStation', JSON.stringify(latest));
}
}
},
// 部分更新当前选中场站(不覆盖全部字段)
updateCurrentStation: (state, action) => {
if (!state.currentStation) return;
state.currentStation = { ...state.currentStation, ...action.payload };
state.stationId = state.currentStation?.id || state.stationId;
localStorage.setItem('currentStation', JSON.stringify(state.currentStation));
// 同步更新 stationList 中对应项
if (state.currentStation?.id && state.stationList?.length) {
const idx = state.stationList.findIndex(s => Number(s.id) === Number(state.currentStation.id));
if (idx >= 0) {
state.stationList[idx] = { ...state.stationList[idx], ...action.payload };
localStorage.setItem('stationList', JSON.stringify(state.stationList));
}
}
},
// 更新列表中的单个场站(编辑场站后调用)
updateStationInList: (state, action) => {
const updatedStation = action.payload;
if (!updatedStation?.id) return;
if (!state.stationList) state.stationList = [];
const idx = state.stationList.findIndex(s => Number(s.id) === Number(updatedStation.id));
if (idx >= 0) {
state.stationList[idx] = { ...state.stationList[idx], ...updatedStation };
} else {
state.stationList.push(updatedStation);
}
localStorage.setItem('stationList', JSON.stringify(state.stationList));
// 如果更新的场站正好是当前选中的,同步 currentStation
if (state.stationId && Number(state.stationId) === Number(updatedStation.id)) {
state.currentStation = { ...state.currentStation, ...updatedStation };
localStorage.setItem('currentStation', JSON.stringify(state.currentStation));
}
},
// 从列表中删除场站
removeStationFromList: (state, action) => {
const deletedId = action.payload;
if (!state.stationList) return;
state.stationList = state.stationList.filter(s => Number(s.id) !== Number(deletedId));
localStorage.setItem('stationList', JSON.stringify(state.stationList));
// 如果删除的是当前选中场站,清空 currentStation
if (state.stationId && Number(state.stationId) === Number(deletedId)) {
state.currentStation = null;
state.stationId = null;
localStorage.removeItem('currentStation');
}
},
// 清空场站(退出登录时用)
clearStation: (state) => {
state.currentStation = null;
state.stationId = null;
state.stationList = [];
localStorage.removeItem('currentStation');
localStorage.removeItem('stationList');
},
},
});
export const { setCurrentStation, clearStation } = stationSlice.actions;
export const {
setCurrentStation,
setStationList,
updateCurrentStation,
updateStationInList,
removeStationFromList,
clearStation,
} = stationSlice.actions;
export default stationSlice.reducer;
//使用const { currentStation, stationId } = useSelector((state: RootState) => state.station);
//使用const { currentStation, stationId, stationList } = useSelector((state: RootState) => state.station);