<template>
  <div class="call-center-phone-bar">
    <form>
      <table width="1224">
        <tr>
          <td width="70%" colspan="2" height="35" style="text-indent: 20px;">
            <b>签入时间：</b> <span id="loginTime" title="" class="status4">{{ loginTime }}</span> &nbsp;&nbsp;
            <b>状态：</b> <span id="agentStatus" title="" class="status4">{{ agentStatus }}</span> &nbsp;&nbsp;
            <b>当前排队人数：</b><span id="queueStat" title="" class="status4">{{ queueNumber }}</span>
          </td>
        </tr>
        <tr>
          <td width="70%">
            <div>
              <div class="head_dial" style="padding-left: 10px; ">
                <dl class="dial">
                  <dt>
                    <label for="callTypeSelect"></label>
                    <select
                      id="callTypeSelect"
                      v-model="dialMode"
                      class="dial-mode-select"
                    >
                      <option value="plaintext">明文</option>
                      <option value="encrypted">密文</option>
                    </select>
                  </dt>
                  <dt>
                    <label for="ccphoneNumber"></label>
                    <input
                      type="text"
                      name="ccphoneNumber"
                      id="ccphoneNumber"
                      placeholder="输入电话号码"
                      class="tel_txt"
                      v-model="phoneNumber"
                      @keydown.enter="handleCall"
                    />
                  </dt>
                  <dd>
                    <ul><li id="callStatus" title="" class="status4">{{ callStatus }}</li></ul>
                    <ul v-if="isDecrypting" class="decrypting-tip">
                      <li>🔄 正在解密号码...</li>
                    </ul>
                  </dd>
                </dl>

                <ul class="dial_btn">
                  <li v-show="featureSwitches.setFree"><a href="#" id="setFree" class="xz_btn off" @click.prevent="handleSetFree"></a><span>置闲</span></li>
                  <li v-show="featureSwitches.setBusy">
                    <a href="#" id="setBusy" class="sm_btn off"></a>
                    <select style="width: 70px; min-width: 70px;" id="setBusySubList" v-model="busySubStatus" @change="handleSetBusy">
                      <option v-for="option in busySubStatusOptions" :key="option.value" :value="option.value">
                        {{ option.label }}
                      </option>
                    </select>
                  </li>
                  <li v-show="featureSwitches.call">
                    <a href="#" id="callBtn" class="wh_btn" @click.prevent="handleCall"></a>
                    <span>{{ isDecrypting ? '解密中...' : '外呼' }}</span>
                  </li>
                  <li id="holdBtnLi" v-show="showHoldBtn && featureSwitches.hold"><a href="#" id="holdBtn" class="bc_btn off" @click.prevent="handleHold"></a><span>保 持</span></li>
                  <li id="unHoldBtnLi" v-show="showUnHoldBtn && featureSwitches.hold"><a href="#" id="unHoldBtn" class="bc2_btn off" @click.prevent="handleUnHold"></a><span>取消保持</span></li>
                  <li v-show="featureSwitches.transfer"><a href="#" id="transferBtn" class="zjie_btn" @click.prevent="handleTransfer"></a><span>转接</span></li>
                  <li v-show="featureSwitches.consultation"><a href="#" id="consultationBtn" class="zixun_btn" @click.prevent="handleConsultation"></a><span>咨询</span></li>
                  <li v-show="featureSwitches.conference"><a href="#" id="conferenceBtn" class="hy_btn" @click.prevent="toggleConferenceArea"></a><span>会议</span></li>
                  <li v-show="featureSwitches.hangup"><a href="#" id="hangUpBtn" class="gj_btn" @click.prevent="handleHangup"></a><span>挂机</span></li>
                  <li v-show="featureSwitches.reset"><a href="#" id="resetStatus" class="qz_btn" @click.prevent="handleReset"></a><span>强置</span></li>
                  <li v-show="featureSwitches.signInOut"><a href="#" id="onLineBtn" class="sx_btn on" @click.prevent="handleOnline"></a><span>{{ onlineButtonText }}</span></li>
                </ul>
              </div>
            </div>
          </td>
          <td width="30%" style="display: none;">
            <div>
              <div style="padding-left: 10px; ">
                &nbsp; &nbsp; 外呼设置：
                <label for="videoCallBtn">
                  <input type="radio" value="video" name="callType" id="videoCallBtn" v-model="callType" />视频外呼
                </label> &nbsp;&nbsp;
                <label for="audioCallBtn">
                  <input type="radio" value="audio" name="callType" checked="checked" id="audioCallBtn" v-model="callType" />语音外呼
                </label> <br />

                &nbsp; &nbsp; 视频清晰度:
                <label for="videoLevelSelect"></label>
                <select id="videoLevelSelect" v-model="videoLevel">
                  <option v-for="(level, key) in videoLevels" :key="key" :value="level.levelId">
                    {{ level.description }}
                  </option>
                </select>
                <input
                  type="button"
                  id="reInviteVideoBtn"
                  title="发送视频邀请，可把音频通话转换为视频通话。"
                  @click="handleReInviteVideo"
                  value="视频邀请"
                  :disabled="!canSendVideoReInvite"
                >

                &nbsp;&nbsp;&nbsp;&nbsp;
                <label for="videoListSelect"></label>
                <select id="videoListSelect" v-model="selectedVideoFile">
                  <option v-for="video in videoFileList" :key="video.value" :value="video.value">
                    {{ video.label }}
                  </option>
                </select>
                <input
                  type="button"
                  id="sendVideoFileBtn"
                  title="推送视频给对方，以便结束当前通话。"
                  @click="handleSendVideoFile"
                  value="推送视频"
                  :disabled="!canSendVideoFile"
                >
              </div>
            </div>
          </td>
        </tr>

        <!-- 会议区域 -->
        <tr id="conference_area" style="display: none" v-show="showConferenceArea">
          <td colspan="2" style="padding-left: 130px; padding-top: 30px;">
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
              <div></div>
              <el-button type="danger" size="small" @click="closeConferenceArea" icon="el-icon-close">
                关闭
              </el-button>
            </div>
            <div>
              <div>
                <div id="conference_start" style="display: block">
                  <select id="conf_layout" name="conf_layout" style="display: none" v-model="conferenceLayout">
                    <option v-for="layout in conferenceLayouts" :key="layout.value" :value="layout.value">
                      {{ layout.label }}
                    </option>
                  </select>
                  &nbsp;
                  <select id="conf_template" name="conf_template" style="display: none" v-model="conferenceTemplate">
                    <option v-for="template in conferenceTemplates" :key="template.value" :value="template.value">
                      {{ template.label }}
                    </option>
                  </select>
                  &nbsp;
                  会议类型:
                  <select id="conf_call_type2" name="conf_call_type2" v-model="conferenceCallType">
                    <option v-for="type in conferenceCallTypes" :key="type.value" :value="type.value">
                      {{ type.label }}
                    </option>
                  </select>
                  <input type="hidden" value="audio" id="conf_call_type" name="conf_call_type" />
                  &nbsp;
                  <input
                    type="button"
                    name="startConference"
                    id="startConference"
                    @click="handleStartConference"
                    style="width: 70px;"
                    value="启动会议"
                    :disabled="conferenceStarted"
                  >
                  &nbsp;
                  <input
                    type="button"
                    name="endConference"
                    id="endConference"
                    @click="handleEndConference"
                    disabled="disabled"
                    style="width: 70px;"
                    value="结束会议"
                  >
                </div>

                <div style="width: 100%;"> &nbsp; </div>

                <div id="conference_member_list" style="display: none" v-show="showConferenceMemberList">
                  <ul>
                    <li id="conference_header">
                      <span class="conf_name">
                        <input
                          id="member_name"
                          name="member_name"
                          placeholder="姓名"
                          style="width: 60px;"
                          v-model="newMemberName"
                        />
                      </span> &nbsp;
                      <span class="conf_phone">
                        <input
                          id="member_phone"
                          name="member_phone"
                          placeholder="手机号"
                          style="width: 110px;"
                          v-model="newMemberPhone"
                        />
                      </span> &nbsp;
                      <span class="conf_call_type">
                        <select
                          id="member_call_type"
                          name="member_call_type"
                          style="display: none"
                          v-model="newMemberCallType"
                        >
                          <option value="video">视频</option>
                          <option value="audio" selected>音频</option>
                        </select>
                      </span>
                      <span class="conf_video_level" style="display: none">
                        <select
                          id="member_video_level"
                          name="member_video_level"
                          v-model="newMemberVideoLevel"
                        >
                          <option v-for="(level, key) in videoLevels" :key="key" :value="level.levelId">
                            {{ level.description }}
                          </option>
                        </select>
                      </span>

                      <span class="conf_name">
                        <input
                          type="button"
                          name="addConfMember"
                          id="addConfMember"
                          @click="handleAddConferenceMember"
                          style="width: 70px;"
                          value="加入会议"
                        >
                      </span>
                    </li>

                    <!-- 会议成员列表 -->
                    <li
                      v-for="(member, index) in conferenceMembers"
                      :key="index"
                      :id="'conf_member_' + member.phone"
                      class="conf_member_item_row"
                    >
                      <span class="conf_name">{{ member.name }}</span>
                      <span class="conf_phone">{{ member.phone }}</span>
                      <span class="conf_mute">
                        <a href="javascript:void(0)" @click="handleMuteMember(member.phone)">
                          <img alt="禁言该成员。" :src="getMuteIcon(member.muted)" width="15" height="17" />
                        </a>
                      </span>
                      <span class="conf_vmute" style="display: none">
                        <a href="javascript:void(0)" @click="handleVMuteMember(member.phone)">
                          <img alt="关闭该成员的视频。" :src="getVMuteIcon(member.vmuted)" />
                        </a>
                      </span>
                      <span class="conf_remove">
                        <a href="javascript:void(0)" @click="handleRemoveMember(member.phone)" title="踢除会议成员。">移除</a>
                      </span>
                      <span class="conf_re_invite" v-if="member.showReInvite">
                        <a href="javascript:void(0)" @click="handleReInviteMember(member)" title="重新呼叫。">重呼</a>
                      </span>
                      <span class="conf_status" :style="{ color: member.statusColor }">
                        {{ member.status }}
                      </span>
                    </li>
                  </ul>
                </div>
              </div>
            </div>
          </td>
        </tr>

        <!-- 转接区域 -->
        <tr id="transfer_area" width="100%" style="display: none" v-show="showTransferArea">
          <td colspan="2" width="100%" style="padding-left: 140px; padding-top: 30px;">
            <table width="100%">
              <tr>
                <td width="90">业务组</td>
                <td width="90">坐席成员</td>
                <td>&nbsp;</td>
                <td align="right">
                  <el-button type="danger" size="small" @click="closeTransferArea" icon="el-icon-close">
                    关闭
                  </el-button>
                </td>
              </tr>
              <tr>
                <td>
                  <el-select
                    id="transfer_to_groupIds"
                    name="transfer_to_groupIds"
                    v-model="selectedGroupId"
                    @change="handleGroupIdChange"
                    placeholder="请选择业务组"
                    filterable
                    size="small"
                    style="width: 200px;"
                  >
                    <el-option
                      v-for="group in groupList"
                      :key="group.groupId"
                      :label="group.bizGroupName"
                      :value="group.groupId"
                    />
                  </el-select>
                </td>

                <td>
                  <el-select
                    id="transfer_to_member"
                    name="transfer_to_member"
                    v-model="selectedMember"
                    placeholder="请选择坐席成员"
                    filterable
                    size="small"
                    style="width: 200px;"
                  >
                    <el-option
                      v-for="member in filteredMemberList"
                      :key="member.opnum"
                      :value="member.opnum"
                      :label="formatMemberText(member)"
                    />
                  </el-select>
                </td>
                <td valign="middle">
                  <el-input
                    type="text"
                    name="externalPhoneNumber"
                    id="externalPhoneNumber"
                    placeholder="电话号码"
                    v-model="externalPhoneNumber"
                    clearable
                    style="width: 200px; margin-bottom: 10px;"
                  />
                  <br />

                  <el-button
                    type="primary"
                    name="doTransferBtn"
                    id="doTransferBtn"
                    @click="handleDoTransfer"
                    v-show="showDoTransferBtn"
                    size="small"
                    style="width: 80px; margin-right: 10px;"
                  >
                    转接电话
                  </el-button>

                  <el-button
                    type="success"
                    name="stopCallWait"
                    id="stopCallWait"
                    @click="handleStopCallWait"
                    v-show="showStopCallWait"
                    size="small"
                    style="width: 80px; margin-right: 10px;"
                  >
                    接回客户
                  </el-button>

                  <el-button
                    type="warning"
                    name="transferCallWait"
                    id="transferCallWait"
                    @click="handleTransferCallWait"
                    v-show="showTransferCallWait"
                    size="small"
                    style="width: 80px; margin-right: 10px;"
                  >
                    转接客户
                  </el-button>

                  <el-button
                    type="info"
                    name="doConsultationBtn"
                    id="doConsultationBtn"
                    @click="handleDoConsultation"
                    v-show="showDoConsultationBtn"
                    size="small"
                    style="width: 80px;"
                  >
                    拨号咨询
                  </el-button>
                </td>
              </tr>
            </table>
          </td>
        </tr>
      </table>
    </form>

    <!-- 聊天和表单并排布局 -->
    <div style="display: flex; gap: 20px; margin-top: 20px;">
      <!-- ASR 实时对话文本框 -->
      <div id="chat-container" v-show="showChatContainer" style="flex: 1; min-width: 0;">
        <div id="chat-messages" class="message-container">
          <div
            v-for="(msg, index) in chatMessages"
            :key="index"
            :class="['message', msg.role === 1 ? 'customer' : 'agent']"
          >
            <div class="message-header">{{ msg.role === 1 ? '客户' : '我' }}</div>
            <div class="message-content">{{ msg.text }}</div>
          </div>
          <div v-if="systemMessages.length > 0" class="system-message">
            {{ systemMessages[systemMessages.length - 1] }}
          </div>
        </div>
      </div>

      <!-- 客户信息登记表单（外呼时自动显示） -->
      <div v-if="showCustomerForm" class="customer-form" style="flex: 1; min-width: 0; padding: 20px; background: #fff; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.1);">
        <h3 style="margin-bottom: 20px; color: #409EFF; border-left: 4px solid #409EFF; padding-left: 12px;">客户信息登记表</h3>
        <el-form :model="customerForm" label-width="120px" size="small">
          <el-form-item label="姓名" label-width="120px">
            <el-input v-model="customerForm.custName" type="textarea" :rows="2" placeholder="请输入姓名" />
          </el-form-item>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="省份">
                <el-select v-model="customerForm.province" placeholder="请选择省份" @change="handleProvinceChange" style="width: 100%;">
                  <el-option
                    v-for="item in provinceList"
                    :key="item.value"
                    :label="item.label"
                    :value="item"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="市">
                <el-select v-model="customerForm.city" placeholder="请选择城市" @change="handleCityChange" style="width: 100%;">
                  <el-option v-for="item in cityList" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="区/县">
                <el-select v-model="customerForm.county" placeholder="请选择区/县" @change="handleDistrictChange" style="width: 100%;">
                  <el-option v-for="item in countyList" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="性别">
                <el-select v-model="customerForm.gender" placeholder="请选择性别" style="width: 100%;">
                  <el-option label="男" value="0" />
                  <el-option label="女" value="1" />
                  <el-option label="未知" value="2" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <el-form-item label="详细地址" label-width="120px">
            <el-input v-model="customerForm.address" type="textarea" :rows="2" placeholder="请输入详细地址" />
          </el-form-item>

          <el-form-item label="沟通内容" label-width="120px">
            <el-input v-model="customerForm.notes" type="textarea" :rows="4" placeholder="请输入本次通话的沟通内容要点" />
          </el-form-item>

          <el-form-item label="历史沟通记录" label-width="120px">
            <el-input v-model="customerForm.communicationHistory" type="textarea" :rows="4" placeholder="历史沟通记录" disabled style="background-color: #f5f7fa;" />
          </el-form-item>

          <el-form-item>
            <el-button type="primary" @click="saveCustomerForm">保存</el-button>
            <el-button @click="closeCustomerForm">关闭</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
