<template>
  <!-- 与 4T 弹窗一致：透明遮罩、可拖动、记录位置、不阻挡地图 -->
  <div v-if="value" class="online-members-dialog">
    <div class="panel-container" :style="panelStyle">
      <div class="dialog-header" @mousedown="onDragStart">
        <h3>{{ $t('onlineMembersDialog.title') }}</h3>
        <div class="close-btn" @mousedown.stop @click="closeDialog">×</div>
      </div>
      
      <div class="dialog-body">
        <el-tabs v-model="activeTab" type="card" size="small">
          <el-tab-pane :label="$t('onlineMembersDialog.onlineMembers')" name="members">
            <div class="members-list">
              <div 
                v-for="member in displayOnlineMembers" 
                :key="member.id"
                class="member-item"
                :class="{ active: member.isEditing }"
              >
                <div class="member-avatar">
                  <el-avatar :size="36" :src="member.avatar">{{ member.name.charAt(0) }}</el-avatar>
                </div>
                <div class="member-info">
                  <div class="member-name">{{ member.name }}</div>
                  <div class="member-role">{{ member.role }}</div>
                </div>
                <div class="member-status">
                  <span class="status-dot online"></span>
                  <span class="status-text">{{ member.status }}</span>
                </div>
                <div v-if="member.isEditing" class="editing-badge">{{ $t('onlineMembersDialog.editing') }}</div>
              </div>
            </div>
          </el-tab-pane>
          
          <el-tab-pane :label="$t('onlineMembersDialog.currentOperation')" name="current">
            <div class="current-operation">
              <div class="operation-section">
                <h4>{{ $t('onlineMembersDialog.editStatus') }}</h4>
                <div class="status-item">
                  <span class="status-label">{{ $t('onlineMembersDialog.currentEditor') }}：</span>
                  <span class="status-value">{{ currentEditor || $t('onlineMembersDialog.none') }}</span>
                </div>
                <div class="status-item">
                  <span class="status-label">{{ $t('onlineMembersDialog.editingObject') }}：</span>
                  <span class="status-value">{{ editingObject || $t('onlineMembersDialog.none') }}</span>
                </div>
                <div class="status-item">
                  <span class="status-label">{{ $t('onlineMembersDialog.editingTime') }}：</span>
                  <span class="status-value">{{ editingTime || $t('onlineMembersDialog.none') }}</span>
                </div>
              </div>
              
              <div class="operation-section">
                <h4>{{ $t('onlineMembersDialog.selectStatus') }}</h4>
                <div class="status-item">
                  <span class="status-label">{{ $t('onlineMembersDialog.selectedObject') }}：</span>
                  <span class="status-value">{{ selectedObject || $t('onlineMembersDialog.none') }}</span>
                </div>
                <div class="status-item">
                  <span class="status-label">{{ $t('onlineMembersDialog.selectedCount') }}：</span>
                  <span class="status-value">{{ selectedCount }} {{ $t('onlineMembersDialog.unit') }}</span>
                </div>
              </div>
            </div>
          </el-tab-pane>
          
          <el-tab-pane :label="$t('onlineMembersDialog.operationLogs')" name="logs">
            <div class="operation-logs">
              <div class="logs-header">
                <h4>{{ $t('onlineMembersDialog.objectOperationLogs') }}</h4>
                <el-button 
                  type="warning" 
                  size="mini" 
                  @click="showRollbackConfirm"
                  :disabled="operationLogs.length === 0"
                >
                  <i class="el-icon-refresh-right"></i> {{ $t('onlineMembersDialog.rollbackOperation') }}
                </el-button>
              </div>
              <el-timeline>
                <el-timeline-item 
                  v-for="log in operationLogs" 
                  :key="log.id"
                  :timestamp="log.time"
                  :type="log.type"
                >
                  <div class="log-content">
                    <div class="log-user">{{ log.user }}</div>
                    <div class="log-action">{{ log.action }}</div>
                    <div class="log-object">{{ $t('onlineMembersDialog.objectOperationLogs') }}：{{ log.object }}</div>
                    <div class="log-detail">{{ log.detail }}</div>
                  </div>
                </el-timeline-item>
              </el-timeline>
              
              <el-dialog
                :title="$t('onlineMembersDialog.rollbackConfirm')"
                :visible.sync="showRollbackDialog"
                width="400px"
                center
                append-to-body
              >
                <div class="rollback-confirm">
                  <p>{{ $t('onlineMembersDialog.rollbackConfirmText') }}</p>
                  <p class="text-warning mt-2">{{ $t('onlineMembersDialog.rollbackWarning') }}</p>
                </div>
                <span slot="footer" class="dialog-footer">
                  <el-button @click="showRollbackDialog = false">{{ $t('leftMenu.cancel') }}</el-button>
                  <el-button type="primary" @click="rollbackOperation">{{ $t('onlineMembersDialog.confirmRollback') }}</el-button>
                </span>
              </el-dialog>
            </div>
          </el-tab-pane>
          
          <el-tab-pane :label="$t('onlineMembersDialog.chatRoom')" name="chat">
            <div class="chat-room">
              <div class="chat-header">
                <el-radio-group v-model="chatMode" size="mini">
                  <el-radio-button label="group">{{ $t('onlineMembersDialog.groupChat') }}</el-radio-button>
                  <el-radio-button label="private">{{ $t('onlineMembersDialog.privateChat') }}</el-radio-button>
                </el-radio-group>
                <span class="online-count">{{ displayOnlineMembers.length }} {{ $t('onlineMembersDialog.onlineCount') }}</span>
              </div>
              
              <!-- 私聊：选择对象 -->
              <div v-if="chatMode === 'private'" class="private-target">
                <span class="target-label">{{ $t('onlineMembersDialog.selectMember') }}：</span>
                <el-select v-model="privateChatTarget" :placeholder="$t('onlineMembersDialog.selectMemberToChat')" size="small" filterable class="target-select">
                  <el-option
                    v-for="m in chatableMembers"
                    :key="m.userId"
                    :label="m.name"
                    :value="m.userId"
                  >
                    <span>{{ m.name }}</span>
                    <span class="target-role">({{ m.role }})</span>
                  </el-option>
                </el-select>
              </div>
              
              <!-- 聊天内容区域 -->
              <div class="chat-content" ref="chatContent">
                <template v-if="chatMode === 'group'">
                  <div
                    v-for="(message, index) in displayChatMessages"
                    :key="'g-' + index"
                    :class="['chat-message', isMessageSelf(message) ? 'self-message' : 'other-message']"
                  >
                    <div class="message-avatar">
                      <el-avatar :size="32" :src="getMessageAvatar(message)">{{ getMessageSenderName(message).charAt(0) }}</el-avatar>
                    </div>
                    <div class="message-content">
                      <div class="message-sender">{{ getMessageSenderName(message) }}</div>
                      <div class="message-text">{{ message.content }}</div>
                      <div class="message-time">{{ formatMessageTime(message.timestamp) }}</div>
                    </div>
                  </div>
                </template>
                <template v-else-if="chatMode === 'private' && privateChatTarget">
                  <div
                    v-for="(message, index) in displayPrivateMessages"
                    :key="'p-' + index"
                    :class="['chat-message', isPrivateMessageSelf(message) ? 'self-message' : 'other-message']"
                  >
                    <div class="message-avatar">
                      <el-avatar :size="32" :src="getPrivateMessageAvatar(message)">{{ getPrivateMessageSenderName(message).charAt(0) }}</el-avatar>
                    </div>
                    <div class="message-content">
                      <div class="message-sender">{{ getPrivateMessageSenderName(message) }}</div>
                      <div class="message-text">{{ message.content }}</div>
                      <div class="message-time">{{ formatMessageTime(message.timestamp) }}</div>
                    </div>
                  </div>
                </template>
                <div v-else-if="chatMode === 'private' && !privateChatTarget" class="chat-empty">
                  {{ $t('onlineMembersDialog.selectMemberToChat') }}
                </div>
              </div>
              
              <!-- 聊天输入区域 -->
              <div class="chat-input">
                <el-input
                  v-model="newMessage"
                  :placeholder="chatMode === 'private' && !privateChatTarget ? $t('onlineMembersDialog.selectMemberFirst') : $t('onlineMembersDialog.inputMessage')"
                  :disabled="chatMode === 'private' && !privateChatTarget"
                  @keyup.enter="sendMessage"
                  clearable
                ></el-input>
                <el-button type="primary" @click="sendMessage" class="send-btn" :disabled="chatMode === 'private' && !privateChatTarget">{{ $t('onlineMembersDialog.send') }}</el-button>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
      <!-- 右下角拖拽调整大小 -->
      <div class="resize-handle" @mousedown="onResizeStart" title="拖动调整大小"></div>
    </div>
  </div>
