更新二维矩阵里的首列字段展示

This commit is contained in:
wmp
2025-10-14 14:32:25 +08:00
parent 6e9e7af780
commit 10395a49c1

View File

@@ -15,8 +15,7 @@ function GatewayConfigContent() {
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [infoData, setInfoData] = useState<GatewayInfo[]>([]) const [infoData, setInfoData] = useState<GatewayInfo[]>([])
const [totalCount, setTotalCount] = useState(0) const [totalCount, setTotalCount] = useState(0)
const [matrixData, setMatrixData] = useState<{ city: string, devices: { [macaddr: string]: GatewayConfig[] } }[]>([]) const [matrixData, setMatrixData] = useState<{ inner_ip: string, devices: { [macaddr: string]: GatewayConfig[] } }[]>([])
const [cities, setCities] = useState<string[]>([])
const [macAddresses, setMacAddresses] = useState<string[]>([]) const [macAddresses, setMacAddresses] = useState<string[]>([])
const [currentTotal, setCurrentTotal] = useState(0) const [currentTotal, setCurrentTotal] = useState(0)
// 缓存处理先保存初始MAC地址列表 // 缓存处理先保存初始MAC地址列表
@@ -161,51 +160,51 @@ function GatewayConfigContent() {
}) })
} }
const cityMinPortMap: { [city: string]: number } = {} const allPortLines = Array.from(
Object.values(macConfigMap).forEach((configs) => {
configs.forEach((config) => {
const city = config.city
if (!city) return // 跳过无城市的配置
const currentPortLastOctet = getLastOctet(config.inner_ip)
if (!cityMinPortMap[city] || currentPortLastOctet < cityMinPortMap[city]) {
cityMinPortMap[city] = currentPortLastOctet
}
})
})
// 获取所有唯一的城市
const allCities = Array.from(
new Set( new Set(
Object.values(macConfigMap) Object.values(macConfigMap)
.flat() .flat()
.map(item => item.city) .map(item => item.inner_ip)// 获取端口和线路
.filter(Boolean), .filter(Boolean),
), ),
).sort((cityA, cityB) => { )
const portA = cityMinPortMap[cityA!] || 0 const portLineConfigMap: { [key: string]: GatewayConfig } = {}
const portB = cityMinPortMap[cityB!] || 0 Object.values(macConfigMap).forEach((configs) => {
configs.forEach((config) => {
const key = config.inner_ip
if (!portLineConfigMap[key]) {
portLineConfigMap[key] = config
}
})
})
// 按端口号排序
const sortedPortLines = allPortLines.sort((a, b) => {
const portA = getLastOctet(a.split('|')[0])
const portB = getLastOctet(b.split('|')[0])
return portA - portB return portA - portB
}) as string[] })
// 构建矩阵数据 // 构建矩阵数据
const matrix = allCities.map((city) => { const matrix = sortedPortLines.map((portLine) => {
const [inner_ip] = portLine.split('|')
const config = portLineConfigMap[portLine]
const row = { const row = {
city, inner_ip: inner_ip || '',
devices: {} as { [macaddr: string]: GatewayConfig[] }, devices: {} as { [macaddr: string]: GatewayConfig[] },
} }
// 为每个MAC地址填充该城市的配置数据 // 为每个MAC地址填充该城市的配置数据
macList.forEach((mac) => { macList.forEach((mac) => {
const configsForCity = macConfigMap[mac] const configsForPortLine = macConfigMap[mac]
.filter(item => item.city === city) .filter(item => item.inner_ip === inner_ip)
.sort(sortByInnerIp) .sort(sortByInnerIp)
row.devices[mac] = configsForCity row.devices[mac] = configsForPortLine
}) })
return row return row
}) })
setMatrixData(matrix) setMatrixData(matrix)
setCities(allCities)
setMacAddresses(macList) setMacAddresses(macList)
setCurrentTotal(matrix.length) setCurrentTotal(matrix.length)
@@ -228,6 +227,7 @@ function GatewayConfigContent() {
try { try {
// 获取网关基本信息 // 获取网关基本信息
const infoResult = await getGatewayInfo() const infoResult = await getGatewayInfo()
if (!infoResult.success) { if (!infoResult.success) {
throw new Error(infoResult.error || '查询网关信息失败') throw new Error(infoResult.error || '查询网关信息失败')
} }
@@ -429,13 +429,13 @@ function GatewayConfigContent() {
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow className="bg-gray-50"> <TableRow className="bg-gray-50">
<TableHead className="text-xs text-gray-500 uppercase tracking-wider sticky top-0 left-0 z-20 bg-gray-50 border-r min-w-[120px]"> <TableHead className="text-xs text-gray-500 bg-gray-50 uppercase tracking-wider sticky top-0 left-0 z-50 border-r min-w-[110px] shadow-md">
</TableHead> </TableHead>
{macAddresses.map((macaddr, index) => ( {macAddresses.map((macaddr, index) => (
<TableHead <TableHead
key={index} key={index}
className="text-xs text-gray-500 uppercase tracking-wider sticky top-0 text-center min-w-[200px]" className="text-xs text-gray-500 uppercase tracking-wider sticky top-0 z-30 bg-gray-50 text-center min-w-[110px] border-r"
> >
{macaddr} {macaddr}
</TableHead> </TableHead>
@@ -444,18 +444,19 @@ function GatewayConfigContent() {
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{matrixData.map((row, rowIndex) => ( {matrixData.map((row, rowIndex) => (
<TableRow key={rowIndex}> <TableRow key={rowIndex} className="border-b">
<TableCell className="px-4 py-2 font-medium sticky left-0 bg-inherit z-10 border-r"> <TableCell className="px-4 py-2 font-medium sticky left-0 z-40 border-r bg-white shadow-[2px_0_0_0_rgba(0,0,0,0.1)] min-w-[110px]">
{row.city} <div className="flex justify-between items-center">
<span className="text-sm font-medium">{row.inner_ip || 'N/A'}</span>
</div>
</TableCell> </TableCell>
{macAddresses.map((macaddr, colIndex) => { {macAddresses.map((macaddr, colIndex) => {
const configs = row.devices[macaddr] || [] const configs = row.devices[macaddr] || []
if (configs.length === 0) { if (configs.length === 0) {
return ( return (
<TableCell <TableCell
key={`${rowIndex}-${colIndex}`} key={`${rowIndex}-${colIndex}`}
className="px-2 py-3 text-center min-w-[180px]" className="px-2 py-3 text-center min-w-[110px] border-r"
> >
<div className="text-gray-400 text-sm py-6">-</div> <div className="text-gray-400 text-sm py-6">-</div>
</TableCell> </TableCell>
@@ -465,7 +466,8 @@ function GatewayConfigContent() {
return ( return (
<TableCell <TableCell
key={`${rowIndex}-${colIndex}`} key={`${rowIndex}-${colIndex}`}
className="p-2 min-w-[180px]" // className="p-2 min-w-[110px] border-r text-center hover:bg-blue-50"
className="px-2 py-3 text-center min-w-[110px] border-r"
> >
<div className="space-y-2"> <div className="space-y-2">
{configs.map((item, itemIndex) => { {configs.map((item, itemIndex) => {
@@ -479,13 +481,12 @@ function GatewayConfigContent() {
} }
return ( return (
<div key={itemIndex} className="flex flex-col gap-1"> <div key={itemIndex} className="flex flex-col gap-1 transition-shadow">
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<span className="text-sm font-medium">{item.public || 'N/A'}</span> <span className="text-sm font-medium">{item.public || 'N/A'}</span>
</div> </div>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<span className="text-xs font-medium">{item.user || 'N/A'}</span> <span className="text-xs font-medium">{item.city || 'N/A'}</span>
<span className="text-xs font-medium">{item.inner_ip || 'N/A'}</span>
</div> </div>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<span className={`px-2 py-0.5 rounded text-xs font-medium ${statusConfig.ischange.bg} ${statusConfig.ischange.text}`}> <span className={`px-2 py-0.5 rounded text-xs font-medium ${statusConfig.ischange.bg} ${statusConfig.ischange.text}`}>