import {
  AgentStatusEnum,
  BusySubStatusOptions,
  ConferenceCallTypes,
  ConferenceLayouts,
  ConferenceTemplates,
  DefaultConfig,
  EventList,
  EventListWithTextInfo,
  PhoneButtons,
  VideoFileList,
  VideoLevels
} from '@/assets/callCenterPhoneBarSdk/constants.js';
import ccPhoneBarSocket from '@/assets/callCenterPhoneBarSdk/ccPhoneBarSocket.js';
import {getToolbarBasicParam, myCallUser, agentLogin} from "../../api/aiSipCall/aiSipCallUser";
import {
  addCustcallrecord,
  callEndSyncByUuid,
  encryptMobile,
  getCustCommunicationInfo
} from "../../api/aiSipCall/aiSipCallOutboundCdr";

export default {
  name: 'CallCenterPhoneBar',

  data() {
    return {
      // 工具条对象
      phoneBar: null,

      // 配置参数
      scriptServer: DefaultConfig.scriptServer,
      scriptServerPort: DefaultConfig.scriptServerPort,
      extNum: DefaultConfig.extNum,//分机号
      opNum: DefaultConfig.opNum,//用户工号
      userName: DefaultConfig.userName,//用户姓名
      loginPassWord:null,
      groupId: DefaultConfig.groupId,
      skillLevel: DefaultConfig.skillLevel,
      ipccServerUrl: DefaultConfig.ipccServerUrl,
      myGateway:null,
      // 状态显示
      loginTime: '00:00:00',
      agentStatus: '空闲',
      queueNumber: 0,
      callStatus: '没有连接',

      // 外呼相关
      phoneNumber: '',
      dialMode: 'plaintext', // 拨号方式：plaintext-明文, encrypted-密文
      callType: 'audio',
      videoLevel: VideoLevels.HD.levelId,
      canSendVideoReInvite: false,
      canSendVideoFile: false,
      selectedVideoFile: '',

      // 置忙子状态
      busySubStatus: '3',
      busySubStatusOptions: BusySubStatusOptions,

      // 视频级别
      videoLevels: VideoLevels,
      videoFileList: VideoFileList,

      // 会议相关
      showConferenceArea: false,
      showConferenceMemberList: false,
      conferenceStarted: false,
      conferenceLayout: '2x2',
      conferenceTemplate: '480p',
      conferenceCallType: 'audio',
      newMemberName: '',
      newMemberPhone: '',
      newMemberCallType: 'audio',
      newMemberVideoLevel: VideoLevels.HD.levelId,
      conferenceMembers: [],
      conferenceLayouts: ConferenceLayouts,
      conferenceTemplates: ConferenceTemplates,
      conferenceCallTypes: ConferenceCallTypes,

      // 转接相关
      showTransferArea: false,
      selectedGroupId: '',
      selectedMember: '',
      externalPhoneNumber: '',
      groupList: [],
      allMemberList: [],
      showDoTransferBtn: false,
      showStopCallWait: false,
      showTransferCallWait: false,
      showDoConsultationBtn: false,

      // ASR 聊天消息
      showChatContainer: false,
      chatMessages: [],
      systemMessages: [],

      // 在线按钮文本
      onlineButtonText: '签入',

      // 保持/取消保持按钮显示控制
      showHoldBtn: true,
      showUnHoldBtn: false,

      // 存储上一次的状态，用于去重
      lastAgentStatus: null,

      // 是否允许自动签入
      allowAutoSignIn: true,

      // 客户信息表单相关
      showCustomerForm: false,
      customerForm: {
        id: '',
        phoneNum: this.phoneNumber,
        custName: '',
        provinceCode: '',
        cityCode: '',
        countyCode: '',
        address: '',
        gender: '0',
        notes: '',
        callRecord: '',
        province: '',
        city: '',
        county: '',
        communicationHistory: ''
      },
      currentCallUuid: '', // 当前通话的 uuid
      provinceList: [],
      cityList: [],
      countyList: [],
      allCityList: [], // 存储当前城市数据
      allCountyList: [], // 存储当前区县数据

      // 功能开关配置(从配置文件读取默认值)
      featureSwitches: DefaultConfig.featureSwitches,

      // 加密号码缓存（仅用于性能优化，不作为主要依赖）
      encryptedNumberCache: null,

      // 加密锁，防止重复加密请求
      encryptingLock: false,

      // 存储解密后的号码（用于拨号，不显示在输入框）
      decryptedPhoneNumber: '',

      // 是否正在解密
      isDecrypting: false
    };
  },

  computed: {
    filteredMemberList() {
      if (!this.selectedGroupId) return [];
      return this.allMemberList.filter(member => member.groupId === this.selectedGroupId);
    }
  },

  mounted() {
    this.initPhoneBar();
    this.setupEventListeners();
    this.setupKeyboardEvents();
    this.setupEncryptedNumberWatcher();
    // 初始化转接/咨询区域的业务组下拉框事件监听 (仅一次)
    this.$nextTick(() => {
      const transferToGroupId = document.getElementById('transfer_to_groupIds');
      if (transferToGroupId) {
        transferToGroupId.addEventListener('change', this.handleGroupIdChange);
      }
    });
  },

  beforeDestroy() {
    // 断开 WebSocket 连接
    if (this.phoneBar) {
      this.phoneBar.disconnect();
    }
    // 移除键盘事件监听
    document.removeEventListener('keyup', this._escKeyHandler);
    document.removeEventListener('keydown', this._enterKeyHandler);
    // 移除业务组下拉框事件监听
    const transferToGroupId = document.getElementById('transfer_to_groupIds');
    if (transferToGroupId) {
      transferToGroupId.removeEventListener('change', this.handleGroupIdChange);
    }
  },

  methods: {
    /**
     * 初始化电话工具条
     */
    initPhoneBar() {
      // 创建工具条对象
      this.phoneBar = new ccPhoneBarSocket();

      // 先调用 myCallUser 获取 extNum
      this.loadExtNumAndInit();
    },

    loadExtNumAndInit() {
      myCallUser().then(response => {
        if (response.code === 200 && response.data && response.data.extNum) {
          // 将 extNum 设置到配置中
          this.extNum = response.data.extNum;
          // 将 网关 设置到配置中
          this.myGateway = response.data.gatewayIds;
          //将外呼平台登陆密码设置到配置中
          this.loginPassWord = response.data.password;
          //将外呼平台登陆用户名设置到配置中
          this.userName = response.data.loginName;
          // 然后再加载 websocket 参数
          this.loadWebsocketParam();
        } else {
          this.$message.error('未查询到分机号信息,请在【系统管理】 - 【员工管理】页面绑定 sip 角色');
        }
      }).catch(error => {
        this.$message.error('获取分机号异常:' +  error);
      });
    },

    loadWebsocketParam(){
      // console.log('[外呼平台登录] 开始调用登录接口...[' +this.userName+ "]["+this.loginPassWord+ "]");
      // 调用坐席登录接口
      // agentLogin({
      //   username: this.userName,
      //   password: this.loginPassWord,
      //   extNum: this.extNum,
      //   groupId: '1',
      //   rememberMe: false
      // }).then(response => {
      //   if (response.code === 200 || response.code === 0) {
      //     console.log('[外呼平台登录] 登录成功，开始用本地参数请求远端接口,分机号:', this.extNum + ",本地配置网关：" + this.myGateway);
      //
      //   } else {
      //     console.error('[外呼平台登录] 登录失败:', response.message || response.msg);
      //     this.$message.error(response.message || response.msg || '外呼平台登录失败');
      //   }
      // }).catch(error => {
      //   console.error('[外呼平台登录] 登录异常:', error);
      //   this.$message.error(error.message || '外呼平台登录异常');
      // });
      getToolbarBasicParam({ extNum:this.extNum, myGateway: this.myGateway }).then(response => {
        if(response.code === 0) {
          //设置登陆账号和用户名
          this.opNum = response.data.opNum;
          this.userName = response.data.userName;
          // 构建配置对象
          const callConfig = {
            useDefaultUi: true,
            loginToken: response.data.loginToken,
            ipccServer: this.ipccServerUrl,
            gatewayList: response.data.gatewayList,
            gatewayEncrypted: false,
            extPassword: response.data.encryptPsw,
            // 分机账户
            extnum : this.extNum,
            // 工号
            opnum : this.userName,
          };

          this.phoneBar.initConfig(callConfig);

          // 登录成功后建立 WebSocket 连接
          this.phoneBar.connect();
        } else {
          this.$message.error("获取工具条基础配置参数失败");
        }
      }).catch(error => {
        this.$message.error("获取工具条基础配置参数异常:" + error);
      });
      // 初始状态应该是"签入"，而不是"签出"
      this.onlineButtonText = '签入';
      this.callStatus = '没有连接';
      this.agentStatus = '空闲';
    },
    /**
     * 设置键盘事件监听
     */
    setupKeyboardEvents() {
      // 监听 ESC 键挂机
      this._escKeyHandler = (e) => {
        if (e.which === 27) {
          if (this.phoneBar && this.phoneBar.getIsConnected()) {
            const hangUpBtn = document.getElementById('hangUpBtn');
            if (hangUpBtn && hangUpBtn.classList.contains('on')) {
              this.phoneBar.hangup();
            }
          }
        }
      };
      document.addEventListener('keyup', this._escKeyHandler);

      // 监听回车键外呼
      this._enterKeyHandler = (e) => {
        if (e.which === 13) {
          const phoneNumberInput = document.getElementById('ccphoneNumber');
          if (phoneNumberInput && document.activeElement === phoneNumberInput) {
            e.preventDefault();
            this.handleCall();
          }
        }
      };
      document.addEventListener('keydown', this._enterKeyHandler);

      // 页面关闭前确认
      window.onbeforeunload = function () {
        if (!confirm('关闭网页将导致您无法接听电话，确定要关闭吗？')) return false;
      };
    },

    /**
     * 设置事件监听
     */
    setupEventListeners() {
      // websocket 通信对象断开事件
      this.phoneBar.on(EventList.WS_DISCONNECTED, (msg) => {
        this.updatePhoneBar(msg, EventList.WS_DISCONNECTED);
        // 断开连接时隐藏所有表单区域
        this.showTransferArea = false;
        this.showConferenceArea = false;
        this.showCustomerForm = false;
        // 更新状态显示
        // 只有在允许自动签入的情况下才设置为"签入"
        if (this.allowAutoSignIn) {
          this.onlineButtonText = '签入';
        }
        this.callStatus = '没有连接';
        this.agentStatus = '空闲';
        this.loginTime = '00:00:00';
      });

      this.phoneBar.on(EventList.OUTBOUND_START, (msg) => {
        // 外呼开始时不显示聊天窗口和客户信息表单（由用户手动控制）
        // this.showChatContainer = true;
        // this.showCustomerForm = true;
        //// 加载历史沟通记录
        // this.loadCommunicationHistory();
        // 注意：此时通话尚未建立，uuid 可能还未生成，需要在 CALLER_ANSWERED 或 CALLEE_ANSWERED 事件中获取
      });

      this.phoneBar.on(EventList.REQUEST_ARGS_ERROR, (msg) => {
        // 当发生请求参数错误时，重置 SDK 的呼叫状态
        if (this.phoneBar && typeof this.phoneBar.isCalling !== 'undefined') {
          this.phoneBar.isCalling = false;
        }
        this.updatePhoneBar(msg, EventList.REQUEST_ARGS_ERROR);
      });

      // 用户已在其他设备登录
      this.phoneBar.on(EventList.USER_LOGIN_ON_OTHER_DEVICE, (msg) => {
        this.updatePhoneBar(msg, EventList.USER_LOGIN_ON_OTHER_DEVICE);
        alert(EventListWithTextInfo.USER_LOGIN_ON_OTHER_DEVICE.msg);
      });


      this.phoneBar.on(EventList.WS_CONNECTED, (msg) => {
        this.loginTime = new Date().toLocaleTimeString();

        // WebSocket 连接成功
        this.handleAgentLoginAfterWsConnect(msg);
      });

      this.phoneBar.on(EventList.CALLEE_RINGING, (msg) => {
        this.updatePhoneBar(msg, EventList.CALLEE_RINGING);
      });

      this.phoneBar.on(EventList.CALLER_ANSWERED, (msg) => {
        this.agentStatus = '通话中';
        // 在主叫接通时获取通话 uuid
        if (msg && msg.object && msg.object.uuid) {
          this.currentCallUuid = msg.object.uuid;
        }
        this.updatePhoneBar(msg, EventList.CALLER_ANSWERED);
      });

      this.phoneBar.on(EventList.CALLER_HANGUP, (msg) => {
        this.agentStatus = '通话结束';
        this.canSendVideoReInvite = false;
        this.canSendVideoFile = false;
        // 隐藏转接/咨询区域和会议区域（与 source 一致）
        this.showTransferArea = false;
        this.showConferenceArea = false;
        // 客户信息表单已经在 OUTBOUND_START 时显示，这里不需要重复显示
        // 获取当前通话的 uuid
        if (msg && msg.object && msg.object.uuid) {
          this.currentCallUuid = msg.object.uuid;
        }
        this.updatePhoneBar(msg, EventList.CALLER_HANGUP);
        // 不需要再次加载，已经在 OUTBOUND_START 时加载过了

        // 通话结束后调用后端接口
        this.handleCallEnd();

        // 向父组件发送通话结束事件
        this.$emit('call-ended');
      });

      this.phoneBar.on(EventList.CALLEE_ANSWERED, (msg) => {
        // 在被叫接通时也获取通话 uuid（作为备用）
        if (msg && msg.object && msg.object.uuid) {
          this.currentCallUuid = msg.object.uuid;
        }
        this.updatePhoneBar(msg, EventList.CALLEE_ANSWERED);
      });

      this.phoneBar.on(EventList.CALLEE_HANGUP, (msg) => {
        // 隐藏转接/咨询区域和会议区域（与 source 一致）
        this.showTransferArea = false;
        this.showConferenceArea = false;
        // 客户信息表单已经在 OUTBOUND_START 时显示，这里不需要重复显示
        // 获取当前通话的 uuid
        if (msg && msg.object && msg.object.uuid) {
          this.currentCallUuid = msg.object.uuid;
        }
        this.updatePhoneBar(msg, EventList.CALLEE_HANGUP);
        // 不需要再次加载，已经在 OUTBOUND_START 时加载过了

        // 通话结束后调用后端接口
        this.handleCallEnd();

        // 向父组件发送通话结束事件
        this.$emit('call-ended');
      });

      this.phoneBar.on(EventList.STATUS_CHANGED, (msg) => {

        // 确保 msg.object 存在才设置
        if (msg && msg.object) {
          const statusText = msg.object.text || '未知状态';
          const statusCode = msg.object.status;

          // 去重：如果状态码和上次一样，则不重复处理
          if (this.lastAgentStatus === statusCode) {
            return;
          }

          // 更新上一次的状态
          this.lastAgentStatus = statusCode;

          // 将"置忙"统一显示为"忙碌"
          this.agentStatus = statusText === '置忙' ? '忙碌' : statusText;
        }
        this.updatePhoneBar(msg, EventList.STATUS_CHANGED);

        // 当状态变为忙碌时，表示可以外呼了
        if (msg.object && msg.object.status === AgentStatusEnum.BUSY) {
        }
      });

      this.phoneBar.on(EventList.ACD_GROUP_QUEUE_NUMBER, (msg) => {
        this.queueNumber = msg.object.queue_number;
      });

      this.phoneBar.on(EventList.ON_AUDIO_CALL_CONNECTED, (msg) => {
        this.canSendVideoReInvite = true;
      });

      this.phoneBar.on(EventList.CUSTOMER_CHANNEL_HOLD, (msg) => {
        this.callStatus = '通话已保持';
        this.showHoldBtn = false;
        this.showUnHoldBtn = true;
      });

      this.phoneBar.on(EventList.CUSTOMER_CHANNEL_UNHOLD, (msg) => {
        this.callStatus = '客户通话已接回';
        this.showHoldBtn = true;
        this.showUnHoldBtn = false;
      });

      this.phoneBar.on(EventList.CUSTOMER_ON_HOLD_HANGUP, (msg) => {
        this.showHoldBtn = true;
        this.showUnHoldBtn = false;
        this.callStatus = '保持的通话已挂机.';
      });

      this.phoneBar.on(EventList.ON_VIDEO_CALL_CONNECTED, (msg) => {
        this.canSendVideoFile = true;
      });

      this.phoneBar.on(EventList.INNER_CONSULTATION_START, (msg) => {
        this.callStatus = '咨询开始.';
      });

      this.phoneBar.on(EventList.INNER_CONSULTATION_STOP, (msg) => {
        this.callStatus = '咨询结束.';
      });

      this.phoneBar.on(EventList.TRANSFER_CALL_SUCCESS, (msg) => {
        // 转接成功后隐藏转接/咨询区域（与 source 一致）
        this.showTransferArea = false;
        this.callStatus = '电话转接成功.';
        this.externalPhoneNumber = '';
      });

      this.phoneBar.on(EventList.AGENT_STATUS_DATA_CHANGED, (msg) => {

        // 解析并更新坐席列表数据
        if (msg && msg.object) {
          try {
            // object 可能是字符串或对象
            const agentList = typeof msg.object === 'string' ? JSON.parse(msg.object) : msg.object;
            if (Array.isArray(agentList)) {
              // 直接复制完整数据，保留所有字段 (包括姓名、工号、状态等)
              this.allMemberList = [...agentList];
            }
          } catch (e) {
            console.error('解析坐席列表失败:', e);
          }
        }

        // 刷新成员列表 (事件监听器已在 mounted 中初始化，无需重复添加)
        this.$nextTick(() => {
          this.refreshMemberIdList();
        });
      });

      // 客户通话等待相关事件
      this.phoneBar.on(EventList.CUSTOMER_CHANNEL_CALL_WAIT, (msg) => {
        // 隐藏会议区域和客户信息表单（与 source 一致）
        this.showConferenceArea = false;
        this.showCustomerForm = false;
        this.showStopCallWait = true;
        this.showDoConsultationBtn = false;
        this.showDoTransferBtn = false;
        this.callStatus = '客户电话等待中.';
        this.showTransferArea = true;
      });

      this.phoneBar.on(EventList.CUSTOMER_CHANNEL_OFF_CALL_WAIT, (msg) => {
        // 隐藏转接/咨询区域
        this.showStopCallWait = false;
        this.showTransferCallWait = false;
        this.showTransferArea = false;
        this.callStatus = '等待的电话已接回.';
      });

      this.phoneBar.on(EventList.INNER_CONSULTATION_START, (msg) => {
        // 隐藏会议区域和客户信息表单（与 source 一致）
        this.showConferenceArea = false;
        this.showCustomerForm = false;
        this.callStatus = '咨询开始.';
        this.showTransferCallWait = true;
        this.showDoConsultationBtn = false;
        this.showDoTransferBtn = false;
      });

      this.phoneBar.on(EventList.INNER_CONSULTATION_STOP, (msg) => {
        // 隐藏转接/咨询区域
        this.showTransferCallWait = false;
        this.showTransferArea = false;
        this.callStatus = '咨询结束.';
      });

      this.phoneBar.on(EventList.CUSTOMER_ON_CALL_WAIT_HANGUP, (msg) => {
        // 隐藏转接/咨询区域
        this.showStopCallWait = false;
        this.showTransferCallWait = false;
        this.showTransferArea = false;
        this.callStatus = '等待的客户已挂机.';
      });

      // 会议相关事件
      this.phoneBar.on(EventList.CONFERENCE_MEMBER_ANSWERED, (msg) => {
        this.updateConferenceMemberStatus(msg.object.phone, '通话中', 'green');
      });

      this.phoneBar.on(EventList.CONFERENCE_MEMBER_HANGUP, (msg) => {
        this.updateConferenceMemberHangup(msg.object.phone, msg.object);
      });

      this.phoneBar.on(EventList.CONFERENCE_MODERATOR_ANSWERED, (msg) => {
        // 隐藏转接/咨询区域和客户信息表单（与 source 一致）
        this.showTransferArea = false;
        this.showCustomerForm = false;
        this.onConferenceStart();
      });

      this.phoneBar.on(EventList.CONFERENCE_MODERATOR_HANGUP, (msg) => {
        // 会议结束后隐藏会议区域
        this.onConferenceEnd();
      });

      this.phoneBar.on(EventList.CONFERENCE_MEMBER_MUTED_SUCCESS, (msg) => {
        const memberPhone = msg.object.phone;
        const member = this.conferenceMembers.find(m => m.phone === memberPhone);
        if (member) {
          member.muted = true;
        }
      });

      this.phoneBar.on(EventList.CONFERENCE_MEMBER_UNMUTED_SUCCESS, (msg) => {
        const memberPhone = msg.object.phone;
        const member = this.conferenceMembers.find(m => m.phone === memberPhone);
        if (member) {
          member.muted = false;
        }
      });

      this.phoneBar.on(EventList.CONFERENCE_MEMBER_VMUTED_SUCCESS, (msg) => {
        const memberPhone = msg.object.phone;
        const member = this.conferenceMembers.find(m => m.phone === memberPhone);
        if (member) {
          member.vmuted = true;
        }
      });

      this.phoneBar.on(EventList.CONFERENCE_MEMBER_UNVMUTED_SUCCESS, (msg) => {
        const memberPhone = msg.object.phone;
        const member = this.conferenceMembers.find(m => m.phone === memberPhone);
        if (member) {
          member.vmuted = false;
        }
      });

      // ASR 相关事件
      this.phoneBar.on(EventList.ASR_PROCESS_STARTED, (msg) => {
        this.chatMessages = [];
      });

      this.phoneBar.on(EventList.ASR_RESULT_GENERATE, (msg) => {
        this.handleAsrMessage(msg);
      });

      this.phoneBar.on(EventList.ASR_PROCESS_END_CUSTOMER, (msg) => {
        this.handleAsrMessage(msg);
      });

      this.phoneBar.on(EventList.ASR_PROCESS_END_AGENT, (msg) => {
        this.handleAsrMessage(msg);
      });
    },

    /**
     * WebSocket 连接成功后处理
     */
    handleAgentLoginAfterWsConnect(wsMsg) {
      this.loginTime = new Date().toLocaleTimeString();

      // 设置初始状态
      this.callStatus = '已签入';
      this.agentStatus = '忙碌';
      this.updatePhoneBar(wsMsg, EventList.WS_CONNECTED);
      this.onlineButtonText = '签出';

      if (this.allowAutoSignIn) {
      }

      // 调用 SDK 的置忙方法
      if (this.phoneBar && this.phoneBar.getIsConnected()) {
        this.phoneBar.setStatusBusy();
      }
    },

    /**
     * 更新电话工具条 UI
     */
    updatePhoneBar(msg, statusCode) {

      const statusInfo = this.findEventByCode(statusCode);

      if (!statusInfo) {
        console.warn('[DEBUG] statusInfo not found for code:', statusCode);
        return;
      }

      // 特殊处理 STATUS_CHANGED 事件
      if (statusCode === EventList.STATUS_CHANGED) {

        // 优先使用服务器返回的状态文本
        if (msg && msg.object && msg.object.text) {
          // 将"置忙"统一显示为"忙碌"
          this.callStatus = msg.object.text === '置忙' ? '忙碌' : msg.object.text;
        }

        // 根据坐席状态更新按钮
        if (msg && msg.object && typeof msg.object.status !== 'undefined') {

          if (msg.object.status === AgentStatusEnum.FREE) {
            // 只有空闲状态才显示为"置闲"
            this.updateButtonState(EventListWithTextInfo.FREE);
          } else if (msg.object.status === AgentStatusEnum.BUSY ||
                     msg.object.status === AgentStatusEnum.BUSY_REST ||
                     msg.object.status === AgentStatusEnum.BUSY_MEETING ||
                     msg.object.status === AgentStatusEnum.BUSY_TRAINING ||
                     msg.object.status === AgentStatusEnum.FILL_FORM) {
            // 置忙、小休、会议、培训、话后整理都显示为"忙碌"
            this.updateButtonState(EventListWithTextInfo.BUSY);
            // 强制设置 callStatus 为"忙碌"
            this.callStatus = '忙碌';
          } else if (msg.object.status === AgentStatusEnum.INCALL ||
                     msg.object.status === AgentStatusEnum.CONFERENCE) {
            // 通话中状态，不需要更新按钮状态，保持当前状态即可
          } else if (msg.object.status === AgentStatusEnum.JUST_LOGIN) {
            // 刚登录，尚未就绪，自动设置为置忙状态以便外呼
            this.agentStatus = '忙碌';
            this.callStatus = '忙碌';
          } else {
            console.warn('[DEBUG] Unknown agent status:', msg.object.status);
          }
        } else {
          console.error('[DEBUG] msg.object.status is missing or invalid');
        }
      } else {
        // 其他事件：更新状态文本和按钮状态
        if (statusInfo.msg) {
          this.callStatus = statusInfo.msg;
        }
        this.updateButtonState(statusInfo);
      }
    },

    /**
     * 根据状态码查找事件信息
     */
    findEventByCode(code) {
      // 将 code 转换为数字类型进行比较
      const numericCode = Number(code);

      for (let key in EventListWithTextInfo) {
        if (EventListWithTextInfo[key].code === numericCode) {
          return EventListWithTextInfo[key];
        }
      }
      return null;
    },

    /**
     * 更新按钮状态
     */
    updateButtonState(statusInfo) {

      if (statusInfo.btn_text) {
        statusInfo.btn_text.forEach(item => {
          const el = document.querySelector(item.id);
          if (el) {
            const nextSpan = el.nextElementSibling;
            if (nextSpan) nextSpan.textContent = item.name;
          } else {
            console.warn('[DEBUG] Button element not found:', item.id);
          }
        });
      }

      if (statusInfo.enabled_btn && statusInfo.enabled_btn.length > 0) {
        PhoneButtons.forEach(btn => {
          const el = document.querySelector(btn);
          // console.log(`[DEBUG] Processing button ${btn}, element exists:`, !!el);
          if (el) {
            // 检查功能开关配置
            let isFeatureEnabled = true;
            if (btn === '#setFree') isFeatureEnabled = this.featureSwitches.setFree;
            else if (btn === '#setBusy') isFeatureEnabled = this.featureSwitches.setBusy;
            else if (btn === '#callBtn') isFeatureEnabled = this.featureSwitches.call;
            else if (btn === '#holdBtn' || btn === '#unHoldBtn') isFeatureEnabled = this.featureSwitches.hold;
            else if (btn === '#transferBtn') isFeatureEnabled = this.featureSwitches.transfer;
            else if (btn === '#consultationBtn') isFeatureEnabled = this.featureSwitches.consultation;
            else if (btn === '#hangUpBtn') isFeatureEnabled = this.featureSwitches.hangup;
            else if (btn === '#resetStatus') isFeatureEnabled = this.featureSwitches.reset;
            else if (btn === '#onLineBtn') isFeatureEnabled = this.featureSwitches.signInOut;

            // 只有在功能启用且状态允许时才启用按钮
            if (statusInfo.enabled_btn.includes(btn) && isFeatureEnabled) {
              el.classList.add('on');
              // console.log(`[DEBUG] Added 'on' class to ${btn}`);
            } else {
              el.classList.remove('on');
              // console.log(`[DEBUG] Removed 'on' class from ${btn}`);
            }
          } else {
            console.warn('[DEBUG] PhoneButton element not found:', btn);
          }
        });
      }
    },

    /**
     * 设置加密号码监听器
     */
    setupEncryptedNumberWatcher() {
      this.$watch(
        () => ({ dialMode: this.dialMode, phoneNumber: this.phoneNumber }),
        async (newVal, oldVal) => {
          // 当拨号方式为密文且电话号码不为空时，自动解密
          if (newVal.dialMode === 'encrypted' && newVal.phoneNumber && newVal.phoneNumber.trim().length > 0) {
            // 如果之前有正在进行的解密，先重置状态
            if (this.isDecrypting || this.encryptingLock) {
              this.isDecrypting = false;
              this.encryptingLock = false;
              // 等待一小段时间确保状态完全重置
              await new Promise(resolve => setTimeout(resolve, 100));
            }
            await this.decryptPhoneNumber(newVal.phoneNumber.trim());
          } else {
            // 如果切换到明文或清空号码，清除解密后的号码
            this.decryptedPhoneNumber = '';
            this.isDecrypting = false;
            this.encryptingLock = false;
          }
        },
        { deep: true }
      );
    },

    /**
     * 实时解密号码（返回 Promise）
     */
    async decryptPhoneNumber(phoneNumber) {
      // 防止重复解密（增加锁检查）
      if (this.isDecrypting || this.encryptingLock) {
        return;
      }

      try {
        this.isDecrypting = true;
        this.encryptingLock = true;

        const combined = phoneNumber + this.generateRandom();

        const response = await encryptMobile({"data": combined});

        if (response.code === 200) {
          // 用密钥解密
          const privateKey = process.env.VUE_APP_SIP_PHONE_ENCRYPT_PRIVATE_KEY;
          // 去掉后六位数据
          const resultData = response.data.slice(0, -6);
          // 保存解密后的号码（用于拨号）
          this.decryptedPhoneNumber = this.xorDecrypt(resultData, privateKey);
        } else {
          this.decryptedPhoneNumber = '';
          this.$message.error('号码解密失败: ' + (response.message || response.msg || '未知错误'));
          console.error('[解密失败] 后端返回错误:', response);
        }
      } catch (error) {
        this.decryptedPhoneNumber = '';
        this.$message.error('号码解密异常: ' + (error.message || '未知错误'));
        console.error('[解密异常] 捕获到错误:', error);
      } finally {
        // 强制释放锁，确保可以再次拨号
        this.isDecrypting = false;
        this.encryptingLock = false;
      }
    },



    /**
     * 外呼处理
     */
    async handleCall() {
      // 检查外呼按钮是否为灰色(disabled)状态
      const callBtn = document.getElementById('callBtn');
      if (!callBtn || !callBtn.classList.contains('on')) {
        this.$message.warning('当前无法外呼，请先置忙');
        return;
      }

      if (!this.phoneNumber || this.phoneNumber.trim().length < 3) {
        this.$message.warning('请输入正确格式的外呼号码!');
        return;
      }

      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先签入后再外呼');
        return;
      }

      // 检查当前是否有通话正在进行
      if (this.phoneBar.getCallConnected()) {
        this.$message.warning('当前有通话正在进行，请先挂机');
        return;
      }

      let dialModeStr = '明文';
      let phoneNumber;

      if (this.dialMode === 'encrypted') {
        dialModeStr = '密文';

        // 检查是否正在解密
        if (this.isDecrypting) {
          this.$message.warning('正在解密号码，请稍候...');
          return;
        }

        // 检查是否已解密
        if (!this.decryptedPhoneNumber) {
          this.$message.warning('号码未解密或解密失败，请重新输入');
          return;
        }

        // 使用解密后的号码
        phoneNumber = this.decryptedPhoneNumber;
      } else {
        // 明文模式：直接使用输入的号码
        phoneNumber = this.phoneNumber.trim();
      }

      this.phoneBar.call(phoneNumber, this.callType, this.videoLevel);
    },

    // 生成6位随机数
    generateRandom() {
      return Math.floor(100000 + Math.random() * 900000).toString();
    },
    // XOR 解密（Base64 输入，私钥字符串）
    xorDecrypt(base64Str, privateKey) {
      // Base64 解码为二进制字符串
      const binaryStr = atob(base64Str);
      const keyBytes = privateKey.split('').map(ch => ch.charCodeAt(0));
      let result = '';
      for (let i = 0; i < binaryStr.length; i++) {
        const dataByte = binaryStr.charCodeAt(i);
        const keyByte = keyBytes[i % keyBytes.length];
        result += String.fromCharCode(dataByte ^ keyByte);
      }
      return result;
    },


    /**
     * 置闲处理
     */
    handleSetFree() {
      const btn = document.getElementById('setFree');
      if (btn && btn.classList.contains('on')) {
        this.phoneBar.setStatus(AgentStatusEnum.FREE);
      }
    },

    /**
     * 置忙处理
     */
    handleSetBusy() {
      const btn = document.getElementById('setBusy');
      if (btn && btn.classList.contains('on')) {
        this.phoneBar.setStatus(parseInt(this.busySubStatus));
      }
    },

    /**
     * 保持通话处理
     */
    handleHold() {
      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先上线.');
        return;
      }
      const btn = document.getElementById('holdBtn');
      if (btn && btn.classList.contains('on')) {
        this.phoneBar.holdCall();
      }
    },

    /**
     * 取消保持处理
     */
    handleUnHold() {
      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先上线.');
        return;
      }
      const btn = document.getElementById('unHoldBtn');
      if (btn && btn.classList.contains('on')) {
        this.phoneBar.unHoldCall();
      }
    },

    /**
     * 关闭转接/咨询区域
     */
    closeTransferArea() {
      this.showTransferArea = false;
      this.showDoTransferBtn = false;
      this.showDoConsultationBtn = false;
    },

    /**
     * 关闭会议区域
     */
    closeConferenceArea() {
      this.showConferenceArea = false;
      this.showConferenceMemberList = false;
    },

    /**
     * 转接处理（美化版）
     */
    handleTransfer() {
      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先上线.');
        return;
      }
      const btn = document.getElementById('transferBtn');
      if (btn && btn.classList.contains('on')) {
        // 如果已经显示转接区域，则隐藏；否则显示
        this.showTransferArea = !this.showTransferArea;
        if (this.showTransferArea) {
          // 先填充业务组选项
          this.populateGroupIdOptions();
          // 订阅坐席状态列表（仅在此处订阅一次）
          this.phoneBar.subscribeAgentList();
          this.showDoTransferBtn = true;
          this.showDoConsultationBtn = false;
          this.showStopCallWait = false;
          this.showTransferCallWait = false;
          // 隐藏客户信息表单（与 source 一致）
          this.showCustomerForm = false;
          // 隐藏会议区域
          this.showConferenceArea = false;

          // 平滑滚动到转接区域
          this.$nextTick(() => {
            const transferArea = document.getElementById('transfer_area');
            if (transferArea) {
              transferArea.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }
          });
        } else {
          // 隐藏转接区域，但不取消订阅（咨询功能也需要）
          this.showDoTransferBtn = false;
          this.showDoConsultationBtn = false;
        }
      }
    },

    /**
     * 咨询处理（美化版）
     */
    handleConsultation() {
      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先上线.');
        return;
      }
      const btn = document.getElementById('consultationBtn');
      if (btn && btn.classList.contains('on')) {
        // 如果已经显示咨询区域，则隐藏；否则显示
        this.showTransferArea = !this.showTransferArea;
        if (this.showTransferArea) {
          // 先填充业务组选项
          this.populateGroupIdOptions();
          // 如果还未订阅，则进行订阅（与转接共用订阅）
          if (!this.phoneBar.subscribeAgentListStarted) {
            this.phoneBar.subscribeAgentList();
          }
          this.showDoConsultationBtn = true;
          this.showDoTransferBtn = false;
          this.showStopCallWait = false;
          this.showTransferCallWait = false;
          // 隐藏客户信息表单（与 source 一致）
          this.showCustomerForm = false;
          // 隐藏会议区域
          this.showConferenceArea = false;

          // 平滑滚动到咨询区域
          this.$nextTick(() => {
            const transferArea = document.getElementById('transfer_area');
            if (transferArea) {
              transferArea.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }
          });
        } else {
          // 隐藏咨询区域，但不取消订阅（转接功能也需要）
          this.showDoConsultationBtn = false;
          this.showDoTransferBtn = false;
        }
      }
    },

    /**
     * 会议区域切换（美化版）
     */
    toggleConferenceArea() {
      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先上线.');
        return;
      }
      // 如果已经显示会议区域，则隐藏；否则显示
      this.showConferenceArea = !this.showConferenceArea;
      if (this.showConferenceArea) {
        this.showConferenceMemberList = false;
        // 隐藏转接/咨询区域
        this.showTransferArea = false;

        // 平滑滚动到会议区域
        this.$nextTick(() => {
          const conferenceArea = document.getElementById('conference_area');
          if (conferenceArea) {
            conferenceArea.scrollIntoView({ behavior: 'smooth', block: 'start' });
          }
        });
      }
    },

    /**
     * 启动会议
     */
    handleStartConference() {
      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先上线.');
        return;
      }
      this.phoneBar.conferenceStartBtnUI('');
    },

    /**
     * 结束会议
     */
    handleEndConference() {
      this.phoneBar.conferenceEnd();
    },

    /**
     * 挂机处理
     */
    handleHangup() {
      const btn = document.getElementById('hangUpBtn');
      if (btn && btn.classList.contains('on')) {
        this.phoneBar.hangup();
      }
    },

    /**
     * 重置处理
     */
    handleReset() {
      window.onbeforeunload = null;
      location.reload();
    },

    /**
     * 签入/签出处理
     */
    handleOnline() {
      const btn = document.getElementById('onLineBtn');
      if (btn && btn.classList.contains('on')) {
        if (this.phoneBar.getIsConnected()) {
          // 已连接时执行签出操作
          // 设置不允许自动签入
          this.allowAutoSignIn = false;
          // 调用 SDK 的 disconnect 方法 (会自动关闭 WebSocket)
          this.phoneBar.disconnect();
          this.onlineButtonText = '签入';
          this.callStatus = '没有连接';
          this.agentStatus = '空闲';
          this.loginTime = '00:00:00';
        } else {
          // 未连接时执行签入操作
          // 允许自动签入
          this.allowAutoSignIn = true;
          // 建立 WebSocket 连接
          this.phoneBar.connect();
          this.onlineButtonText = '签出';
        }
      } else {
        alert('当前不允许操作!');
      }
    },

    /**
     * 视频邀请处理
     */
    handleReInviteVideo() {
      if (!this.phoneBar.getIsConnected()) {
        this.$message.warning('请先上线.');
        return;
      }
      this.phoneBar.reInviteVideoCall();
    },

    /**
     * 发送视频文件处理
     */
    handleSendVideoFile() {
      if (!this.selectedVideoFile) {
        alert('请选择视频文件!');
        return;
      }
      this.phoneBar.sendVideoFile(this.selectedVideoFile);
    },

    /**
     * 填充业务组选项（与 source 一致）
     */
    populateGroupIdOptions() {
      const groups = this.phoneBar.callConfig.groups;
      if (groups) {
        this.groupList = [...groups];
        // 默认选中第一个（与 source 一致）
        if (this.groupList.length > 0 && !this.selectedGroupId) {
          this.selectedGroupId = this.groupList[0].groupId;
        }
      }

      // 确保在下一个 DOM 更新周期刷新成员列表
      this.$nextTick(() => {
        this.refreshMemberIdList();
      });
    },

    /**
     * 业务组改变处理
     */
    handleGroupIdChange() {
      // 成员列表会自动通过 computed 过滤
      this.selectedMember = '';
    },

    /**
     * 刷新成员 ID 列表
     */
    refreshMemberIdList() {
      if (this.selectedGroupId) {
        const origValue = this.selectedMember;
        // 成员列表会自动通过 computed 过滤
        // 判断原始选择项是否还存在，存在则重新赋值
        const hasValue = this.filteredMemberList.find(m => m.opnum === origValue);
        if (hasValue) {
          this.selectedMember = origValue;
        } else {
          this.selectedMember = '';
        }
      }
    },

    /**
     * 格式化成员文本（与 source 一致）
     */
    formatMemberText(member) {
      const statusMap = {
        1: '刚签入',
        2: '空闲',
        3: '忙碌',
        4: '通话中',
        5: '事后处理'
      };
      const statusText = statusMap[member.agentStatus] || '';
      return `${member.opnum}(${statusText})`;
    },

    /**
     * 执行转接（与 source 一致）
     */
    handleDoTransfer() {
      let transferType = 'outer';
      let phoneNumber = this.externalPhoneNumber.trim();

      if (phoneNumber === '') {
        transferType = 'inner';
        if (!this.selectedGroupId) {
          alert('请选择业务组!');
          return;
        }
        if (!this.selectedMember) {
          alert('请选择要转接的坐席成员!');
          return;
        }

        const member = this.filteredMemberList.find(m => m.opnum === this.selectedMember);
        if (member && member.agentStatus !== 2) {
          alert('请选择空闲的坐席成员!');
          return;
        }

        if (this.selectedMember === this.phoneBar.getOpNum()) {
          alert('不能转给自己，请选择其他坐席成员!');
          return;
        }
        phoneNumber = this.selectedMember;
      }

      // 隐藏转接区域（与 source 一致）
      this.showTransferArea = false;
      this.showDoTransferBtn = false;

      this.phoneBar.transferCall(phoneNumber, transferType);
    },

    /**
     * 执行咨询（与 source 一致）
     */
    handleDoConsultation() {
      let transferType = 'outer';
      let phoneNumber = this.externalPhoneNumber.trim();

      if (phoneNumber === '') {
        transferType = 'inner';
        if (!this.selectedGroupId) {
          alert('请选择业务组!');
          return;
        }
        if (!this.selectedMember) {
          alert('请选择要咨询的坐席成员!');
          return;
        }

        const member = this.filteredMemberList.find(m => m.opnum === this.selectedMember);
        if (member && member.agentStatus !== 2) {
          alert('请选择空闲的坐席成员!');
          return;
        }

        if (this.selectedMember === this.phoneBar.getOpNum()) {
          alert('不能咨询自己，请选择其他坐席成员!');
          return;
        }
        phoneNumber = this.selectedMember;
      }

      // 隐藏咨询区域（与 source 一致）
      this.showTransferArea = false;
      this.showDoConsultationBtn = false;

      // 直接调用 callControl 方法，传入正确的参数
      this.phoneBar.callControl("consultation", {"to": phoneNumber, "transferType": transferType});
    },

    /**
     * 接回客户
     */
    handleStopCallWait() {
      this.phoneBar.stopCallWaitBtnClickUI();
    },

    /**
     * 转接客户
     */
    handleTransferCallWait() {
      this.phoneBar.transferCallWaitBtnClickUI();
    },

    /**
     * 添加会议成员
     */
    handleAddConferenceMember() {
      if (!this.newMemberName || this.newMemberName.trim() === '') {
        alert('请填写参会者姓名!');
        return;
      }
      if (!this.newMemberPhone || this.newMemberPhone.trim() === '') {
        alert('请填写参会者手机号!');
        return;
      }

      const existMember = this.conferenceMembers.find(m => m.phone === this.newMemberPhone.trim());
      if (existMember) {
        alert('会议成员已经存在，请不要重复添加!');
        return;
      }

      // 添加到成员列表
      this.conferenceMembers.push({
        name: this.newMemberName.trim(),
        phone: this.newMemberPhone.trim(),
        callType: this.newMemberCallType,
        videoLevel: this.newMemberVideoLevel,
        status: '即将呼叫',
        muted: false,
        vmuted: false,
        showReInvite: false,
        statusColor: 'black'
      });

      // 调用工具条方法添加成员
      this.phoneBar.conferenceAddMembers([
        {
          name: this.newMemberName.trim(),
          phone: this.newMemberPhone.trim(),
          callType: this.newMemberCallType,
          videoLevel: this.newMemberVideoLevel
        }
      ]);

      // 清空输入框
      this.newMemberName = '';
      this.newMemberPhone = '';
    },

    /**
     * 禁言成员
     */
    handleMuteMember(phone) {
      this.phoneBar.conferenceMuteMember(phone);
    },

    /**
     * 禁用视频成员
     */
    handleVMuteMember(phone) {
      this.phoneBar.conferenceVMuteMember(phone);
    },

    /**
     * 移除成员
     */
    handleRemoveMember(phone) {
      const memberItemObj = document.getElementById('conf_member_' + phone);
      const statusEl = memberItemObj ? memberItemObj.querySelector('.conf_status') : null;

      if (statusEl && statusEl.textContent === '通话中') {
        this.phoneBar.conferenceRemoveMembers(phone);
      }

      this.conferenceMembers = this.conferenceMembers.filter(m => m.phone !== phone);
    },

    /**
     * 重新邀请成员
     */
    handleReInviteMember(member) {
      this.phoneBar.conferenceAddMemberBtnUI(1, member.phone, member.name);
    },

    /**
     * 会议开始回调
     */
    onConferenceStart() {
      this.conferenceStarted = true;
      this.showConferenceMemberList = true;
      const tips = '多方通话进行中';
      this.callStatus = tips;
      this.agentStatus = tips;
      // 禁用外呼按钮
      // 禁用置闲按钮
      // 禁用签出按钮
    },

    /**
     * 会议结束回调
     */
    onConferenceEnd() {
      this.conferenceStarted = false;
      this.showConferenceMemberList = false;
      this.showConferenceArea = false;
      const tips = '多方通话结束';
      this.callStatus = tips;
      this.agentStatus = tips;
      this.conferenceMembers = [];
    },

    /**
     * 更新会议成员状态
     */
    updateConferenceMemberStatus(phone, status, color) {
      const member = this.conferenceMembers.find(m => m.phone === phone);
      if (member) {
        member.status = status;
        member.statusColor = color;
        member.muted = false;
        member.vmuted = false;
      }
    },

    /**
     * 更新会议成员挂机状态
     */
    updateConferenceMemberHangup(phone, obj) {
      const member = this.conferenceMembers.find(m => m.phone === phone);
      if (member) {
        const answerStatus = obj.answeredTime === 0 ? '未接通' : obj.hangupClause;
        const color = obj.answeredTime === 0 ? 'red' : 'green';
        member.status = `已挂机 (${answerStatus})`;
        member.statusColor = color;
        member.showReInvite = true;
      }
    },

    /**
     * 获取禁言图标
     */
    getMuteIcon(muted) {
      return muted
        ? require('@/assets/callCenterPhoneBarSdk/images/unmute.jpg')
        : require('@/assets/callCenterPhoneBarSdk/images/mute.jpg');
    },

    /**
     * 获取视频禁用图标
     */
    getVMuteIcon(vmuted) {
      return vmuted
        ? require('@/assets/callCenterPhoneBarSdk/images/no_video.jpg')
        : require('@/assets/callCenterPhoneBarSdk/images/video.jpg');
    },

    /**
     * 处理 ASR 消息
     */
    handleAsrMessage(data) {
      // 只有在客户表单显示时才显示聊天容器
      if (this.showCustomerForm) {
        this.showChatContainer = true;
      }
      const { status, object } = data;
      if (status === 619 && object) {
        const { role, text, vadType } = object;
        if (vadType === 1) {
          this.addMessageToChat(role, text);
        }
      } else if (status === 620 || status === 621) {
        this.addSystemMessage('对话已结束。');
      }
    },

    /**
     * 添加聊天消息
     */
    addMessageToChat(role, text) {
      this.chatMessages.push({
        role: role,
        text: text
      });
      // 滚动到底部
      this.$nextTick(() => {
        const chatMessages = document.getElementById('chat-messages');
        if (chatMessages) {
          chatMessages.scrollTop = chatMessages.scrollHeight;
        }
      });
    },

    /**
     * 添加系统消息
     */
    addSystemMessage(text) {
      this.systemMessages.push(text);
    },

    /**
     * 加载历史沟通记录
     */
    loadCommunicationHistory() {
      getCustCommunicationInfo(this.phoneNumber,2,this.currentCallUuid,this.dialMode).then(response => {
        if(response.code === 0 && response.data){
          const data = response.data;

          // 填充客户信息
          if(data.ccCustInfo){
            const custInfo = data.ccCustInfo;
            this.customerForm.id = custInfo.id || '';
            this.customerForm.custName = custInfo.custName || '';
            this.customerForm.province = custInfo.province || '';
            this.customerForm.city = custInfo.city || '';
            this.customerForm.county = custInfo.county || ''; // 注意：表单绑定的是 county，数据库字段也是 county
            this.customerForm.provinceCode = custInfo.provinceCode || '';
            this.customerForm.cityCode = custInfo.cityCode || '';
            this.customerForm.countyCode = custInfo.countyCode || '';
            this.customerForm.address = custInfo.address || '';
            this.customerForm.gender = String(custInfo.gender) || '0';
          }

          // 填充历史沟通记录
          if(data.ccCustInfo && data.ccCustInfo.callRecordList && data.ccCustInfo.callRecordList.length > 0){
            let historyText = '';
            data.ccCustInfo.callRecordList.forEach((record, index) => {
              if (index > 0) {
                historyText += '\n';
              }
              historyText += `沟通时间：${record.createTime}\n沟通内容：${record.notes}`;
            });
            this.customerForm.communicationHistory = historyText;
          } else {
            this.customerForm.communicationHistory = '暂无历史沟通记录';
          }

          // 加载省份列表 - 保存所有省份数据 (deep=0)
          if(data.provinces && data.provinces.length > 0){
            this.provinceList = data.provinces.map(p => ({
              id: p.id,
              value: p.extId,
              label: p.extName,
              code: p.extId,
              pid: p.pid,
              deep: p.deep
            }));
          }

          // 加载城市列表 - 保存所有城市数据 (deep=1)
          if(data.citys && data.citys.length > 0){
            this.allCityList = data.citys.map(c => ({
              id: c.id,
              value: c.extId,
              label: c.extName,
              code: c.extId,
              pid: c.pid,
              deep: c.deep
            }));
          }

          // 加载区县列表 - 保存所有区县数据 (deep=2)
          if(data.countys && data.countys.length > 0){
            this.allCountyList = data.countys.map(d => ({
              id: d.id,
              value: d.extId,
              label: d.extName,
              code: d.extId,
              pid: d.pid, // 区县的 pid 指向市级的 id
              deep: d.deep
            }));
          }
        }else{
          this.customerForm.communicationHistory = '暂无历史沟通记录';
        }
        this.outboundCdrList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },

    /**
     * 保存客户信息表单
     */
    saveCustomerForm() {
      const callRecordData = {
        notes: this.customerForm.notes,
        callType: 2,
        uuid: this.currentCallUuid
      };

      // 组装完整的客户信息
      const customerData = {
        id: this.customerForm.id,
        phoneNum: this.phoneNumber,
        custName: this.customerForm.custName,
        province: this.customerForm.province,
        provinceCode: this.customerForm.provinceCode,
        city: this.customerForm.city,
        cityCode: this.customerForm.cityCode,
        county: this.customerForm.county,
        countyCode: this.customerForm.countyCode,
        address: this.customerForm.address,
        gender: this.customerForm.gender,
        notes: this.customerForm.notes,
        opNum: this.opNum,
        userName: this.userName,
        callRecord: JSON.stringify(callRecordData)
      };

      addCustcallrecord(customerData).then(response => {
        if(response.code === 0){
          this.$message.success('客户信息保存成功');
        }else{
          this.$message.error(response.msg || '保存失败');
        }
      });
    },

    /**
     * 关闭客户信息表单
     */
    closeCustomerForm() {
      this.showCustomerForm = false;
      this.showChatContainer = false; // 同时隐藏聊天窗口
      // 清空聊天消息数据
      this.chatMessages = [];
      this.systemMessages = [];
      // 清空表单
      this.customerForm = {
        id: '',
        phoneNum: this.phoneNumber,
        custName: '',
        province: '',
        provinceCode: '',
        city: '',
        cityCode: '',
        county: '',
        countyCode: '',
        address: '',
        gender: '0',
        notes: '',
        callRecord: '',
        communicationHistory: ''
      };
      this.currentCallUuid = '';
      this.cityList = [];
      this.countyList = [];
      // 不清空全局省市区数据，以便下次使用
    },

    /**
     * 省份改变时触发
     */
    handleProvinceChange(selectedProvince) {
      if (selectedProvince) {
        this.customerForm.province = selectedProvince.label;
        this.customerForm.provinceCode = selectedProvince.code;
        // 预加载对应城市数据：通过省份的 id 匹配城市的 pid
        if (this.allCityList && this.allCityList.length > 0) {
          this.cityList = this.allCityList.filter(c => c.pid === selectedProvince.id);
        } else {
          this.cityList = [];
        }
      }
      // 清空城市和区县的选择
      this.customerForm.city = '';
      this.customerForm.cityCode = '';
      this.customerForm.county = '';
      this.customerForm.countyCode = '';
      // 清空区县列表
      this.countyList = [];
    },

    /**
     * 城市改变时触发
     */
    handleCityChange(value) {
      // 从城市列表中查找选中的城市
      const selectedCity = this.cityList.find(c => c.value === value);
      if (selectedCity) {
        this.customerForm.city = selectedCity.label;
        this.customerForm.cityCode = selectedCity.code;

        // 预加载对应区县数据：通过城市的 id 匹配区县的 pid
        if (this.allCountyList && this.allCountyList.length > 0) {
          this.countyList = this.allCountyList.filter(d => d.pid === selectedCity.id);
        } else {
          this.countyList = [];
        }
      }
      // 清空区县表单
      this.customerForm.county = '';
      this.customerForm.countyCode = '';
    },

    /**
     * 区县改变时触发
     */
    handleDistrictChange(value) {
      // 从区县列表中查找选中的区县
      const selectedDistrict = this.countyList.find(d => d.value === value);
      if (selectedDistrict) {
        this.customerForm.county = selectedDistrict.label;
        this.customerForm.countyCode = selectedDistrict.code;
      }
    },

    /**
     * 通话结束后处理
     */
    handleCallEnd() {
      if (!this.currentCallUuid) {
        console.warn('[通话结束] 未获取到通话 UUID');
        return;
      }

      // 捕获当前通话 UUID 到局部变量，防止频繁外呼时被新通话覆盖
      const callUuid = this.currentCallUuid;

      // 延时10秒异步处理通话结束同步
      setTimeout(() => {
        callEndSyncByUuid({ uuid: callUuid }).then(() => {
        }).catch(error => {
          console.error('[通话结束] 后端同步通话记录接口调用失败, UUID:', callUuid, ', 错误:', error);
        });
      }, 10000);
    },
  }
};
</script>