</template>

<script>
const STORAGE_KEY_PREFIX = 'onlineMembersPanel_'

export default {
  name: 'OnlineMembersDialog',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    onlineMembers: {
      type: Array,
      default: () => []
    },
    roomId: {
      type: [String, Number],
      default: null
    },
    chatMessages: {
      type: Array,
      default: () => []
    },
    privateChatMessages: {
      type: Object,
      default: () => ({})
    },
    sendChat: {
      type: Function,
      default: null
    },
    sendPrivateChat: {
      type: Function,
      default: null
    },
    sendPrivateChatHistoryRequest: {
      type: Function,
      default: null
    },
    currentUserId: {
      type: [Number, String],
      default: null
    }
  },
  data() {
    return {
      activeTab: 'members',
      panelLeft: null,
      panelTop: null,
      panelWidth: 700,
      panelHeight: 520,
      isDragging: false,
      dragStartX: 0,
      dragStartY: 0,
      isResizing: false,
      resizeStartX: 0,
      resizeStartY: 0,
      resizeStartW: 0,
      resizeStartH: 0,
      showRollbackDialog: false,
      
      // 在线成员数据（当 props.onlineMembers 为空时使用 mock）
      _mockOnlineMembers: [
        { id: 1, name: '张三', role: '指挥官', status: '在线', isEditing: true, avatar: 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png' },
        { id: 2, name: '李四', role: '参谋', status: '在线', isEditing: false, avatar: 'https://cube.elemecdn.com/1/88/03b0d39583f48206768a7534e55bcpng.png' },
        { id: 3, name: '王五', role: '操作员', status: '在线', isEditing: false, avatar: 'https://cube.elemecdn.com/2/88/03b0d39583f48206768a7534e55bcpng.png' },
        { id: 4, name: '赵六', role: '观察员', status: '在线', isEditing: false, avatar: 'https://cube.elemecdn.com/3/88/03b0d39583f48206768a7534e55bcpng.png' },
        { id: 5, name: '孙七', role: '分析师', status: '在线', isEditing: false, avatar: 'https://cube.elemecdn.com/4/88/03b0d39583f48206768a7534e55bcpng.png' }
      ],
      
      // 当前操作状态
      currentEditor: '张三',
      editingObject: 'J-20 歼击机',
      editingTime: 'K+00:45:23',
      selectedObject: 'Alpha进场航线',
      selectedCount: 1,
      
      // 操作日志
      operationLogs: [
        { 
          id: 1, 
          user: '张三', 
          action: '修改', 
          object: 'J-20 歼击机', 
          detail: '更新了速度参数从800km/h到850km/h', 
          time: 'K+00:45:23', 
          type: 'success'
        },
        { 
          id: 2, 
          user: '李四', 
          action: '选择', 
          object: 'Alpha进场航线', 
          detail: '选中了Alpha进场航线进行编辑', 
          time: 'K+00:42:15', 
          type: 'primary'
        },
        { 
          id: 3, 
          user: '王五', 
          action: '添加', 
          object: 'WP5', 
          detail: '在Beta巡逻航线上添加了新航点WP5', 
          time: 'K+00:38:47', 
          type: 'info'
        },
        { 
          id: 4, 
          user: '赵六', 
          action: '删除', 
          object: '旧侦察航线', 
          detail: '删除了过期的侦察航线', 
          time: 'K+00:35:12', 
          type: 'warning'
        },
        { 
          id: 5, 
          user: '孙七', 
          action: '修改', 
          object: 'HQ-9防空系统', 
          detail: '更新了射程参数从120km到150km', 
          time: 'K+00:32:08', 
          type: 'success'
        }
      ],
      
      newMessage: '',
      chatMode: 'group',
      privateChatTarget: null
    };
  },
  computed: {
    displayOnlineMembers() {
      const list = (this.onlineMembers && this.onlineMembers.length > 0) ? this.onlineMembers : this._mockOnlineMembers;
      return Array.isArray(list) ? list : [];
    },
    chatableMembers() {
      const list = this.displayOnlineMembers;
      if (!Array.isArray(list)) return [];
      const cur = this.currentUserId != null ? Number(this.currentUserId) : null;
      return list.filter(m => m.userId != null && Number(m.userId) !== cur);
    },
    displayChatMessages() {
      return this.chatMessages || [];
    },
    displayPrivateMessages() {
      if (!this.privateChatTarget) return [];
      return this.privateChatMessages[this.privateChatTarget] || [];
    },
    selectedPrivateMember() {
      if (!this.privateChatTarget) return null;
      return this.chatableMembers.find(m => Number(m.userId) === Number(this.privateChatTarget));
    },
    panelStyle() {
      const left = this.panelLeft != null ? this.panelLeft : (window.innerWidth - this.panelWidth) / 2 - 20;
      const top = this.panelTop != null ? this.panelTop : (window.innerHeight - this.panelHeight) / 2 - 40;
      return {
        left: `${left}px`,
        top: `${top}px`,
        width: `${this.panelWidth}px`,
        height: `${this.panelHeight}px`
      };
    }
  },
  methods: {
    closeDialog() {
      this.$emit('input', false);
    },
    getStorageKey() {
      return STORAGE_KEY_PREFIX + (this.roomId || 'default');
    },
    loadPosition() {
      try {
        const key = this.getStorageKey();
        const raw = localStorage.getItem(key);
        if (raw) {
          const d = JSON.parse(raw);
          if (d.panelPosition) {
            const left = Number(d.panelPosition.left);
            const top = Number(d.panelPosition.top);
            if (!isNaN(left) && left >= 0) this.panelLeft = Math.min(left, window.innerWidth - this.panelWidth);
            if (!isNaN(top) && top >= 0) this.panelTop = Math.min(top, window.innerHeight - this.panelHeight);
          }
          if (d.panelSize) {
            const w = Number(d.panelSize.width);
            const h = Number(d.panelSize.height);
            if (!isNaN(w) && w >= 400 && w <= 1000) this.panelWidth = w;
            if (!isNaN(h) && h >= 300 && h <= window.innerHeight - 60) this.panelHeight = h;
          }
        }
      } catch (e) {
        console.warn('加载在线成员弹窗位置失败:', e);
      }
    },
    savePosition() {
      try {
        const payload = { panelSize: { width: this.panelWidth, height: this.panelHeight } };
        if (this.panelLeft != null && this.panelTop != null) {
          payload.panelPosition = { left: this.panelLeft, top: this.panelTop };
        }
        localStorage.setItem(this.getStorageKey(), JSON.stringify(payload));
      } catch (e) {
        console.warn('保存在线成员弹窗位置失败:', e);
      }
    },
    onDragStart(e) {
      e.preventDefault();
      this.isDragging = true;
      const currentLeft = this.panelLeft != null ? this.panelLeft : (window.innerWidth - this.panelWidth) / 2 - 20;
      const currentTop = this.panelTop != null ? this.panelTop : (window.innerHeight - this.panelHeight) / 2 - 40;
      this.dragStartX = e.clientX - currentLeft;
      this.dragStartY = e.clientY - currentTop;
      document.addEventListener('mousemove', this.onDragMove);
      document.addEventListener('mouseup', this.onDragEnd);
    },
    onDragMove(e) {
      if (!this.isDragging) return;
      e.preventDefault();
      let left = e.clientX - this.dragStartX;
      let top = e.clientY - this.dragStartY;
      left = Math.max(0, Math.min(window.innerWidth - this.panelWidth, left));
      top = Math.max(0, Math.min(window.innerHeight - this.panelHeight, top));
      this.panelLeft = left;
      this.panelTop = top;
    },
    onDragEnd() {
      this.isDragging = false;
      document.removeEventListener('mousemove', this.onDragMove);
      document.removeEventListener('mouseup', this.onDragEnd);
      this.savePosition();
    },
    onResizeStart(e) {
      e.preventDefault();
      e.stopPropagation();
      this.isResizing = true;
      this.resizeStartX = e.clientX;
      this.resizeStartY = e.clientY;
      this.resizeStartW = this.panelWidth;
      this.resizeStartH = this.panelHeight;
      document.addEventListener('mousemove', this.onResizeMove);
      document.addEventListener('mouseup', this.onResizeEnd);
    },
    onResizeMove(e) {
      if (!this.isResizing) return;
      e.preventDefault();
      const dx = e.clientX - this.resizeStartX;
      const dy = e.clientY - this.resizeStartY;
      this.panelWidth = Math.max(400, Math.min(1000, this.resizeStartW + dx));
      this.panelHeight = Math.max(300, Math.min(window.innerHeight - 60, this.resizeStartH + dy));
    },
    onResizeEnd() {
      this.isResizing = false;
      document.removeEventListener('mousemove', this.onResizeMove);
      document.removeEventListener('mouseup', this.onResizeEnd);
      this.savePosition();
    },

    showRollbackConfirm() {
      this.showRollbackDialog = true;
    },
    
    rollbackOperation() {
      this.showRollbackDialog = false;
      this.$message.success(this.$t('onlineMembersDialog.operationRollbackSuccess'));
      // 这里可以添加实际的回滚逻辑
    },
    
    // 新增：发送聊天消息
    sendMessage() {
      const text = this.newMessage.trim();
      if (!text) {
        this.$message.warning(this.$t('onlineMembersDialog.pleaseInputMessage'));
        return;
      }
      if (this.chatMode === 'group') {
        if (this.sendChat) this.sendChat(text);
      } else {
        const target = this.selectedPrivateMember;
        if (!target || !this.sendPrivateChat) return;
        this.sendPrivateChat(target.userId, target.userName, text);
      }
      this.newMessage = '';
      this.$nextTick(() => this.scrollChatToBottom());
    },
    formatMessageTime(ts) {
      if (!ts) return '';
      const d = new Date(typeof ts === 'number' ? ts : parseInt(ts, 10));
      return d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0') + ':' + d.getSeconds().toString().padStart(2, '0');
    },
    isMessageSelf(msg) {
      return msg.sender && Number(msg.sender.userId) === Number(this.currentUserId);
    },
    getMessageAvatar(msg) {
      const av = (msg.sender && msg.sender.avatar) || '';
      return this.resolveAvatarUrl(av);
    },
    getMessageSenderName(msg) {
      if (!msg.sender) return '';
      return msg.sender.nickName || msg.sender.userName || '';
    },
    isPrivateMessageSelf(msg) {
      return msg.sender && Number(msg.sender.userId) === Number(this.currentUserId);
    },
    getPrivateMessageAvatar(msg) {
      const av = (msg.sender && msg.sender.avatar) || '';
      return this.resolveAvatarUrl(av);
    },
    getPrivateMessageSenderName(msg) {
      if (!msg.sender) return '';
      return msg.sender.nickName || msg.sender.userName || '';
    },
    scrollChatToBottom() {
      const el = this.$refs.chatContent;
      if (el) el.scrollTop = el.scrollHeight;
    },
    resolveAvatarUrl(av) {
      if (!av) return '';
      if (av.startsWith('http')) return av;
      const base = process.env.VUE_APP_BACKEND_URL || (window.location.origin + (process.env.VUE_APP_BASE_API || '/dev-api'));
      return base + av;
    }
  },
  watch: {
    value(val) {
      if (val) this.loadPosition();
    },
    activeTab(newVal) {
      if (newVal === 'chat') {
        this.$nextTick(() => this.scrollChatToBottom());
      }
    },
    chatMessages: {
      handler() {
        this.$nextTick(() => this.scrollChatToBottom());
      },
      deep: true
    },
    displayPrivateMessages: {
      handler() {
        this.$nextTick(() => this.scrollChatToBottom());
      },
      deep: true
    },
    chatableMembers: {
      handler(members) {
        if (this.privateChatTarget && !members.some(m => Number(m.userId) === Number(this.privateChatTarget))) {
          this.privateChatTarget = null;
        }
      }
    },
    privateChatTarget(val) {
      if (val && this.sendPrivateChatHistoryRequest) {
        this.sendPrivateChatHistoryRequest(val);
      }
    }
  }
};
</script>

