From 88a31d5a960bd10f3799bc00f8aa24461567d06e Mon Sep 17 00:00:00 2001
From: shimai <shimai@example.com>
Date: Tue, 07 Apr 2026 15:23:43 +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 |  138 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 138 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..cff2c45
--- /dev/null
+++ b/web-app/src/components/common/AppHeader.jsx
@@ -0,0 +1,138 @@
+/**
+ * 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();
+  const userInfo = {
+    userId: params.userId || '',
+    roleId: params.roleId || '',
+    auth_token: params.auth_token || '',
+    unitType: params.unitType || '',
+    trueName: params.trueName ? decodeURIComponent(params.trueName) : '调解员',
+    unit: params.unit ? decodeURIComponent(params.unit) : '',
+    unitRegion: params.unitRegion ? decodeURIComponent(params.unitRegion) : '',
+    roleName: params.roleName ? decodeURIComponent(params.roleName) : '管理员',
+    avatar: params.avatar || ''
+  };
+
+  // 存储到 localStorage
+  try {
+    localStorage.setItem('userInfo', JSON.stringify(userInfo));
+  } catch (error) {
+    console.error('Failed to save userInfo to localStorage:', error);
+  }
+
+  return userInfo;
+};
+
+/**
+ * 通知列表组件
+ */
+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