<style scoped>
.call-center-phone-bar {
  background: transparent;
  padding: 20px;
  border-radius: 12px;
  min-height: 200px;
}

/* 状态显示区域 */
.call-center-phone-bar table {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}

.call-center-phone-bar .status4 {
  color: #409EFF;
  font-weight: 600;
  font-size: 14px;
  padding: 4px 8px;
  background: rgba(64, 158, 255, 0.1);
  border-radius: 4px;
}

/* 拨号盘区域 */
.call-center-phone-bar .head_dial {
  padding: 15px;
  background: #f5f7fa;
  border-radius: 8px;
  margin-bottom: 15px;
}

.call-center-phone-bar .dial {
  float: left;
  margin-right: 20px;
}

.call-center-phone-bar .dial dt {
  padding-bottom: 8px;
}

/* 拨号方式选择框 */
.call-center-phone-bar .dial-mode-select {
  border: 2px solid #e0e6ed;
  border-radius: 8px;
  height: 36px;
  font-size: 14px;
  background: linear-gradient(to right, #f5f7fa, #ffffff);
  color: #606266;
  text-indent: 10px;
  width: 200px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
  cursor: pointer;
  margin-bottom: 8px;
  font-weight: 500;
}

.call-center-phone-bar .dial-mode-select:hover {
  border-color: #409EFF;
  box-shadow: 0 4px 10px rgba(64, 158, 255, 0.15);
}

.call-center-phone-bar .dial-mode-select:focus {
  border-color: #409EFF;
  outline: none;
  box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.2);
}