<style scoped>
/* 与 4T 弹窗一致：透明遮罩、不阻挡地图点击 */
.online-members-dialog {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: transparent;
  pointer-events: none;
}

.panel-container {
  position: fixed;
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  z-index: 1001;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  animation: dialog-fade-in 0.3s ease;
}

@keyframes dialog-fade-in {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid #e8e8e8;
  cursor: move;
}

.dialog-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

.close-btn {
  font-size: 20px;
  color: #999;
  cursor: pointer;
  transition: color 0.3s;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.close-btn:hover {
  color: #666;
  background: #f5f5f5;
  border-radius: 50%;
}

.dialog-body {
  padding: 20px;
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

.resize-handle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 20px;
  height: 20px;
  cursor: nwse-resize;
  user-select: none;
  z-index: 10;
  background: linear-gradient(to top left, transparent 50%, rgba(0, 138, 255, 0.2) 50%);
}

.resize-handle:hover {
  background: linear-gradient(to top left, transparent 50%, rgba(0, 138, 255, 0.4) 50%);
}

/* 在线成员样式 */
.members-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 400px;
  overflow-y: auto;
}

.member-item {
  display: flex;
  align-items: center;
  padding: 12px;
  border-radius: 8px;
  background: rgba(240, 242, 245, 0.8);
  transition: all 0.3s;
}

