unis_sip/oms_web/docs/components/InfoPanel.md

9.2 KiB
Raw Blame History

InfoPanel 组件

组件说明

信息展示面板组件,用于以网格布局展示数据的字段信息,支持自定义字段渲染和操作按钮。常用于详情页面或抽屉中展示结构化数据。

组件位置

src/components/InfoPanel/InfoPanel.jsx
src/components/InfoPanel/InfoPanel.css

参数说明

参数名 类型 必填 默认值 说明
data Object - 数据源对象
fields Array [] 字段配置数组
actions Array [] 操作按钮配置数组
gutter Array [24, 16] Grid 网格间距 [水平, 垂直]

FieldConfig 配置项

属性名 类型 必填 说明
key string 数据字段名
label string 字段显示标签
span number 网格占位份数24栅格系统默认 6
render function(value, data) 自定义渲染函数

ActionConfig 配置项

属性名 类型 必填 说明
key string 按钮唯一标识
label string 按钮文本
icon ReactNode 按钮图标
type string 按钮类型primary/default/dashed/text/link
danger boolean 是否为危险按钮
disabled boolean 是否禁用
onClick function 点击回调函数

使用示例

基础用法

import InfoPanel from '../components/InfoPanel/InfoPanel'

function UserDetail() {
  const userData = {
    userName: 'admin',
    name: '系统管理员',
    group: '管理员组',
    userType: '管理员',
    status: 'enabled',
    grantedTerminals: 8,
    grantedImages: 21,
  }

  const userFields = [
    { key: 'userName', label: '用户名', span: 6 },
    { key: 'name', label: '姓名', span: 6 },
    { key: 'group', label: '用户分组', span: 6 },
    { key: 'userType', label: '用户类型', span: 6 },
    { key: 'grantedTerminals', label: '授权终端', span: 6 },
    { key: 'grantedImages', label: '授权镜像', span: 6 },
  ]

  return <InfoPanel data={userData} fields={userFields} />
}

自定义字段渲染

import { Tag } from 'antd'

const userFields = [
  { key: 'userName', label: '用户名', span: 6 },
  { key: 'name', label: '姓名', span: 6 },
  {
    key: 'status',
    label: '状态',
    span: 6,
    render: (value) => (
      <Tag color={value === 'enabled' ? 'green' : 'default'}>
        {value === 'enabled' ? '启用' : '停用'}
      </Tag>
    ),
  },
  {
    key: 'description',
    label: '描述',
    span: 18,
    render: (value) => value || '--',  // 空值显示默认占位符
  },
]

<InfoPanel data={userData} fields={userFields} />

带操作按钮

import { LockOutlined } from '@ant-design/icons'

<InfoPanel
  data={userData}
  fields={userFields}
  actions={[
    {
      key: 'move',
      label: '转移分组',
      type: 'primary',
      onClick: () => console.log('转移分组'),
    },
    {
      key: 'blacklist',
      label: '加入黑名单',
      onClick: () => console.log('加入黑名单'),
    },
    {
      key: 'reset',
      label: '重置密码',
      onClick: () => console.log('重置密码'),
    },
    {
      key: 'disable',
      label: '停用',
      icon: <LockOutlined />,
      onClick: () => console.log('停用'),
    },
  ]}
/>

配合 DetailDrawer 使用

import DetailDrawer from '../components/DetailDrawer/DetailDrawer'
import InfoPanel from '../components/InfoPanel/InfoPanel'
import { Tag } from 'antd'

function UserListPage() {
  const [showDetailDrawer, setShowDetailDrawer] = useState(false)
  const [selectedUser, setSelectedUser] = useState(null)

  const userFields = [
    { key: 'userName', label: '用户名', span: 6 },
    { key: 'group', label: '用户分组', span: 6 },
    { key: 'name', label: '姓名', span: 6 },
    { key: 'grantedImages', label: '授权镜像', span: 6 },
    { key: 'userType', label: '用户类型', span: 6 },
    { key: 'grantedTerminals', label: '授权终端', span: 6 },
    {
      key: 'status',
      label: '启停用',
      span: 6,
      render: (value) => (
        <Tag color={value === 'enabled' ? 'green' : 'default'}>
          {value === 'enabled' ? '启用' : '停用'}
        </Tag>
      ),
    },
    { key: 'description', label: '描述', span: 18, render: () => '--' },
  ]

  return (
    <DetailDrawer
      visible={showDetailDrawer}
      onClose={() => setShowDetailDrawer(false)}
      title={{
        text: selectedUser?.userName || '',
      }}
    >
      <InfoPanel
        data={selectedUser}
        fields={userFields}
        actions={[
          { key: 'move', label: '转移分组', type: 'primary', onClick: () => console.log('转移分组') },
          { key: 'blacklist', label: '加入黑名单', onClick: () => console.log('加入黑名单') },
          { key: 'reset', label: '重置密码', onClick: () => console.log('重置密码') },
          { key: 'disable', label: '停用', onClick: () => console.log('停用') },
        ]}
      />
    </DetailDrawer>
  )
}

