From 0ea1a453dbb475eda07dcb5b955201e0afd5a51e Mon Sep 17 00:00:00 2001 From: Your Name <2499342078@qq.com> Date: Tue, 22 Jul 2025 17:01:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=A0=B7=E5=BC=8F=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E8=AE=BE=E8=AE=A1=EF=BC=8C=E6=95=B0=E6=8D=AE=E9=9D=A2?= =?UTF-8?q?=E7=89=88=E7=BD=91=E7=B3=BB=E9=A2=9C=E8=89=B2=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/app/admin/base-setting/page.tsx | 5 +- apps/web/src/app/admin/department/page.tsx | 2 +- apps/web/src/app/admin/staff/page.tsx | 2 +- .../app/main/devicepage/dashboard/page.tsx | 266 +++++++++++------- .../app/main/devicepage/devicemodal/page.tsx | 3 +- apps/web/src/app/main/devicepage/page.tsx | 14 +- .../main/devicepage/select/Device-manager.tsx | 2 +- apps/web/src/app/main/layout/MainFooter.tsx | 20 +- apps/web/src/app/main/layout/MainHeader.tsx | 9 +- apps/web/src/app/main/layout/MainLayout.tsx | 36 ++- .../src/app/main/layout/NavigationMenu.tsx | 11 +- .../web/src/app/main/layout/UserInfoPanel.tsx | 67 +++++ apps/web/src/index.css | 74 ++++- config/nginx/conf.d/web.conf | 4 +- 14 files changed, 356 insertions(+), 159 deletions(-) create mode 100644 apps/web/src/app/main/layout/UserInfoPanel.tsx diff --git a/apps/web/src/app/admin/base-setting/page.tsx b/apps/web/src/app/admin/base-setting/page.tsx index 5d8ab38..53e2b3d 100755 --- a/apps/web/src/app/admin/base-setting/page.tsx +++ b/apps/web/src/app/admin/base-setting/page.tsx @@ -137,10 +137,7 @@ export default function BaseSettingPage() {
diff --git a/apps/web/src/app/admin/department/page.tsx b/apps/web/src/app/admin/department/page.tsx index a453c39..9dfeb51 100755 --- a/apps/web/src/app/admin/department/page.tsx +++ b/apps/web/src/app/admin/department/page.tsx @@ -1,7 +1,7 @@ import DeptEditor from "@web/src/components/models/department/dept-editor"; export default function DepartmentAdminPage() { - return
+ return
} \ No newline at end of file diff --git a/apps/web/src/app/admin/staff/page.tsx b/apps/web/src/app/admin/staff/page.tsx index 35d3c2c..4ba4815 100755 --- a/apps/web/src/app/admin/staff/page.tsx +++ b/apps/web/src/app/admin/staff/page.tsx @@ -1,7 +1,7 @@ import StaffEditor from "@web/src/components/models/staff/staff-editor" export default function StaffPage() { return ( -
+
); diff --git a/apps/web/src/app/main/devicepage/dashboard/page.tsx b/apps/web/src/app/main/devicepage/dashboard/page.tsx index 8a5ff5f..7128004 100755 --- a/apps/web/src/app/main/devicepage/dashboard/page.tsx +++ b/apps/web/src/app/main/devicepage/dashboard/page.tsx @@ -150,92 +150,36 @@ const DashboardPage = () => { }; }; - // 准备网系类型故障时间分布数据 - const prepareNetworkFaultsByTimeData = () => { - if (!devices || !networkTypeTerms) return { xAxis: [], series: [] }; + // 生成多样化颜色函数(为不同用途添加偏移) + const generateDiverseColors = (count: number, offset: number = 0) => { + const colors = []; + const hueStep = 360 / count; - const startDate = dateRange[0]; - const endDate = dateRange[1]; - const diffDays = endDate.diff(startDate, 'day'); - - // 时间间隔逻辑 - const intervals = []; - let format = ''; - - if (diffDays <= 14) { - format = 'MM-DD'; - for (let i = 0; i <= diffDays; i++) { - intervals.push(startDate.add(i, 'day')); - } - } else if (diffDays <= 90) { - format = 'MM-DD'; - const weeks = Math.ceil(diffDays / 7); - for (let i = 0; i < weeks; i++) { - const weekStart = startDate.add(i * 7, 'day'); - intervals.push(weekStart); - } - } else { - format = 'YYYY-MM'; - const months = Math.ceil(diffDays / 30); - for (let i = 0; i < months; i++) { - const monthStart = startDate.add(i, 'month').startOf('month'); - intervals.push(monthStart); - } + for (let i = 0; i < count; i++) { + const hue = ((i * hueStep) + offset) % 360; + // 使用固定的饱和度和亮度,确保颜色鲜明且不相近 + const color = `hsl(${hue}, 80%, 66%)`; + colors.push(color); } - const timeLabels = intervals.map(date => { - if (diffDays <= 14) { - return date.format(format); - } else if (diffDays <= 90) { - return `${date.format(format)}至${date.add(6, 'day').format(format)}`; - } else { - return date.format(format); - } - }); - - // 统计每个网系类型在每个时间段的故障数 - const networkNames = networkTypeTerms.map(type => type.name); - const seriesData = networkNames.map(name => ({ - name, - type: 'bar', - data: new Array(intervals.length).fill(0) - })); - - devices.forEach(device => { - const deviceTerms = getDeviceTerms(device); - const networkName = deviceTerms.networkType; - const networkIndex = networkNames.indexOf(networkName); - - if (networkIndex !== -1) { - const createDate = dayjs(device.createdAt); - - for (let i = 0; i < intervals.length; i++) { - if (diffDays <= 14) { - if (createDate.format('YYYY-MM-DD') === intervals[i].format('YYYY-MM-DD')) { - seriesData[networkIndex].data[i]++; - } - } else if (diffDays <= 90) { - const weekEnd = intervals[i].add(6, 'day').endOf('day'); - if (createDate.isAfter(intervals[i]) && createDate.isBefore(weekEnd)) { - seriesData[networkIndex].data[i]++; - } - } else { - const monthEnd = intervals[i].endOf('month'); - if (createDate.isAfter(intervals[i]) && createDate.isBefore(monthEnd)) { - seriesData[networkIndex].data[i]++; - } - } - } - } - }); - - return { - xAxis: timeLabels, - series: seriesData - }; + return colors; }; - // 准备三层分类统计数据 + // 为网系类型生成一致的颜色映射(保持不变,用于网系类型图表间的一致性) + const getNetworkTypeColors = () => { + if (!networkTypeTerms || networkTypeTerms.length === 0) return {}; + + const colors = generateDiverseColors(networkTypeTerms.length, 0); // 网系类型从0度开始 + const colorMap = {}; + + networkTypeTerms.forEach((type, index) => { + colorMap[type.name] = colors[index]; + }); + + return colorMap; + }; + + // 修改准备三层分类统计数据函数 const prepareHierarchicalFaultData = () => { if (!devices || !networkTypeTerms || networkTypeTerms.length === 0) { return { names: [], values: [] }; @@ -243,6 +187,7 @@ const DashboardPage = () => { const hierarchicalCounts = {}; const totalDevices = devices.length; + const networkColors = getNetworkTypeColors(); // 使用一致的网系类型颜色 // 初始化网系类型计数 networkTypeTerms.forEach(type => { @@ -261,13 +206,16 @@ const DashboardPage = () => { const names = Object.keys(hierarchicalCounts); const values = names.map(name => ({ value: totalDevices ? ((hierarchicalCounts[name] / totalDevices) * 100).toFixed(2) : 0, - name + name, + itemStyle: { + color: networkColors[name] + } })); return { names, values }; }; - // 修改系统类型分布数据(基于选中的网系类型,支持交互) + // 修改系统类型分布数据(使用不同的颜色偏移) const prepareGroupedSystemTypeDistribution = () => { if (!devices || !systemTypeTerms || !networkTypeTerms || systemTypeTerms.length === 0 || networkTypeTerms.length === 0) { @@ -325,7 +273,7 @@ const DashboardPage = () => { } }); - // 构建分组数据 + // 构建分组数据 - 为系统类型使用不同的颜色偏移 const values: Array<{ value: number; name: string; @@ -333,18 +281,23 @@ const DashboardPage = () => { itemStyle: { color: string }; }> = []; - // 为每个网系定义色系 - const networkColors: Record = { - '安全网络': ['#FF6B6B', '#FF8E8E', '#FFB1B1', '#FFD4D4'], - '办公网络': ['#4ECDC4', '#7ED7D2', '#AEE2E0', '#DFEEED'], - '生产网络': ['#45B7D1', '#6BC5D9', '#91D3E1', '#B7E1E9'], - '未分类': ['#96CEB4', '#B2D8C3', '#CDE2D2', '#E8EDE1'] - }; - + // 收集所有有数据的系统类型 + const allSystemTypes = []; Object.entries(networkGroups).forEach(([networkName, systemTypeDisplayNames]) => { - const colors = networkColors[networkName] || ['#DDA0DD', '#E6B3E6', '#F0C6F0', '#F9E9F9']; + systemTypeDisplayNames.forEach((displayName) => { + const count = systemTypeCounts[displayName]; + if (count > 0) { + allSystemTypes.push(displayName); + } + }); + }); - systemTypeDisplayNames.forEach((displayName, index) => { + // 为系统类型生成多样化颜色(使用120度偏移,避免与网系类型颜色重叠) + const systemColors = generateDiverseColors(allSystemTypes.length, 120); + + let colorIndex = 0; + Object.entries(networkGroups).forEach(([networkName, systemTypeDisplayNames]) => { + systemTypeDisplayNames.forEach((displayName) => { const count = systemTypeCounts[displayName]; if (count > 0) { values.push({ @@ -352,9 +305,10 @@ const DashboardPage = () => { name: displayName, networkType: networkName, itemStyle: { - color: colors[index % colors.length] + color: systemColors[colorIndex] } }); + colorIndex++; } }); }); @@ -362,7 +316,95 @@ const DashboardPage = () => { return { groups: networkGroups, values }; }; - // 新增:故障类型分布数据(基于选中的系统类型) + // 修改网系类型故障时间分布数据,使用一致的颜色 + const prepareNetworkFaultsByTimeData = () => { + if (!devices || !networkTypeTerms) return { xAxis: [], series: [] }; + + const startDate = dateRange[0]; + const endDate = dateRange[1]; + const diffDays = endDate.diff(startDate, 'day'); + + // 时间间隔逻辑 + const intervals = []; + let format = ''; + + if (diffDays <= 14) { + format = 'MM-DD'; + for (let i = 0; i <= diffDays; i++) { + intervals.push(startDate.add(i, 'day')); + } + } else if (diffDays <= 90) { + format = 'MM-DD'; + const weeks = Math.ceil(diffDays / 7); + for (let i = 0; i < weeks; i++) { + const weekStart = startDate.add(i * 7, 'day'); + intervals.push(weekStart); + } + } else { + format = 'YYYY-MM'; + const months = Math.ceil(diffDays / 30); + for (let i = 0; i < months; i++) { + const monthStart = startDate.add(i, 'month').startOf('month'); + intervals.push(monthStart); + } + } + + const timeLabels = intervals.map(date => { + if (diffDays <= 14) { + return date.format(format); + } else if (diffDays <= 90) { + return `${date.format(format)}至${date.add(6, 'day').format(format)}`; + } else { + return date.format(format); + } + }); + + // 统计每个网系类型在每个时间段的故障数 + const networkNames = networkTypeTerms.map(type => type.name); + const networkColors = getNetworkTypeColors(); // 使用与饼图一致的网系类型颜色 + + const seriesData = networkNames.map(name => ({ + name, + type: 'bar', + data: new Array(intervals.length).fill(0), + color: networkColors[name] // 使用一致的网系类型颜色 + })); + + devices.forEach(device => { + const deviceTerms = getDeviceTerms(device); + const networkName = deviceTerms.networkType; + const networkIndex = networkNames.indexOf(networkName); + + if (networkIndex !== -1) { + const createDate = dayjs(device.createdAt); + + for (let i = 0; i < intervals.length; i++) { + if (diffDays <= 14) { + if (createDate.format('YYYY-MM-DD') === intervals[i].format('YYYY-MM-DD')) { + seriesData[networkIndex].data[i]++; + } + } else if (diffDays <= 90) { + const weekEnd = intervals[i].add(6, 'day').endOf('day'); + if (createDate.isAfter(intervals[i]) && createDate.isBefore(weekEnd)) { + seriesData[networkIndex].data[i]++; + } + } else { + const monthEnd = intervals[i].endOf('month'); + if (createDate.isAfter(intervals[i]) && createDate.isBefore(monthEnd)) { + seriesData[networkIndex].data[i]++; + } + } + } + } + }); + + return { + xAxis: timeLabels, + series: seriesData + }; + }; + + // 修改故障类型分布数据,使用另一个颜色偏移 const prepareDeviceTypeDistribution = () => { if (!devices || !deviceTypeTerms || !systemTypeTerms || !selectedSystemType) return { names: [], values: [] }; @@ -388,12 +430,20 @@ const DashboardPage = () => { }); const names = Object.keys(deviceCounts); - const values = names.map(name => ({ - value: deviceCounts[name], - name - })).filter(item => item.value > 0); + const validNames = names.filter(name => deviceCounts[name] > 0); - return { names, values }; + // 为故障类型使用240度偏移,与网系类型和系统类型都不重叠 + const deviceColors = generateDiverseColors(validNames.length, 240); + + const values = validNames.map((name, index) => ({ + value: deviceCounts[name], + name, + itemStyle: { + color: deviceColors[index] + } + })); + + return { names: validNames, values }; }; // 准备故障处置完成率数据 @@ -781,8 +831,8 @@ const DashboardPage = () => { }; return ( -
-

故障数据可视化面板

+
+ {/*

故障数据可视化面板

*/} @@ -810,7 +860,7 @@ const DashboardPage = () => { @@ -818,7 +868,7 @@ const DashboardPage = () => { { { @@ -850,7 +900,7 @@ const DashboardPage = () => { diff --git a/apps/web/src/app/main/devicepage/devicemodal/page.tsx b/apps/web/src/app/main/devicepage/devicemodal/page.tsx index cf75ea0..c41a921 100755 --- a/apps/web/src/app/main/devicepage/devicemodal/page.tsx +++ b/apps/web/src/app/main/devicepage/devicemodal/page.tsx @@ -205,7 +205,7 @@ export default function DeviceModal() { onCancel={handleCancel} width={1000} style={{ top: 20 }} - bodyStyle={{ maxHeight: "calc(100vh - 200px)", overflowY: "auto" }} + bodyStyle={{ maxHeight: "calc(100vh - 200px)", overflowY: "auto",overflowX: "hidden" }} >
@@ -236,6 +236,7 @@ export default function DeviceModal() { value={selectedDeviceType} onChange={setSelectedDeviceType} systemTypeId={selectedSystemType} + disabled={!selectedSystemType} // 没有选择系统类型时禁用 /> diff --git a/apps/web/src/app/main/devicepage/page.tsx b/apps/web/src/app/main/devicepage/page.tsx index 90c2ad2..7443da9 100755 --- a/apps/web/src/app/main/devicepage/page.tsx +++ b/apps/web/src/app/main/devicepage/page.tsx @@ -37,6 +37,7 @@ import { import DepartmentSelect from "@web/src/components/models/department/department-select"; import SystemTypeSelect from "@web/src/app/main/devicepage/select/System-select"; import DeviceTypeSelect from "@web/src/app/main/devicepage/select/Device-select"; +import NetworkTypeSelect from "@web/src/app/main/devicepage/select/Network-type-select"; import dayjs from "dayjs"; import FixTypeSelect from "./select/Fix-select"; import { api } from "@nice/client"; @@ -580,7 +581,7 @@ export default function DeviceMessage() { ]; return ( -
+
{/* 页面标题区域 */}
@@ -640,7 +641,7 @@ export default function DeviceMessage() { - + />
diff --git a/apps/web/src/app/main/devicepage/select/Device-manager.tsx b/apps/web/src/app/main/devicepage/select/Device-manager.tsx index 21a499b..fb8ab41 100755 --- a/apps/web/src/app/main/devicepage/select/Device-manager.tsx +++ b/apps/web/src/app/main/devicepage/select/Device-manager.tsx @@ -663,7 +663,7 @@ export default function DeviceManager({ title }: TermManagerProps) { }; return ( -
+
{/* 主要内容卡片 */} {/* 统计信息区域 */} diff --git a/apps/web/src/app/main/layout/MainFooter.tsx b/apps/web/src/app/main/layout/MainFooter.tsx index c2569b7..74f9d3b 100755 --- a/apps/web/src/app/main/layout/MainFooter.tsx +++ b/apps/web/src/app/main/layout/MainFooter.tsx @@ -8,26 +8,26 @@ import { export function MainFooter() { return ( -