.member-item:hover {
  background: rgba(220, 233, 255, 0.8);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 138, 255, 0.15);
}

.member-item.active {
  background: rgba(190, 220, 255, 0.8);
  border: 1px solid rgba(0, 138, 255, 0.3);
  box-shadow: 0 2px 10px rgba(0, 138, 255, 0.2);
}

.member-avatar {
  margin-right: 12px;
}

.member-info {
  flex: 1;
}

.member-name {
  font-weight: 600;
  color: #333;
  margin-bottom: 4px;
}

.member-role {
  font-size: 12px;
  color: #666;
}

.member-status {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-right: 12px;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.status-dot.online {
  background: #52c41a;
  box-shadow: 0 0 4px rgba(82, 196, 26, 0.8);
}

.status-text {
  font-size: 12px;
  color: #666;
}

.editing-badge {
  background: #ff7875;
  color: white;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
}

/* 当前操作样式 */
.current-operation {
  display: flex;
  flex-direction: column;
  gap: 20px;
  height: 400px;
  overflow-y: auto;
}

.operation-section {
  background: rgba(240, 242, 245, 0.8);
  padding: 16px;
  border-radius: 8px;
}

.operation-section h4 {
  margin: 0 0 12px 0;
  font-size: 14px;
  font-weight: 600;
  color: #333;
}

.status-item {
  display: flex;
  margin-bottom: 8px;
}

.status-label {
  width: 100px;
  font-size: 13px;
  color: #666;
}

.status-value {
  font-size: 13px;
  color: #333;
  font-weight: 500;
}

/* 操作日志样式 */
.operation-logs {
  position: relative;
  max-height: 400px;
  overflow-y: auto;
}

.logs-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.logs-header h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: #333;
}