不同 span 值的布局

// 24栅格系统一行总共24份
const fields = [
  { key: 'field1', label: '字段1', span: 6 },   // 占1/4宽度
  { key: 'field2', label: '字段2', span: 6 },   // 占1/4宽度
  { key: 'field3', label: '字段3', span: 6 },   // 占1/4宽度
  { key: 'field4', label: '字段4', span: 6 },   // 占1/4宽度满一行
  { key: 'field5', label: '字段5', span: 8 },   // 占1/3宽度
  { key: 'field6', label: '字段6', span: 8 },   // 占1/3宽度
  { key: 'field7', label: '字段7', span: 8 },   // 占1/3宽度满一行
  { key: 'field8', label: '字段8', span: 12 },  // 占1/2宽度
  { key: 'field9', label: '字段9', span: 12 },  // 占1/2宽度满一行
  { key: 'description', label: '描述', span: 24 },  // 占满整行
]

<InfoPanel data={data} fields={fields} />

访问完整数据对象

const fields = [
  { key: 'userName', label: '用户名', span: 6 },
  {
    key: 'status',
    label: '状态信息',
    span: 18,
    // render 函数的第二个参数是完整的数据对象
    render: (value, data) => (
      <div>
        <Tag color={value === 'enabled' ? 'green' : 'default'}>
          {value === 'enabled' ? '启用' : '停用'}
        </Tag>
        <span style={{ marginLeft: 8 }}>
          授权终端{data.grantedTerminals} 
        </span>
      </div>
    ),
  },
]

<InfoPanel data={userData} fields={fields} />

自定义网格间距

// 默认间距 [24, 16]
<InfoPanel
  data={userData}
  fields={userFields}
  gutter={[32, 24]}  // 更大的间距
/>

// 紧凑布局
<InfoPanel
  data={userData}
  fields={userFields}
  gutter={[16, 12]}  // 更小的间距
/>

布局说明

组件使用 Ant Design 的 24 栅格系统:

┌─────────────────────────────────────────────────┐
│  span=6    span=6    span=6    span=6          │  一行4列
├─────────────────────────────────────────────────┤
│  span=8         span=8         span=8          │  一行3列
├─────────────────────────────────────────────────┤
│  span=12                span=12                │  一行2列
├─────────────────────────────────────────────────┤
│  span=24                                       │  占满一行
└─────────────────────────────────────────────────┘

常用 span 值:

  • span=6 - 一行 4 列
  • span=8 - 一行 3 列
  • span=12 - 一行 2 列
  • span=24 - 占满整行(适合描述、备注等长文本字段)

样式定制

组件提供以下 CSS 类名供自定义样式:

  • .info-panel - 组件根容器
  • .info-panel-item - 单个字段容器
  • .info-panel-label - 字段标签
  • .info-panel-value - 字段值
  • .info-panel-actions - 操作按钮区域

使用场景

  1. 详情页信息展示 - 在详情抽屉或页面中展示对象的属性信息
  2. 用户信息展示 - 展示用户的基本信息和状态
  3. 设备信息展示 - 展示设备的配置和参数
  4. 订单信息展示 - 展示订单的详细信息
  5. 任何结构化数据展示 - 以标签-值形式展示的数据

注意事项

  1. datanullundefined 时组件不渲染任何内容
  2. 字段 span 值总和建议为 24 的倍数以保持布局整齐
  3. 长文本字段(如描述、备注)建议使用 span=24span=18
  4. render 函数可以返回任何 React 节点包括组件、文本、HTML 等
  5. 操作按钮会显示在所有字段下方,建议不超过 6 个按钮
  6. 使用 render 函数时,第一个参数是字段值,第二个参数是完整数据对象
  7. 网格间距 gutter 的第一个值是水平间距,第二个值是垂直间距