重新设计属性面板,为 demand 提供二级表格显示更多信息

This commit is contained in:
JIANG
2025-11-14 11:34:36 +08:00
parent 4ddc32b282
commit dd93b37685
3 changed files with 147 additions and 16 deletions

View File

@@ -7,10 +7,20 @@ interface BaseProperty {
formatter?: (value: string | number) => string;
}
// 新增:表格型属性(用于二级数据)
interface TableProperty {
type: "table";
label: string;
columns: string[]; // 表头
rows: (string | number)[][]; // 每行的数据
}
type PropertyItem = BaseProperty | TableProperty;
interface PropertyPanelProps {
id?: string;
type?: string;
properties?: BaseProperty[];
properties?: PropertyItem[];
}
const PropertyPanel: React.FC<PropertyPanelProps> = ({
@@ -30,8 +40,17 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
const isImportantKeys = ["ID", "类型", "Name", "面积", "长度"];
// 统计属性数量(表格型按行数计入)
const totalProps = id
? 2 +
properties.reduce((sum, p) => {
if ("type" in p && p.type === "table") return sum + p.rows.length;
return sum + 1;
}, 0)
: 0;
return (
<div className="absolute top-4 right-4 bg-white shadow-2xl rounded-xl overflow-hidden w-96 z-10 max-h-[850px] flex flex-col backdrop-blur-sm opacity-95 hover:opacity-100 transition-all duration-300">
<div className="absolute top-4 right-4 bg-white shadow-2xl rounded-xl overflow-hidden w-96 z-10 max-h[850px] flex flex-col backdrop-blur-sm opacity-95 hover:opacity-100 transition-all duration-300">
{/* 头部 */}
<div className="flex justify-between items-center px-5 py-4 bg-[#257DD4] text-white">
<div className="flex items-center gap-2">
@@ -98,12 +117,60 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
</div>
</div>
{/* 其他属性 */}
{/* 其他属性(包含二级表格) */}
{properties.map((property, index) => {
const isImportant = isImportantKeys.includes(property.label);
// 二级表格
if ("type" in property && property.type === "table") {
return (
<div
key={`table-${index}`}
className="group rounded-lg p-3 transition-all duration-200 bg-gray-50 hover:bg-gray-100"
>
<div className="flex justify-between items-start gap-3">
<span className="font-medium text-xs uppercase tracking-wide text-gray-600">
{property.label}
</span>
</div>
<div className="ml-4 mt-2 border border-gray-300 rounded-md overflow-hidden shadow-sm">
<table className="w-full text-xs">
<thead className="bg-gray-200 text-gray-700">
<tr>
{property.columns.map((col, ci) => (
<th
key={ci}
className="px-3 py-2 text-left font-semibold"
>
{col}
</th>
))}
</tr>
</thead>
<tbody className="divide-y divide-gray-300">
{property.rows.map((row, ri) => (
<tr key={ri} className="bg-white hover:bg-gray-50">
{row.map((cell, cci) => (
<td
key={cci}
className="px-3 py-2 text-gray-800"
>
{cell}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}
// 普通属性
const base = property as BaseProperty;
const isImportant = isImportantKeys.includes(base.label);
return (
<div
key={index}
key={`prop-${index}`}
className={`group rounded-lg p-3 transition-all duration-200 ${
isImportant
? "bg-blue-50 hover:bg-blue-100 border-l-4 border-blue-500"
@@ -116,14 +183,14 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
isImportant ? "text-blue-700" : "text-gray-600"
}`}
>
{property.label}
{base.label}
</span>
<span
className={`text-sm font-semibold text-right flex-1 ${
isImportant ? "text-blue-900" : "text-gray-800"
}`}
>
{formatValue(property)}
{formatValue(base)}
</span>
</div>
</div>
@@ -150,7 +217,7 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
/>
</svg>
{id ? properties.length + 2 : 0}
{totalProps}
</span>
{id && (
<span className="text-green-600 flex items-center gap-1 font-medium">