.log-content {
  background: rgba(240, 242, 245, 0.8);
  padding: 12px;
  border-radius: 6px;
  margin-left: 16px;
}

.log-user {
  font-weight: 600;
  color: #333;
  margin-bottom: 4px;
}

.log-action {
  font-size: 13px;
  color: #666;
  margin-bottom: 4px;
}

.log-object {
  font-size: 12px;
  color: #008aff;
  margin-bottom: 2px;
}

.log-detail {
  font-size: 12px;
  color: #999;
}

/* 回滚确认样式 */
.rollback-confirm {
  text-align: center;
}

.text-warning {
  color: #fa8c16;
}

/* 新增：聊天室样式 */
.chat-room {
  display: flex;
  flex-direction: column;
  height: 400px;
}

.chat-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.chat-header h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: #333;
}

.private-target {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.target-label {
  font-size: 13px;
  color: #666;
  margin-right: 8px;
  white-space: nowrap;
}

.target-select {
  flex: 1;
  min-width: 120px;
}

.target-role {
  font-size: 12px;
  color: #999;
  margin-left: 4px;
}

.chat-empty {
  color: #999;
  font-size: 14px;
  text-align: center;
  padding: 40px 0;
}

.online-count {
  font-size: 12px;
  color: #008aff;
}

.chat-content {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  background: rgba(240, 242, 245, 0.5);
  border-radius: 8px;
  margin-bottom: 12px;
}

.chat-message {
  display: flex;
  margin-bottom: 16px;
  max-width: 80%;
}

.self-message {
  flex-direction: row-reverse;
  margin-left: auto;
}

.other-message {
  margin-right: auto;
}

.message-avatar {
  margin: 0 8px;
}

.message-content {
  background: white;
  padding: 8px 12px;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.self-message .message-content {
  background: #e6f7ff;
}

.message-sender {
  font-size: 12px;
  font-weight: 600;
  color: #333;
  margin-bottom: 4px;
}

.message-text {
  font-size: 13px;
  color: #333;
  line-height: 1.4;
  margin-bottom: 4px;
}

.message-time {
  font-size: 11px;
  color: #999;
  text-align: right;
}

.chat-input {
  display: flex;
  gap: 8px;
}

.chat-input .el-input {
  flex: 1;
}

.send-btn {
  width: 80px;
}
</style>