.call-center-phone-bar .tel_txt {
  border: 2px solid #e0e6ed;
  border-radius: 8px;
  height: 42px;
  font-size: 16px;
  background: #FFFFFF;
  color: #2c3e50;
  text-indent: 15px;
  width: 200px;
  transition: all 0.3s ease;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
}

.call-center-phone-bar .tel_txt:focus {
  border-color: #409EFF;
  outline: none;
  box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
}

.call-center-phone-bar .tel_txt::placeholder {
  color: #909399;
}

.call-center-phone-bar .dial dd ul {
  border: 2px solid #e0e6ed;
  background: #FFFFFF;
  border-radius: 8px;
  height: auto;
  width: 100px;
  margin-left: 0;
  padding: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.call-center-phone-bar .dial dd ul li {
  height: auto;
  line-height: 28px;
  margin-left: 0;
  padding-left: 10px;
  font-weight: 500;
}

.call-center-phone-bar .dial dd ul li.status1 { color: #E6A23C; }
.call-center-phone-bar .dial dd ul li.status2 { color: #67C23A; }
.call-center-phone-bar .dial dd ul li.status3 { color: #67C23A; }
.call-center-phone-bar .dial dd ul li.status4 { color: #409EFF; }
.call-center-phone-bar .dial dd ul li.status5 { color: #909399; }

/* 解密状态提示 */
.call-center-phone-bar .decrypting-tip {
  color: #E6A23C;
  font-size: 12px;
  margin-top: 5px;
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

/* 按钮组 */
.call-center-phone-bar .dial_btn {
  float: left;
  display: flex;
  align-items: center;
  gap: 12px;
}

.call-center-phone-bar .dial_btn li {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 10px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  border: 2px solid #e8e8e8;
}

.call-center-phone-bar .dial_btn li:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
  border-color: #409EFF;
}

.call-center-phone-bar .dial_btn li a {
  display: block;
  border-radius: 50%;
  border: 3px solid #409EFF;
  width: 56px;
  height: 56px;
  margin: 0 auto 8px;
  transition: all 0.3s ease;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
  background-color: #409EFF;
}

.call-center-phone-bar .dial_btn li span {
  font-size: 12px;
  color: #606266;
  font-weight: 500;
  text-align: center;
}

/* 按钮激活状态 */
.call-center-phone-bar .wh_btn.on,
.call-center-phone-bar .zj_btn.on,
.call-center-phone-bar .gj_btn.on,
.call-center-phone-bar .bc_btn.on,
.call-center-phone-bar .zjie_btn.on,
.call-center-phone-bar .myd_btn.on,
.call-center-phone-bar .jt_btn.on,
.call-center-phone-bar .qca_btn.on,
.call-center-phone-bar .lj_btn.on,
.call-center-phone-bar .qc_btn.on,
.call-center-phone-bar .hy_btn.on,
.call-center-phone-bar .sx_btn.on,
.call-center-phone-bar .xx_btn.on,
.call-center-phone-bar .wc_btn.on,
.call-center-phone-bar .jy_btn.on,
.call-center-phone-bar .xz_btn.on,
.call-center-phone-bar .sm_btn.on,
.call-center-phone-bar .qz_btn.on {
  filter: grayscale(0%) !important;
  transform: scale(1.05);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
  border-color: #409EFF !important;
  background-color: #409EFF !important;
}

/* 外呼按钮 - 绿色 */
.call-center-phone-bar .wh_btn,
.call-center-phone-bar .wh_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/call.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .wh_btn.on {
  filter: grayscale(0%);
}

/* 挂机按钮 - 红色 */
.call-center-phone-bar .gj_btn,
.call-center-phone-bar .gj_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/hangup_enable.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .gj_btn.on {
  filter: grayscale(0%);
}

/* 保持按钮 - 橙色 */
.call-center-phone-bar .bc_btn,
.call-center-phone-bar .bc_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/hold.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .bc_btn.on {
  filter: grayscale(0%);
}

/* 取消保持按钮 - 蓝色 */
.call-center-phone-bar .bc2_btn,
.call-center-phone-bar .bc2_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/unhold.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .bc2_btn.on {
  filter: grayscale(0%);
}

/* 转接按钮 - 紫色 */
.call-center-phone-bar .zjie_btn,
.call-center-phone-bar .zjie_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/transfer.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .zjie_btn.on {
  filter: grayscale(0%);
}

/* 咨询按钮 - 青色 */
.call-center-phone-bar .zixun_btn,
.call-center-phone-bar .zixun_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/consultation.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .zixun_btn.on {
  filter: grayscale(0%);
}

/* 会议按钮 - 深蓝色 */
.call-center-phone-bar .hy_btn,
.call-center-phone-bar .hy_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/conference.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .hy_btn.on {
  filter: grayscale(0%);
}

/* 上线按钮 - 蓝绿色 */
.call-center-phone-bar .sx_btn,
.call-center-phone-bar .sx_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/online.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .sx_btn.on {
  filter: grayscale(0%);
}

/* 置闲按钮 - 灰色 */
.call-center-phone-bar .xz_btn,
.call-center-phone-bar .xz_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/setFree.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
}

.call-center-phone-bar .xz_btn.on {
  filter: grayscale(0%);
}

/* 置忙按钮 - 橙红色 */
.call-center-phone-bar .sm_btn,
.call-center-phone-bar .sm_btn.on {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/busy_enable.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(100%);
  border: 3px solid #409EFF;
  background-color: #409EFF;
}

.call-center-phone-bar .sm_btn.on {
  filter: grayscale(0%);
  border-color: #409EFF;
  background-color: #409EFF;
}

/* 强置按钮 - 始终黄色 */
.call-center-phone-bar .qz_btn {
  background-image: url("../../assets/callCenterPhoneBarSdk/images/phonebar/reset.png");
  background-repeat: no-repeat;
  background-size: contain;
  filter: grayscale(0%);
  border: 3px solid #E6A23C;
  background-color: #E6A23C;
}

/* 强置按钮激活状态也保持黄色 */
.call-center-phone-bar .qz_btn.on {
  filter: grayscale(0%);
  border-color: #E6A23C !important;
  background-color: #E6A23C !important;
}

/* 下拉选择框 */
.call-center-phone-bar select {
  border: 2px solid #e0e6ed;
  border-radius: 6px;
  height: 32px;
  background: #FFFFFF;
  color: #606266;
  font-size: 13px;
  padding: 0 10px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.call-center-phone-bar select:hover {
  border-color: #409EFF;
}

.call-center-phone-bar select:focus {
  border-color: #409EFF;
  outline: none;
  box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
}

/* 输入框 */
.call-center-phone-bar input[type='text'] {
  border: 2px solid #e0e6ed;
  border-radius: 6px;
  height: 32px;
  font-size: 14px;
  background: #FFFFFF;
  color: #606266;
  text-indent: 10px;
  transition: all 0.3s ease;
}

.call-center-phone-bar input[type='text']:focus {
  border-color: #409EFF;
  outline: none;
  box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
}

/* 按钮 */
.call-center-phone-bar input[type='button'] {
  border: none;
  border-radius: 6px;
  height: 32px;
  font-size: 13px;
  background: linear-gradient(to right, #409EFF, #66b1ff);
  color: #FFFFFF;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

.call-center-phone-bar input[type='button']:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
}

.call-center-phone-bar input[type='button']:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* 会议成员列表 */
.call-center-phone-bar #conference_member_list ul {
  float: left;
  overflow: hidden;
  width: 100%;
}

.call-center-phone-bar #conference_member_list li {
  float: left;
  border-style: solid;
  border-width: 1px;
  border-color: #e0e6ed;
  background: #f5f7fa;
  width: 700px;
  line-height: 40px;
  margin: 4px 0;
  border-radius: 6px;
  transition: all 0.3s ease;
}

.call-center-phone-bar #conference_member_list li:hover {
  background: #ecf5ff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
}

.call-center-phone-bar .conf_name {
  padding-left: 15px;
  width: 100px;
  display: inline-block;
  font-weight: 500;
}

.call-center-phone-bar .conf_phone {
  width: 130px;
  display: inline-block;
  color: #606266;
}

.call-center-phone-bar .conf_call_type {
  padding-left: 10px;
  width: 50px;
  display: inline-block;
}

.call-center-phone-bar .conf_video_level {
  padding-left: 10px;
  padding-right: 10px;
  width: 50px;
  display: inline-block;
}

.call-center-phone-bar .conf_status {
  width: 120px;
  display: inline-block;
  font-weight: 500;
}

.call-center-phone-bar .conf_mute,
.call-center-phone-bar .conf_vmute,
.call-center-phone-bar .conf_remove,
.call-center-phone-bar .conf_re_invite {
  width: 50px;
  display: inline-block;
  text-align: center;
}

.call-center-phone-bar .conf_mute img,
.call-center-phone-bar .conf_vmute img {
  transition: all 0.3s ease;
}

.call-center-phone-bar .conf_mute a:hover img,
.call-center-phone-bar .conf_vmute a:hover img {
  transform: scale(1.2);
}

/* ASR 聊天容器 */
.call-center-phone-bar #chat-container {
  width: 90%;
  max-width: 600px;
  margin: 20px auto;
  background: rgba(255, 255, 255, 0.98);
  border: 1px solid #e0e6ed;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 15px;
}

.call-center-phone-bar .message {
  padding: 12px 16px;
  margin: 10px 0;
  border-radius: 12px;
  animation: slideIn 0.3s ease;
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.call-center-phone-bar .customer {
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  border-left: 4px solid #909399;
}

.call-center-phone-bar .agent {
  background: linear-gradient(135deg, #f0f9ff 0%, #c6efff 100%);
  border-right: 4px solid #409EFF;
}

.call-center-phone-bar .system-message {
  text-align: center;
  color: #909399;
  font-style: italic;
  padding: 10px;
  background: rgba(245, 247, 250, 0.5);
  border-radius: 8px;
  margin: 10px 0;
}

.call-center-phone-bar .message-container {
  display: flex;
  flex-direction: column;
  max-height: 400px;
  overflow-y: auto;
}

.call-center-phone-bar .message-container::-webkit-scrollbar {
  width: 6px;
}

.call-center-phone-bar .message-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.call-center-phone-bar .message-container::-webkit-scrollbar-thumb {
  background: #c0c4cc;
  border-radius: 3px;
}

.call-center-phone-bar .message-container::-webkit-scrollbar-thumb:hover {
  background: #909399;
}

.call-center-phone-bar .message-header {
  font-weight: 600;
  margin-bottom: 6px;
  color: #606266;
  font-size: 13px;
}

.call-center-phone-bar .message-content {
  color: #303133;
  font-size: 14px;
  line-height: 1.6;
}

/* 客户信息表单 */
.call-center-phone-bar .customer-form {
  background: rgba(255, 255, 255, 0.98);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  border: 1px solid #e0e6ed;
}

.call-center-phone-bar .customer-form h3 {
  background: linear-gradient(to right, #409EFF, #66b1ff);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  border-left: none;
  padding-left: 0;
}

/* 转接和咨询下拉框 */
::v-deep #transfer_to_groupIds,
::v-deep #transfer_to_member {
  width: 100%;
  border: 2px solid #e0e6ed;
  border-radius: 6px;
  background: #FFFFFF;
  transition: all 0.3s ease;
}

::v-deep #transfer_to_groupIds:hover,
::v-deep #transfer_to_member:hover {
  border-color: #409EFF;
}

::v-deep #transfer_to_groupIds:focus,
::v-deep #transfer_to_member:focus {
  border-color: #409EFF;
  box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
}

::v-deep .el-select .el-input__inner {
  height: 32px;
  line-height: 32px;
  border-radius: 6px;
  border: 2px solid #e0e6ed;
  transition: all 0.3s ease;
}

::v-deep .el-select .el-input__inner:hover {
  border-color: #409EFF;
}

::v-deep .el-button {
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.3s ease;
}

::v-deep .el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 确保样式能够覆盖到子组件 */
::v-deep .dial_btn li a {
  cursor: pointer;
}

/* 转接和咨询区域 */
.call-center-phone-bar #transfer_area {
  background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%);
  border-radius: 12px;
  padding: 20px !important;
  margin-top: 15px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  border: 1px solid #e0e6ed;
  animation: slideDownFade 0.3s ease;
}

@keyframes slideDownFade {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 会议区域 */
.call-center-phone-bar #conference_area {
  background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
  border-radius: 12px;
  padding: 20px !important;
  margin-top: 15px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  border: 1px solid #e0e6ed;
  animation: slideDownFade 0.3s ease;
}

::v-deep input[type='button']:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none !important;
}

/* 表格第一行样式 */
.call-center-phone-bar table tr:first-child {
  background: linear-gradient(to right, #667eea, #764ba2);
}

.call-center-phone-bar table tr:first-child td {
  padding: 15px 20px;
}

.call-center-phone-bar table tr:first-child b {
  color: #FFFFFF;
  font-weight: 600;
}

.call-center-phone-bar table tr:first-child .status4 {
  color: #FFFFFF;
  background: rgba(255, 255, 255, 0.2);
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .call-center-phone-bar {
    padding: 15px;
  }

  .call-center-phone-bar .dial_btn {
    flex-wrap: wrap;
  }

  .call-center-phone-bar .dial_btn li {
    margin: 4px;
  }
}
</style>
