From e4dfe9f17d64d016376872b786d2987805ee41ef Mon Sep 17 00:00:00 2001
From: shimai <shimai@example.com>
Date: Fri, 03 Apr 2026 11:12:14 +0800
Subject: [PATCH] Merge branch 'test/tony.cheng/260312' of http://120.79.193.119:9090/r/~chengmw/cloud-melody-front into test/shimai.huang/260309
---
web-app/src/components/common/AppHeader.jsx | 124 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 124 insertions(+), 0 deletions(-)
diff --git a/web-app/src/components/common/AppHeader.jsx b/web-app/src/components/common/AppHeader.jsx
new file mode 100644
index 0000000..d0fe896
--- /dev/null
+++ b/web-app/src/components/common/AppHeader.jsx
@@ -0,0 +1,124 @@
+/**
+ * AppHeader 组件 - 蓝色顶部导航栏
+ * 包含系统名称、通知图标、调解员信息
+ */
+
+import React, { useState, useCallback } from 'react';
+import { Badge, Popover, List, Avatar } from 'antd';
+import { BellOutlined, UserOutlined } from '@ant-design/icons';
+import { getMergedParams } from '../../utils/urlParams';
+import './AppHeader.css';
+
+// 默认头像
+const DEFAULT_AVATAR = '/app_logo.png';
+
+/**
+ * 从URL参数获取调解员信息
+ */
+const getMediatorInfo = () => {
+ const params = getMergedParams();
+ return {
+ trueName: params.trueName || '调解员',
+ unit: params.unit || '',
+ roleName: params.roleName || '管理员',
+ avatar: params.avatar || ''
+ };
+};
+
+/**
+ * 通知列表组件
+ */
+const NotificationList = ({ notifications, onClose }) => {
+ if (!notifications?.length) {
+ return (
+ <div className="notification-empty">
+ <span>暂无新通知</span>
+ </div>
+ );
+ }
+
+ return (
+ <List
+ className="notification-list"
+ dataSource={notifications}
+ renderItem={(item) => (
+ <List.Item className="notification-item">
+ <div className="notification-content">
+ <span className="notification-text">{item.content || item.title}</span>
+ <span className="notification-time">{item.create_time || item.time}</span>
+ </div>
+ </List.Item>
+ )}
+ />
+ );
+};
+
+/**
+ * AppHeader 主组件
+ */
+const AppHeader = ({ notifications = [] }) => {
+ const [popoverVisible, setPopoverVisible] = useState(false);
+ const mediatorInfo = getMediatorInfo();
+
+ // 处理Popover显示状态
+ const handlePopoverChange = useCallback((visible) => {
+ setPopoverVisible(visible);
+ }, []);
+
+ // 渲染通知图标和气泡
+ const renderNotificationIcon = () => (
+ <Badge count={notifications.length} offset={[-2, 2]} size="small">
+ <BellOutlined className="header-bell-icon" />
+ </Badge>
+ );
+
+ // 渲染调解员信息
+ const renderMediatorInfo = () => (
+ <div className="header-mediator">
+ <Avatar
+ src={mediatorInfo.avatar || DEFAULT_AVATAR}
+ icon={!mediatorInfo.avatar && <UserOutlined />}
+ className="mediator-avatar"
+ />
+ <div className="mediator-details">
+ <span className="mediator-name">{mediatorInfo.trueName}</span>
+ <span className="mediator-role">
+ {mediatorInfo.unit && `${mediatorInfo.unit} | `}{mediatorInfo.roleName}
+ </span>
+ </div>
+ <span className="mediator-status-dot" />
+ </div>
+ );
+
+ return (
+ <header className="app-header">
+ {/* 左侧:系统名称 */}
+ <div className="header-left">
+ <span className="header-title">矛盾纠纷应用</span>
+ </div>
+
+ {/* 右侧:通知+调解员信息 */}
+ <div className="header-right">
+ {/* 通知图标 */}
+ <Popover
+ content={<NotificationList notifications={notifications} />}
+ title="系统通知"
+ trigger="click"
+ open={popoverVisible}
+ onOpenChange={handlePopoverChange}
+ placement="bottomRight"
+ overlayClassName="notification-popover"
+ >
+ <div className="header-notification">
+ {renderNotificationIcon()}
+ </div>
+ </Popover>
+
+ {/* 调解员信息 */}
+ {renderMediatorInfo()}
+ </div>
+ </header>
+ );
+};
+
+export default AppHeader;
--
Gitblit v1.8.0