<template>
  <div class="chat-workbench-container">
    <div class="chat-workbench-card">
      <!-- 1. 左侧会话侧边栏 -->
      <div class="chat-sidebar">
        <!-- 搜索与 Tab 切换区 -->
        <div class="sidebar-header">
          <div class="tab-wrap">
            <div 
              :class="['tab-item', activeTab === 'mini' ? 'active' : '']" 
              @click="activeTab = 'mini'"
            >
              <span>小程序</span>
              <el-badge v-if="miniUnread > 0" :value="miniUnread" class="unread-badge" />
            </div>
            <div 
              :class="['tab-item', activeTab === 'merchant' ? 'active' : '']" 
              @click="activeTab = 'merchant'"
            >
              <span>商家</span>
              <el-badge v-if="merchantUnread > 0" :value="merchantUnread" class="unread-badge" />
            </div>
          </div>
          <div class="search-wrap">
            <el-input
              v-model="searchQuery"
              :prefix-icon="Search"
              placeholder="搜索会员/商家..."
              clearable
              class="custom-search"
            />
          </div>
        </div>

        <!-- 历史会话列表 -->
        <div class="session-list-container">
          <el-scrollbar>
            <div 
              v-for="item in filteredSessionList" 
              :key="item.id" 
              :class="['session-item', activeSessionId === item.id ? 'active' : '']"
              @click="selectSession(item)"
            >
              <div class="avatar-wrap">
                <el-avatar :size="48" :src="item.avatar" />
                <div v-if="item.status === 'online'" class="online-indicator"></div>
              </div>
              <div class="session-info">
                <div class="top-line">
                  <span class="name text-ellipsis">{{ item.name }}</span>
                  <span class="time">{{ item.lastTime }}</span>
                </div>
                <div class="bottom-line">
                  <span class="last-msg text-ellipsis">{{ item.lastMsg }}</span>
                  <el-badge v-if="item.unread > 0" :value="item.unread" :max="99" class="item-unread" />
                </div>
              </div>
            </div>
            <div v-if="filteredSessionList.length === 0" class="empty-placeholder">
              <el-empty description="暂无咨询列表" :image-size="60" />
            </div>
          </el-scrollbar>
        </div>
      </div>

      <!-- 2. 中间聊天主区域 -->
      <div class="chat-main-area">
        <!-- 聊天顶栏 -->
        <div class="chat-main-header">
          <div class="current-user-info">
            <div class="title-wrap">
              <h2 class="title">{{ activeSession?.name || '等待接待' }}</h2>
              <div class="user-status">
                <span class="dot"></span>
                {{ activeTab === 'mini' ? '会员咨询中' : '商家咨询中' }}
              </div>
            </div>
          </div>
          <div class="header-actions">
            <span class="waiter-status-label">坐席在线</span>
            <el-switch v-model="isWaiterOnline" active-color="#10b981" />
            <el-divider direction="vertical" />
            <el-button link :icon="CircleClose" :disabled="!hasActiveSession" @click="handleEndSession">强制结束</el-button>
          </div>
        </div>

        <!-- 消息记录区域 -->
        <div class="message-feed" ref="msgContainerRef">
          <div v-if="!hasActiveSession" class="empty-placeholder empty-chat-main">
            <el-empty description="当前没有会话" :image-size="80" />
          </div>
          <div 
            v-else
            v-for="(msg, index) in messageList" 
            :key="index" 
            :class="['message-row', msg.sender === 'waiter' ? 'row-right' : 'row-left']"
          >
            <el-avatar :size="38" :src="msg.sender === 'waiter' ? (msg.senderAvatar && isValidAvatarUrl(msg.senderAvatar) ? msg.senderAvatar : waiterAvatar) : (resolvedUserAvatar)" class="avatar" />
            <div class="msg-content-box">
              <div class="time-stamp">{{ msg.time }}</div>
              
              <!-- 文本 -->
              <div v-if="msg.type === 'text'" class="msg-bubble" v-html="formatContent(msg.content)"></div>
              
              <!-- 图片消息 -->
              <div v-else-if="msg.type === 'image'" class="msg-bubble image-bubble">
                <el-image 
                  :src="msg.payload.url" 
                  :preview-src-list="[msg.payload.url]"
                  fit="cover"
                  class="chat-img"
                  hide-on-click-modal
                  preview-teleported
                />
              </div>

               <!-- 文件/附件 -->
              <div v-else-if="msg.type === 'file'" class="msg-bubble file-bubble">
                <div class="file-main">
                  <el-icon :size="32" color="#2563eb"><Document /></el-icon>
                  <div class="file-info">
                    <div class="f-name text-ellipsis">{{ msg.payload.name }}</div>
                    <div class="f-size">{{ msg.payload.size }}</div>
                  </div>
                </div>
                <div class="file-actions">
                  <el-button link type="primary" size="small" @click="previewFile(msg.payload)">预览</el-button>
                  <el-divider direction="vertical" />
                  <el-button link type="primary" size="small" @click="downloadFile(msg.payload)">下载</el-button>
                </div>
              </div>

              <!-- 岗位卡片 -->
              <div v-else-if="msg.type === 'job_card'" class="msg-card job-card">
                <div class="card-body">
                  <div class="card-top">
                    <span class="j-title">{{ msg.payload.title }} <el-tag v-if="msg.payload.urgency" size="small" type="danger" effect="dark">{{ msg.payload.urgency }}</el-tag></span>
                    <span class="j-salary">{{ msg.payload.salary }}</span>
                  </div>
                  <div class="j-tags">
                    <span v-for="tag in msg.payload.tags" :key="tag" class="j-tag">{{ tag }}</span>
                  </div>
                  
                  <!-- 新增：招录与截止时间 -->
                  <div class="j-extra-info" v-if="msg.payload.quota || msg.payload.deadline">
                    <div class="ex-item" v-if="msg.payload.quota"><el-icon><User /></el-icon> 招录 {{ msg.payload.quota }}</div>
                    <div class="ex-item" v-if="msg.payload.deadline"><el-icon><Clock /></el-icon> 截止时间：{{ msg.payload.deadline }}</div>
                  </div>

                  <div class="j-company-info">
                    <div class="c-logo">
                       <el-image style="width: 24px; height: 24px" src="https://api.dicebear.com/7.x/initials/svg?seed=HJ" />
                    </div>
                    <span class="c-name">{{ msg.payload.company }} <el-icon color="#10b981"><SuccessFilled /></el-icon></span>
                    <span class="j-loc">{{ msg.payload.location }}</span>
                  </div>
                </div>
              </div>

              <!-- 结算单卡片 (支持失效状态) -->
              <div v-else-if="msg.type === 'order_card'" class="msg-card order-card" :class="{'is-expired': msg.payload.status === '已失效'}">
                <div class="order-header">
                  <span class="o-title">{{ msg.payload.status === '已失效' ? '您有一笔待付款项' : '请核对并支付结算单' }}</span>
                  <span v-if="msg.payload.status === '已失效'" class="expired-text">已失效</span>
                  <div v-else class="o-header-right">
                    <span class="o-timer" v-if="msg.payload.countdown">{{ msg.payload.countdown }}s</span>
                    <el-tag size="small" type="warning" effect="dark">待支付</el-tag>
                  </div>
                </div>
                <div class="order-body">
                  <div class="o-subtitle" v-if="msg.payload.status === '已失效'">预定金支付通知</div>
                  <div class="o-row"><span class="o-label">项目名称:</span> <span class="o-val">{{ msg.payload.name }}</span></div>
                  <div class="o-row"><span class="o-label">支付金额:</span> <span class="o-price">￥ {{ msg.payload.price }}</span></div>
                </div>
                <div class="order-footer-btn" :class="{'expired-btn': msg.payload.status === '已失效'}">
                  {{ msg.payload.status === '已失效' ? '已失效' : '立即支付' }}
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 3. 输入操作区域 (带高度调整) -->
        <div class="input-panel-wrapper" :style="{ height: inputHeight + 'px' }">
          <div class="resizer" @mousedown="startResizing"></div>
          <div class="action-toolbar">
            <el-popover placement="top" :width="370" trigger="click" popper-class="emoji-popover-refined">
              <template #reference>
                <div class="tool-btn">
                  <el-icon :size="20"><ChatRound /></el-icon>
                </div>
              </template>
              <div class="emoji-picker-stage">
                <div class="picker-header">所有表情</div>
                <div class="picker-body">
                  <span v-for="emoji in emojiList" :key="emoji" class="emoji-node" @click="appendEmoji(emoji)">{{ emoji }}</span>
                </div>
              </div>
            </el-popover>
            
            <el-upload
              :show-file-list="false"
              :auto-upload="true"
              :http-request="handleImageUpload"
              class="tool-btn-upload"
            >
              <div class="tool-btn">
                <el-icon :size="20"><Picture /></el-icon>
              </div>
            </el-upload>
            
            <el-upload
              :show-file-list="false"
              :auto-upload="true"
              :http-request="handleFileUpload"
              class="tool-btn-upload"
            >
              <div class="tool-btn">
                <el-icon :size="20"><FolderOpened /></el-icon>
              </div>
            </el-upload>

            <el-popover v-if="activeTab === 'mini'" placement="top" :width="180" trigger="click" popper-class="biz-card-popover">
              <template #reference>
                <div class="tool-btn">
                  <el-icon :size="20"><Memo /></el-icon>
                </div>
              </template>
              <div class="biz-card-menu">
                <div class="menu-item" @click="openJobSelector('order')"><el-icon><CreditCard /></el-icon> 发送结算卡片</div>
                <div class="menu-item" @click="openJobSelector('job')"><el-icon><Briefcase /></el-icon> 发送岗位卡片</div>
              </div>
            </el-popover>
            
            <div class="spacer"></div>
            <div class="history-trigger" @click="showHistory = true">
              <el-icon><Clock /></el-icon>
              <span>历史记录</span>
            </div>
          </div>
          
          <div class="input-editor">
            <textarea 
              v-model="inputText" 
              :disabled="!hasActiveSession"
              placeholder="请输入您要回复的内容，按回车键快捷发送..." 
              @keyup.enter.exact.prevent="handleSend"
            ></textarea>
          </div>
          
          <div class="input-footer">
            <span class="hot-key">Enter 发送 / Shift+Enter 换行</span>
            <div class="btn-group">
              <el-button plain :disabled="!hasActiveSession" @click="handleEndSession">结束会话</el-button>
              <el-button type="primary" class="send-action" :disabled="!hasActiveSession" @click="handleSend">发送消息</el-button>
            </div>
          </div>
        </div>
      </div>

      <!-- 4. 右侧画像摘要 -->
      <div class="chat-profile-panel">
        <el-scrollbar>
          <div v-if="!hasActiveSession" class="empty-placeholder empty-profile-panel">
            <el-empty description="当前没有会话" :image-size="80" />
          </div>
          <!-- 访客(小程序)且没有学员信息时不显示右侧面板内容 -->
          <template v-else-if="activeTab === 'mini' && studentInfo">
          <div class="summary-card">
            <div class="avatar-ring">
              <el-avatar :size="80" :src="resolvedUserAvatar" />
            </div>
            <h3 class="uname">{{ studentInfo?.name || activeSession?.name }}</h3>
            <div class="tag-row">
              <span class="u-tag mini">
                小程序注册会员
              </span>
              <el-button type="primary" size="small" round @click="showFullArchive = true" class="archive-btn">
                会员详细档案
              </el-button>
            </div>
          </div>

          <!-- 联系信息 -->
          <div class="info-block">
            <div class="b-head"><el-icon><Phone /></el-icon> 联系信息</div>
            <div class="b-body contact">
              <div class="row"><span class="l">手机</span><span class="v">{{ studentInfo?.mobile || '未绑定' }}</span></div>
              <div class="row"><span class="l">邮箱</span><span class="v">{{ studentInfo?.email || '未留存' }}</span></div>
              <div class="row"><span class="l">地区</span><span class="v">{{ studentInfo?.workCity || studentInfo?.address || '未知' }}</span></div>
            </div>
          </div>

          <!-- 核心统计 -->
          <div class="info-block">
            <div class="b-head"><el-icon><User /></el-icon> 会员统计</div>
            <div class="b-body">
              <div class="stat-matrix">
                <div class="stat-item"><div class="num">{{ studentInfo?.consultationCount || 0 }}</div><div class="lab">咨询数</div></div>
                <div class="stat-item"><div class="num">{{ studentInfo?.evaluationCount || 0 }}</div><div class="lab">测评数</div></div>
                <div class="stat-item"><div class="num">{{ studentInfo?.isEmployed === '1' ? 1 : 0 }}</div><div class="lab">已入职</div></div>
              </div>
              <div class="sub-list">
                <div class="sl-item"><span>注册编号:</span> <b>{{ studentInfo?.studentNo || '--' }}</b></div>
                <div class="sl-item"><span>账号状态:</span> <el-tag size="small" :type="studentInfo?.status === '0' ? 'success' : 'danger'">{{ studentInfo?.status === '0' ? '正常' : '封禁' }}</el-tag></div>
              </div>
            </div>
          </div>

          <!-- 最近记录 -->
          <div class="info-block no-border">
            <div class="b-head"><el-icon><ShoppingCart /></el-icon> 最近订单</div>
            <div class="b-body">
              <div class="mini-order" v-for="(item, idx) in studentInfo?.orderList?.slice(0, 3)" :key="idx">
                <div class="o-main">
                  <div class="oname text-ellipsis">{{ item.orderNo }}</div>
                  <div class="ometa">{{ item.createTime }} · <span class="price-small">￥{{ item.totalAmount }}</span></div>
                </div>
                <div class="o-side">
                  <el-tag size="small" :type="getOrderStatusType(item.orderStatus)" effect="light" class="status-tag">
                    {{ getOrderStatusLabel(item.orderStatus) }}
                  </el-tag>
                </div>
              </div>
              <el-button link class="see-more" @click="showAllOrders = true">查看全部记录</el-button>
            </div>
          </div>
          </template>

          <!-- 商家渠道 - 显示真实商家数据 -->
          <template v-else-if="activeTab === 'merchant' && merchantInfo">
          <div class="summary-card">
            <div class="avatar-ring">
              <el-avatar :size="80" :src="resolvedUserAvatar" />
            </div>
            <h3 class="uname">{{ merchantInfo?.companyName || activeSession?.name }}</h3>
            <div class="tag-row">
              <span class="u-tag merchant">
                认证企业商户
              </span>
              <el-button type="primary" size="small" round @click="showFullArchive = true" class="archive-btn">
                商家详细档案
              </el-button>
            </div>
          </div>

          <!-- 联系信息 -->
          <div class="info-block">
            <div class="b-head"><el-icon><Phone /></el-icon> 联系信息</div>
            <div class="b-body contact">
              <div class="row"><span class="l">联系人</span><span class="v">{{ (merchantInfo?.surname || '') + (merchantInfo?.name || '') || '未填写' }}</span></div>
              <div class="row"><span class="l">手机</span><span class="v">{{ merchantInfo?.mobile || '未填写' }}</span></div>
              <div class="row"><span class="l">邮箱</span><span class="v">{{ merchantInfo?.officialAccount || '未填写' }}</span></div>
              <div class="row"><span class="l">地址</span><span class="v">{{ merchantInfo?.officeAddress || '未填写' }}</span></div>
            </div>
          </div>

          <!-- 商户统计 -->
          <div class="info-block">
            <div class="b-head"><el-icon><User /></el-icon> 商户资产</div>
            <div class="b-body">
              <div class="stat-matrix">
                <div class="stat-item"><div class="num">{{ merchantInfo?.applyStatus === 1 ? '已认证' : '待审核' }}</div><div class="lab">认证状态</div></div>
              </div>
              <div class="sub-list">
                <div class="sl-item"><span>申请编号:</span> <b>{{ merchantInfo?.applyNo || '--' }}</b></div>
                <div class="sl-item"><span>信用代码:</span> <b>{{ merchantInfo?.creditCode || '--' }}</b></div>
                <div class="sl-item"><span>入驻日期:</span> <b>{{ merchantInfo?.createTime || '--' }}</b></div>
              </div>
            </div>
          </div>

          <!-- 已购套餐 -->
          <div class="info-block no-border">
            <div class="b-head"><el-icon><ShoppingCart /></el-icon> 已购套餐</div>
            <div class="b-body">
              <div class="mini-order" v-for="(item, idx) in currentDisplayOrders.slice(0, 2)" :key="idx">
                <div class="o-main">
                  <div class="oname text-ellipsis">{{ item.name }}</div>
                  <div class="ometa">{{ item.time }} · <span class="price-small">{{ item.amount }}</span></div>
                </div>
                <div class="o-side">
                  <el-tag size="small" :type="getStatusType(item.status)" effect="light" class="status-tag">
                    {{ item.status }}
                  </el-tag>
                </div>
              </div>
              <el-button link class="see-more" @click="showAllOrders = true">查看全部记录</el-button>
            </div>
          </div>
          </template>

          <!-- 访客(小程序)无学员信息 或 商家无入驻信息 -->
          <template v-else>
            <div class="empty-placeholder empty-profile-panel">
              <el-empty :description="activeTab === 'mini' ? '暂无会员信息' : '暂无商家信息'" :image-size="80" />
            </div>
          </template>
        </el-scrollbar>
      </div>
    </div>

    <!-- 5. 全量档案侧滑 (Refined from Fig 3) -->
    <el-drawer 
      v-model="showFullArchive" 
      :title="activeTab === 'mini' ? '会员档案详情' : '商家入驻全量档案'" 
      size="1100px" 
      custom-class="archive-drawer-modern"
      append-to-body
    >
      <div class="archive-content">
        <!-- 头部综合信息区 (动态识别用户/商家) -->
        <div class="archive-header-card">
          <div class="h-left">
            <el-avatar :size="100" :src="resolvedUserAvatar" />
            <div class="h-tag">{{ activeTab === 'mini' ? '一周内到岗' : (merchantInfo?.applyStatus === 1 ? '已认证企业' : '待审核企业') }}</div>
          </div>
          <div class="h-main">
            <template v-if="activeTab === 'mini'">
              <div class="m-title">{{ studentInfo?.name || '未知' }} 
                <el-icon v-if="studentInfo?.gender === 'M'" color="#409eff"><Male /></el-icon>
                <el-icon v-if="studentInfo?.gender === 'F'" color="#f472b6"><Female /></el-icon>
              </div>
              <div class="m-grid">
                <div class="g-item"><label>身份证号:</label> {{ studentInfo?.idCardNumber || '未填写' }}</div>
                <div class="g-item"><label>联系电话:</label> {{ studentInfo?.mobile || '未填写' }}</div>
                <div class="g-item"><label>电子邮箱:</label> {{ studentInfo?.email || '未填写' }}</div>
                <div class="g-item"><label>求职意向:</label> {{ studentInfo?.jobIntention || '未填写' }}</div>
                <div class="g-item"><label>求职类型:</label> {{ studentInfo?.jobType || '未填写' }}</div>
                <div class="g-item"><label>毕业院校:</label> {{ studentInfo?.schoolName || '未填写' }}-{{ studentInfo?.grade || '' }}-{{ studentInfo?.education || '' }}</div>
                <div class="g-item"><label>实习时长:</label> {{ studentInfo?.internshipDuration || '未填写' }}</div>
                <div class="g-item"><label>注册日期:</label> {{ studentInfo?.createTime || '未填写' }}</div>
                <div class="g-item"><label>最后更新:</label> {{ studentInfo?.updateTime || '未填写' }}</div>
              </div>
            </template>
            <template v-else>
              <div class="m-title">{{ merchantInfo?.companyName || '未知企业' }}</div>
              <div class="m-grid">
                <div class="g-item"><label>统一社会信用代码:</label> {{ merchantInfo?.creditCode || '未填写' }}</div>
                <div class="g-item"><label>企业联系人:</label> {{ (merchantInfo?.surname || '') + (merchantInfo?.name || '') || '未填写' }}</div>
                <div class="g-item"><label>联系电话:</label> {{ merchantInfo?.mobile || '未填写' }}</div>
                <div class="g-item"><label>官方邮箱:</label> {{ merchantInfo?.officialAccount || '未填写' }}</div>
                <div class="g-item"><label>办公地址:</label> {{ merchantInfo?.officeAddress || '未填写' }}</div>
                <div class="g-item"><label>申请编号:</label> {{ merchantInfo?.applyNo || '未填写' }}</div>
                <div class="g-item"><label>认证状态:</label> {{ merchantInfo?.applyStatus === 1 ? '已认证' : '待审核' }}</div>
                <div class="g-item"><label>入驻日期:</label> {{ merchantInfo?.createTime || '未填写' }}</div>
                <div class="g-item" v-if="merchantInfo?.authLetter" style="grid-column: span 2; display: flex; align-items: flex-start; margin-top: 10px;">
                  <label>委托招聘证明:</label>
                  <el-image 
                    style="width: 140px; height: 100px; border-radius: 8px; border: 1px solid #f1f5f9; box-shadow: 0 4px 12px rgba(0,0,0,0.05);" 
                    :src="merchantInfo?.authLetterUrl" 
                    :preview-src-list="merchantInfo?.authLetterUrl ? [merchantInfo.authLetterUrl] : []"
                  />
                </div>
              </div>
            </template>
          </div>
        </div>

        <!-- 详细信息页签区 (仅会员显示) -->
        <el-tabs v-if="activeTab === 'mini'" v-model="archiveActiveTab" class="archive-tabs">
          <el-tab-pane label="在线简历" name="resume">
            <div class="pane-inner">
              <section class="a-section">
                <div class="s-head">教育经历</div>
                <el-table :data="studentInfo?.educationList || []" border stripe>
                  <el-table-column prop="school" label="学校" />
                  <el-table-column prop="education" label="学历" width="120" />
                  <el-table-column label="时间" width="220">
                    <template #default="scope">
                      {{ scope.row.startTime }} - {{ scope.row.endTime || '至今' }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="major" label="专业" />
                  <el-table-column prop="description" label="在校经历" />
                </el-table>
              </section>
              <section class="a-section mt-20">
                <div class="s-head">工作经历</div>
                <el-table :data="studentInfo?.experienceList || []" border stripe>
                  <el-table-column label="公司">
                    <template #default="scope">
                      {{ scope.row.isHidden === 1 ? '***（已屏蔽）' : scope.row.company }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="industry" label="行业" width="120" />
                  <el-table-column label="时间" width="220">
                    <template #default="scope">
                      {{ scope.row.startTime }} - {{ scope.row.endTime || '至今' }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="jobTitle" label="职位" />
                  <el-table-column prop="department" label="所属部门" />
                  <el-table-column prop="workContent" label="工作内容" />
                </el-table>
              </section>
              <section class="a-section mt-20">
                <div class="s-head">项目经历</div>
                <el-table :data="studentInfo?.projectList || []" border stripe>
                  <el-table-column prop="projectName" label="项目" />
                  <el-table-column prop="role" label="担任角色" width="120" />
                  <el-table-column label="时间" width="220">
                    <template #default="scope">
                      {{ scope.row.startTime }} - {{ scope.row.endTime || '至今' }}
                    </template>
                  </el-table-column>
                  <el-table-column prop="description" label="描述" />
                  <el-table-column prop="performance" label="业绩" />
                  <el-table-column prop="projectLink" label="链接" />
                </el-table>
              </section>
            </div>
          </el-tab-pane>
          <el-tab-pane label="附件信息" name="appendix">
            <div class="pane-inner">
              <el-table :data="studentInfo?.appendixList || []" border stripe>
                <el-table-column prop="fileName" label="文件名" />
                <el-table-column prop="createTime" label="上传时间" width="180" />
                <el-table-column label="操作" width="120">
                  <template #default="scope">
                    <el-button link type="primary" @click="previewAppendix(scope.row)">预览</el-button>
                    <el-button link type="primary" @click="downloadAppendix(scope.row)">下载</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-tab-pane>
          <el-tab-pane label="测评信息" name="assess">
            <div class="pane-inner">
              <el-table :data="assessRecords" border stripe>
                <el-table-column prop="name" label="测评名称" />
                <el-table-column prop="score" label="得分" width="100" />
                <el-table-column prop="level" label="评级" width="100" />
                <el-table-column prop="time" label="测评时间" width="180" />
                <el-table-column label="操作" width="100">
                  <template #default><el-button link type="primary">查看报告</el-button></template>
                </el-table-column>
              </el-table>
            </div>
          </el-tab-pane>
          <el-tab-pane label="培训信息" name="train">
            <div class="pane-inner">
               <el-table :data="trainRecords" border stripe>
                <el-table-column prop="name" label="课程名称" />
                <el-table-column prop="type" label="类型" width="120" />
                <el-table-column prop="progress" label="进度" width="120" />
                <el-table-column prop="time" label="最后学习" width="180" />
              </el-table>
            </div>
          </el-tab-pane>
          <el-tab-pane label="订单信息" name="order">
            <div class="pane-inner">
              <el-table v-loading="orderLoading" :data="allOrdersList" border stripe>
                <el-table-column prop="orderNo" label="订单号" width="150" />
                <el-table-column prop="productName" label="业务内容" />
                <el-table-column prop="totalAmount" label="金额" width="100">
                  <template #default="scope">￥{{ scope.row.totalAmount }}</template>
                </el-table-column>
                <el-table-column prop="createTime" label="交易时间" width="160" />
                <el-table-column prop="orderStatus" label="状态" width="100">
                  <template #default="scope">
                    <el-tag :type="getOrderStatusType(scope.row.orderStatus)">{{ getOrderStatusLabel(scope.row.orderStatus) }}</el-tag>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-tab-pane>
          <el-tab-pane label="任职信息" name="job_info">
            <div class="pane-inner">
              <el-table :data="任职信息记录" border stripe>
                <el-table-column prop="company" label="入职单位" />
                <el-table-column prop="job" label="岗位" />
                <el-table-column prop="time" label="入职日期" width="160" />
                <el-table-column prop="status" label="当前状态" width="120" />
              </el-table>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-drawer>

    <!-- 全部记录抽屉 -->
    <el-drawer v-model="showAllOrders" title="历史深度交易看板" size="1000px" append-to-body @open="fetchOrderList">
      <div class="drawer-p20">
        <el-table v-loading="orderLoading" :data="allOrdersList" stripe style="width: 100%">
          <el-table-column prop="orderNo" label="订单号" width="160" />
          <el-table-column prop="productName" label="内容摘要" min-width="200" />
          <el-table-column prop="totalAmount" label="实付" width="100" align="right">
            <template #default="scope">
              ￥{{ scope.row.totalAmount }}
            </template>
          </el-table-column>
          <el-table-column prop="orderStatus" label="状态" width="120" align="center">
            <template #default="scope">
              <el-tag size="small" :type="getOrderStatusType(scope.row.orderStatus)" effect="light">
                {{ getOrderStatusLabel(scope.row.orderStatus) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="订单创建时间" width="200" align="center" />
        </el-table>
      </div>
    </el-drawer>


    <!-- 6. 岗位选择弹窗 (高仿 Fig 2) -->
    <el-dialog 
      v-model="jobSelectVisible" 
      :title="currentSelectionType === 'job' ? '选择发送岗位' : '选择岗位发送结算单'" 
      width="600px" 
      class="job-selector-dialog"
      append-to-body
      destroy-on-close
    >
      <div class="job-selector-body">
        <div class="filter-tabs-wrapper">
          <div class="filter-tabs">
            <span 
              v-for="cat in ['全职岗位', '实习岗位', '兼职岗位']" 
              :key="cat"
              :class="['f-tab', selectedJobCategory === cat ? 'active' : '']"
              @click="handleCategoryChange(cat)"
            >{{ cat }}</span>
          </div>
          <div class="search-box">
             <el-input 
              v-model="jobSearchKeyword" 
              placeholder="搜索岗位名称/公司..." 
              :prefix-icon="Search"
              clearable
              @input="jobCurrentPage = 1"
            />
          </div>
        </div>
        <div class="job-list-scroll-container" v-loading="jobLoading" style="flex: 1; overflow: hidden; background: #f8fafc; display: flex; flex-direction: column;">
          <div class="job-list-scroll" style="flex: 1; overflow-y: auto; padding: 25px 20px 20px;">
            <div 
              v-for="job in jobList" 
              :key="job.id" 
              class="job-mini-item"
              style="display: flex; align-items: center; justify-content: space-between; background: #fff; border-radius: 12px; padding: 20px; margin-bottom: 12px; border: 1px solid #f1f5f9; cursor: pointer;"
              @click="executeSend(job)"
            >
              <div class="j-main" style="flex: 1; min-width: 0;">
                <div class="j-title-row" style="display: flex; align-items: center; gap: 10px; margin-bottom: 8px;">
                  <span class="t" style="font-size: 16px; font-weight: bold; color: #1e293b;">{{ job.title }} <el-tag v-if="job.urgency" size="small" type="danger" effect="dark">{{ job.urgency }}</el-tag></span>
                  <span class="p" style="color: #2563eb; font-weight: bold;">{{ job.salary }}</span>
                </div>
                <div class="j-sec-row" style="display: flex; gap: 8px; margin-bottom: 12px;">
                  <span v-for="tag in job.tags" :key="tag" class="tag" style="font-size: 12px; color: #64748b; background: #f1f5f9; padding: 2px 8px; border-radius: 4px;">{{ tag }}</span>
                </div>
                <div class="j-corp" style="display: flex; align-items: center; gap: 8px; font-size: 13px; color: #94a3b8;">
                  <img :src="job.corpLogo" class="cl" style="width: 24px !important; height: 24px !important; border-radius: 4px; object-fit: cover;" />
                  <span class="cn" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{{ job.company }} · {{ job.location }}</span>
                </div>
              </div>
              <el-button type="primary" size="small" round style="margin-left: 15px;">选择发送</el-button>
            </div>
            <div v-if="jobList.length === 0" class="empty-list">
               <el-empty description="暂无符合条件的岗位" :image-size="60" />
            </div>
          </div>
        </div>
        <div class="job-selector-footer">
          <el-pagination
            v-model:current-page="jobCurrentPage"
            v-model:page-size="jobPageSize"
            :page-sizes="[3, 5, 10, 20]"
            :total="totalJobsCount"
            layout="total, sizes, prev, pager, next"
            small
            background
          />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="CustService">
import { ref, computed, onMounted, nextTick, onBeforeUnmount, watch } from 'vue';
import { 
  Search, ChatRound, FolderOpened, Memo, Clock, 
  CircleClose, Phone, User, ShoppingCart, Document,
  CreditCard, Briefcase, DataLine, Male, Female,
  Picture, SuccessFilled
} from '@element-plus/icons-vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { getSessionList, createSession, endSession } from '@/api/chat/session';
import { getMessageHistory, sendTextMessage, sendImageMessage, sendFileMessage, sendJobCard, sendOrderCard, markMessageRead } from '@/api/chat/message';
import { connectChat, sendTextByWs, disconnectChat, generateMsgNo } from '@/utils/chatSocket';
import { listOrder } from '@/api/system/order/index';
import { getStudent } from '@/api/main/student';
import { getCompanyApplyBySession } from '@/api/main/companyApply';
import { listPosition } from '@/api/main/position';

// 核心状态
const activeTab = ref('mini');
const activeSessionId = ref(0);
const activeSession = ref(null);
const searchQuery = ref('');
const inputText = ref('');
const isWaiterOnline = ref(true);
const msgContainerRef = ref(null);
const fileInput = ref(null);
const imageInput = ref(null);
let countdownTimer = null;

// 高度调整逻辑
const inputHeight = ref(200); // 默认最小高度
const isResizing = ref(false);

// 视图控制
const showFullArchive = ref(false);
const archiveActiveTab = ref('resume');
const showAllOrders = ref(false);
const jobSelectVisible = ref(false);
const currentSelectionType = ref('job'); // job or order
const selectedJobCategory = ref('全职岗位');
const jobSearchKeyword = ref('');
const jobCurrentPage = ref(1);
const jobPageSize = ref(3);

// 视图控制状态
const studentInfo = ref(null);
const merchantInfo = ref(null);
const miniUnread = computed(() => {
  return sessionList.value.filter(s => s.type === 'mini').reduce((sum, s) => sum + (s.unread || 0), 0);
});
const merchantUnread = computed(() => {
  return sessionList.value.filter(s => s.type === 'merchant').reduce((sum, s) => sum + (s.unread || 0), 0);
});
// 判断是否是有效的可访问URL（排除本地路径、空值、过期链接）
function isValidAvatarUrl(url) {
  if (!url) return false;
  const str = String(url).trim();
  // 排除空值
  if (!str) return false;
  // 已经是有效 HTTP URL
  if (str.startsWith('http://') || str.startsWith('https://')) return true;
  // 排除小程序本地路径
  if (str.startsWith('/static/') || str.startsWith('/static\\')) return false;
  // 纯数字是 OSS ID，需要前端转换（视为有效，resolveAvatarUrl 会转换）
  if (/^\d+$/.test(str)) return true;
  // 其余（/dev-api/ 路径等）视为有效
  return true;
}

// 将 OSS ID 或无效头像转为可访问的 URL，如果已为有效 URL 则原样返回
function resolveAvatarUrl(url) {
  if (!url) return '';
  const str = String(url).trim();
  // 已经是有效 HTTP URL（后端 ossService.selectUrlByIds 已转为真实 URL）
  if (str.startsWith('http://') || str.startsWith('https://')) return str;
  // 纯数字 → OSS URL（需要拼接代理前缀）
  if (/^\d+$/.test(str)) {
    const baseApi = import.meta.env.VITE_APP_BASE_API;
    return `${baseApi}/resource/oss/file/${str}`;
  }
  // 本地路径 → 空值（el-avatar 显示默认）
  if (str.startsWith('/static/')) return '';
  // 已经是有效 URL
  return str;
}

// 获取当前会话的有效用户头像
const resolvedUserAvatar = computed(() => {
  // 商家：优先用 merchantInfo 的 avatarUrl（已由 processCompanyApplyData 转换）
  if (activeTab.value === 'merchant' && merchantInfo.value?.avatarUrl) {
    return merchantInfo.value.avatarUrl;
  }
  // 小程序学员：优先用 studentInfo 的 avatarUrl
  if (activeTab.value === 'mini' && studentInfo.value?.avatarUrl) {
    return studentInfo.value.avatarUrl;
  }
  // 最后用后端返回的 fromUserAvatar（尝试转换 OSS ID）
  const raw = activeSession.value?.avatar || '';
  const resolved = resolveAvatarUrl(raw);
  if (resolved) return resolved;
  // 全部无效时返回空（el-avatar 会显示默认图标）
  return '';
});

// 客服头像：优先用后端返回的 waiterAvatar，尝试转换 OSS ID
const waiterAvatar = computed(() => {
  const raw = activeSession.value?.waiterAvatar || '';
  return resolveAvatarUrl(raw) || '';
});
const emojiList = ['😀', '😁', '😂', '🤣', '😃', '😄', '😅', '😆', '😉', '😊', '😋', '😎', '😍', '😘', '😗', '😙', '😚', '☺️', '🙂', '🤗', '🤩', '🤔', '🤨', '😐', '😑', '😶', '🙄', '😏', '😣', '😥', '😮', '🤐', '😯', '😪', '😫', '😴', '😌', '😛', '😜', '😝', '🤤', '😒', '😓', '😔', '😕', '🙃', '🤑', '😲','👍','👋','👌','👏','🙏'];
const hasActiveSession = computed(() => !!activeSession.value && !!activeSessionId.value);

const sessionList = ref([]);

const messageList = ref([]);

// 档案表格数据（从接口获取）
const assessRecords = ref([]);
const trainRecords = ref([]);
const 任职信息记录 = ref([]);
const allOrdersList = ref([]);
const orderLoading = ref(false);

async function fetchOrderList() {
  if (!activeSession.value?.fromUserId) return;
  orderLoading.value = true;
  try {
    const res = await listOrder({
      buyerId: activeSession.value.fromUserId,
      buyerType: activeTab.value === 'mini' ? 2 : 1,
      pageNum: 1,
      pageSize: 50
    });
    if (res.code === 200 || res.rows) {
      allOrdersList.value = res.rows || res.data || [];
    }
  } catch (error) {
    console.error('获取订单列表失败:', error);
  } finally {
    orderLoading.value = false;
  }
}

const merchantOrdersList = ref([
  { id: 'PKG10001', name: '初级岗位招聘充值套餐', amount: '￥999.00', time: '2024-03-01 10:00', status: '已生效' },
  { id: 'SVC20002', name: '平台首页广告位置展示服务', amount: '￥2000.00', time: '2024-03-05 14:30', status: '待支付' },
  { id: 'PKG10005', name: '季度高级会员服务包', amount: '￥5000.00', time: '2024-02-15 09:00', status: '退款中' },
  { id: 'SVC20009', name: '高级人才库解锁插件', amount: '￥299.00', time: '2024-01-20 16:00', status: '已取消' },
  { id: 'PKG10012', name: '体验版月度推广套餐', amount: '￥199.00', time: '2024-03-10 10:00', status: '已退款' }
]);

const currentDisplayOrders = computed(() => {
  return activeTab.value === 'mini' ? allOrdersList.value : merchantOrdersList.value;
});

function getStatusType(status) {
  const map = {
    '已支付': 'success', '已生效': 'success',
    '待支付': 'warning',
    '退款中': 'danger',
    '已退款': 'info',
    '已取消': 'info'
  };
  return map[status] || 'info';
}

function getOrderStatusType(status) {
  const map = {
    0: 'warning', // 待支付
    1: 'success', // 已支付
    2: 'success', // 已完成
    3: 'info',    // 已取消
    4: 'info',    // 已退款
    5: 'danger'   // 退款中
  };
  return map[status] || 'info';
}

function getOrderStatusLabel(status) {
  const map = {
    0: '待支付',
    1: '已支付',
    2: '已完成',
    3: '已取消',
    4: '已退款',
    5: '退款中'
  };
  return map[status] || '未知';
}

const jobList = ref([]);
const totalJobsCount = ref(0);
const jobLoading = ref(false);

async function fetchJobList() {
  jobLoading.value = true;
  try {
    const res = await listPosition({
      postName: jobSearchKeyword.value, 
      postType: selectedJobCategory.value === '全职岗位' ? '1' : (selectedJobCategory.value === '实习岗位' ? '2' : '3'),
      pageNum: jobCurrentPage.value,
      pageSize: jobPageSize.value
    });
    
    const rows = res.rows || res.data?.rows || (Array.isArray(res.data) ? res.data : []);
    jobList.value = rows.map(item => ({
      id: item.id,
      title: item.postName || item.title || '未命名岗位',
      salary: item.salaryRange || '面议',
      tags: item.welfareTags ? (typeof item.welfareTags === 'string' ? item.welfareTags.split(',') : item.welfareTags) : [],
      company: item.companyName || '企业客户', 
      location: item.workCity || '不限',
      type: selectedJobCategory.value,
      urgency: item.isUrgent === 1 ? '急招' : '',
      corpLogo: item.companyLogo || 'https://api.dicebear.com/7.x/initials/svg?seed=' + (item.postName || 'Job')
    }));
    totalJobsCount.value = res.total || res.data?.total || 0;
  } catch (error) {
    console.error('获取岗位失败:', error);
  } finally {
    jobLoading.value = false;
  }
}

// 监听岗位列表相关参数变化
watch([selectedJobCategory, jobCurrentPage, jobPageSize], () => {
  fetchJobList();
});

// 监听关键词（增加防抖）
let searchTimer = null;
watch(jobSearchKeyword, () => {
  if (searchTimer) clearTimeout(searchTimer);
  searchTimer = setTimeout(() => {
    jobCurrentPage.value = 1;
    fetchJobList();
  }, 500);
});

// 监听弹窗打开
watch(jobSelectVisible, (val) => {
  if (val) {
    fetchJobList();
  }
});





function handleCategoryChange(cat) {
  selectedJobCategory.value = cat;
  jobCurrentPage.value = 1;
}

const filteredSessionList = computed(() => {
  return sessionList.value.filter(s => s.type === activeTab.value && s.name.includes(searchQuery.value));
});

// --- 输入高度拖拽逻辑 ---
function startResizing(e) {
  isResizing.value = true;
  document.addEventListener('mousemove', handleMouseMove);
  document.addEventListener('mouseup', stopResizing);
  document.body.style.cursor = 'ns-resize';
}

function handleMouseMove(e) {
  if (!isResizing.value) return;
  const container = document.querySelector('.chat-main-area');
  if (container) {
    const rect = container.getBoundingClientRect();
    const offset = rect.bottom - e.clientY;
    // 限制高度范围
    if (offset > 140 && offset < 500) {
      inputHeight.value = offset;
    }
  }
}

function stopResizing() {
  isResizing.value = false;
  document.removeEventListener('mousemove', handleMouseMove);
  document.removeEventListener('mouseup', stopResizing);
  document.body.style.cursor = '';
}

// 获取当前全时间
function getFullTime() {
  const d = new Date();
  const pad = (n) => n.toString().padStart(2, '0');
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
}

// --- 业务功能 ---
async function fetchSessionList() {
  try {
    const response = await getSessionList({
      sessionType: activeTab.value === 'mini' ? 1 : 2,
      pageNum: 1,
      pageSize: 100
    });
    if (response.code === 200 || response.code === 0) {
      sessionList.value = response.rows.map(item => ({
        id: item.sessionId,
        name: item.fromUserName,
        type: item.sessionType === 1 ? 'mini' : 'merchant',
        lastMsg: item.lastMsg,
        lastTime: item.lastMsgTime,
        unread: item.unreadCount,
        status: item.status === 1 ? 'online' : 'offline',
        avatar: resolveAvatarUrl(item.fromUserAvatar) || '',
        sessionNo: item.sessionNo,
        fromUserId: item.fromUserId,
        waiterAvatar: item.waiterAvatar || '',
        waiterName: item.waiterName || '',
        seatName: item.seatName || '',
        isOnline: item.isOnline || false
      }));
      
      if (sessionList.value.length > 0) {
        selectSession(sessionList.value[0]);
      } else {
        messageList.value = [];
        activeSession.value = null;
        activeSessionId.value = 0;
        studentInfo.value = null;
        merchantInfo.value = null;
      }
    }
  } catch (error) {
    console.error('获取会话列表失败:', error);
  }
}

async function handleSend() {
  if (!inputText.value.trim() || !activeSessionId.value) return;
  
  const text = inputText.value;
  inputText.value = ''; // 立即清空输入框提升体验
  
  try {
    const msgNo = generateMsgNo();
    const messageData = {
      sessionId: activeSessionId.value,
      msgNo: msgNo,
      // 不传 senderId，由后端通过 LoginHelper.getUserId() 自动获取当前登录客服ID
      msgType: 'text',
      content: text
    };
    
    // 如果WebSocket连接正常，优先由WS广播，这里本地不直接Push，等待WS回传
    // 但为了UI即时反馈，可以先Push一个带加载状态的对象，通过msgNo去重
    messageList.value.push({
      msgNo: msgNo,
      sender: 'waiter', 
      type: 'text', 
      content: text,
      time: getFullTime(),
      loading: true // 增加加载状态
    });
    scrollToBottom();

    // 调用REST API发送消息（后端会通过WS给所有人发广播）
    const response = await sendTextMessage(messageData);
    
    if (response.code === 200 || response.code === 0) {
      // 发送成功，等待WS推送真实消息回来替换本地Loading状态
    } else {
      ElMessage.error('发送错误: ' + (response.msg || '未知错误'));
    }
  } catch (error) {
    console.error('发送消息失败:', error);
    ElMessage.error('网络错误，发送失败');
  }
}

function formatContent(text) {
  if (!text) return '';
  return text.replace(/\n/g, '<br/>');
}

async function selectSession(session) {
  if (activeSessionId.value === session.id) return;
  
  activeSessionId.value = session.id;
  activeSession.value = session;
  studentInfo.value = null; // 重置
  merchantInfo.value = null; // 重置

  // 标记当前会话未读数为0
  session.unread = 0;

  // 如果是小程序渠道，获取会员详细档案
  if (session.type === 'mini' && session.fromUserId) {
    try {
      const res = await getStudent(session.fromUserId);
      if (res.code === 200 || res.data) {
        studentInfo.value = res.data;
        // 同步头像到当前会话
        if (studentInfo.value.avatarUrl) {
          session.avatar = studentInfo.value.avatarUrl;
        }
      }
    } catch (e) {
      console.warn('获取档案失败', e);
    }
  }

  // 如果是商家渠道，获取商家入驻信息
  if (session.type === 'merchant' && session.fromUserId) {
    try {
      const data = await getCompanyApplyBySession(session.fromUserId, session.name);
      if (data) {
        merchantInfo.value = data;
        // 同步头像到当前会话
        if (merchantInfo.value.avatarUrl) {
          session.avatar = merchantInfo.value.avatarUrl;
        }
      }
    } catch (e) {
      console.warn('获取商家信息失败', e);
    }
  }

  // 重新建立 WebSocket 连接以订阅当前会话频道
  reconnectChat();

  // 标记已读
  // ... (后端标记已读逻辑见下文)

  // 标记当前会话已读
  const lastMsg = messageList.value[messageList.value.length - 1];
  if (lastMsg && lastMsg.msgId) {
    markMessageRead(session.id, lastMsg.msgId);
  }
  
  try {
    // 从后端加载历史消息
    const response = await getMessageHistory({
      sessionId: session.id,
      pageNum: 1,
      pageSize: 50
    });
    
    if (response.code === 200 || response.rows) {
      // 将后端返回的消息转换为前端格式
      const rows = response.rows || response.data.rows || [];
      messageList.value = rows.map(msg => {
        let parsedPayload = null;
        if ((msg.msgType === 'job_card' || msg.msgType === 'order_card') && msg.payload) {
          parsedPayload = typeof msg.payload === 'string' ? JSON.parse(msg.payload) : msg.payload;
        } else if (msg.msgType === 'file') {
          parsedPayload = { name: msg.fileName || '未知文件', url: msg.fileUrl, size: '未知大小' };
        } else if (msg.msgType === 'image') {
          parsedPayload = { url: msg.fileUrl || msg.content };
        }
        // 优先使用 senderRole 判断发送者，fallback 到 senderType
        let sender;
        if (msg.senderRole === 'waiter' || msg.senderRole === 'system') {
          sender = 'waiter';
        } else if (msg.senderRole === 'user') {
          sender = 'customer';
        } else {
          sender = msg.senderType === 2 ? 'waiter' : 'customer';
        }
        return {
          msgId: msg.msgId,
          sender: sender,
          senderAvatar: msg.senderAvatar,
          type: msg.msgType || 'text',
          content: msg.content,
          time: msg.sendTime,
          payload: parsedPayload,
          fileUrl: msg.fileUrl,
          fileName: msg.fileName
        };
      }).reverse(); // 数据库按时间倒序查询的，前端展示需要反转
    }
  } catch (error) {
    console.error('加载历史消息失败:', error);
  }
  
  scrollToBottom();
}

function appendEmoji(emoji) {
  inputText.value += emoji;
}

function triggerUpload() { /* 已被 el-upload 接管 */ }
function triggerImageUpload() { /* 已被 el-upload 接管 */ }

// 分离图片上传
async function handleImageUpload(options) {
  const file = options.file;
  try {
    const msgNo = generateMsgNo();
    const time = getFullTime();
    const response = await sendImageMessage(activeSessionId.value, msgNo, file); // 不传senderId，后端自动获取
    const code = response.code ?? response.data?.code;
    if (code === 200 || code === 0) {
      const data = response.data || response;
      messageList.value.push({ 
        msgNo: msgNo,
        sender: 'waiter', 
        type: 'image', 
        time, 
        payload: { url: data.fileUrl || data.url, name: file.name } 
      });
      scrollToBottom();
      ElMessage.success('图片已发送');
    }
  } catch (error) {
    console.error('发送图片失败:', error);
    ElMessage.error('图片发送失败');
  }
}

// 分离文件上传
async function handleFileUpload(options) {
  const file = options.file;
  try {
    const msgNo = generateMsgNo();
    const time = getFullTime();
    const response = await sendFileMessage(activeSessionId.value, msgNo, file); // 不传senderId，后端自动获取
    const code = response.code ?? response.data?.code;
    if (code === 200 || code === 0) {
      const data = response.data || response;
      messageList.value.push({ 
        msgNo: msgNo,
        sender: 'waiter', 
        type: 'file', 
        time, 
        payload: { 
          name: file.name, 
          size: (file.size/1024/1024).toFixed(2) + 'MB',
          url: data.fileUrl || data.url
        } 
      });
      scrollToBottom();
      ElMessage.success('文件已发送');
    }
  } catch (error) {
    console.error('发送文件失败:', error);
    ElMessage.error('文件发送失败');
  }
}

async function handleFileChange(e) {
  // 弃用，使用 el-upload 的 http-request 替代
}

function previewFile(payload) {
  if (payload.url) {
    window.open(payload.url, '_blank');
  } else {
    ElMessage.warning('文件地址无效，无法预览');
  }
}

function downloadFile(payload) {
  const link = document.createElement('a');
  link.href = payload.url;
  link.download = payload.name;
  link.click();
  ElMessage.success('已开始下载');
}

function previewAppendix(row) {
  if (row.fileUrl) {
    window.open(row.fileUrl, '_blank');
  } else if (row.url) {
    window.open(row.url, '_blank');
  } else {
    ElMessage.warning('附件地址无效');
  }
}

function downloadAppendix(row) {
  const url = row.fileUrl || row.url;
  if (url) {
    const link = document.createElement('a');
    link.href = url;
    link.download = row.fileName || '附件';
    link.click();
    ElMessage.success('已开始下载');
  } else {
    ElMessage.warning('附件地址无效');
  }
}

function openJobSelector(type) {
  currentSelectionType.value = type;
  jobSelectVisible.value = true;
}

async function executeSend(job) {
  const time = getFullTime();
  const msgNo = generateMsgNo();
  const basePayload = { 
    ...job, 
    jumpPath: `/pages/job/detail?id=${job.id}` 
  };
  
  try {
    if (currentSelectionType.value === 'job') {
      const res = await sendJobCard({
        sessionId: activeSessionId.value,
        // 不传 senderId，由后端通过 LoginHelper.getUserId() 自动获取当前登录客服ID
        msgNo: msgNo,
        msgType: 'job_card',
        payload: basePayload
      });
      if (res.code === 200 || res.code === 1 || res.code === 0) {
        messageList.value.push({ 
          msgId: res.data?.msgId,
          msgNo: msgNo, // 带上 msgNo 方便去重
          sender: 'waiter', 
          type: 'job_card', 
          time, 
          payload: basePayload 
        });
        ElMessage.success('岗位卡片已发送');
      }
    } else {
      const orderPayload = { 
        name: `${job.title}项目入职定金`, 
        price: '29.9',
        jobId: job.id,
        status: '待支付',
        countdown: 60
      };
      const res = await sendOrderCard({
        sessionId: activeSessionId.value,
        // 不传 senderId，由后端通过 LoginHelper.getUserId() 自动获取当前登录客服ID
        msgNo: msgNo,
        msgType: 'order_card',
        payload: orderPayload
      });
      if (res.code === 200 || res.code === 0) {
        messageList.value.push({ 
          msgId: res.data?.msgId,
          sender: 'waiter', 
          type: 'order_card', 
          time, 
          payload: orderPayload 
        });
        ElMessage.success('结算单已发送');
      }
    }
  } catch (error) {
    console.error('发送卡片失败:', error);
    ElMessage.error('发送失败');
  }
  jobSelectVisible.value = false;
  scrollToBottom();
}

function handleEndSession() {
  ElMessageBox.confirm('确定要强制结束本次会话吗？', '提示').then(() => {
    messageList.value = [];
    activeSession.value = null;
    activeSessionId.value = 0;
    studentInfo.value = null;
    merchantInfo.value = null;
  });
}

function scrollToBottom() {
  nextTick(() => { if (msgContainerRef.value) msgContainerRef.value.scrollTop = msgContainerRef.value.scrollHeight; });
}

// 监听档案标签页切换，如果切到订单页则加载数据
watch(archiveActiveTab, (val) => {
  if (val === 'order') {
    fetchOrderList();
  }
});

// ---- 关键修复：监听 tab 切换（小程序↔商家），自动刷新会话列表并加载消息 ----
watch(activeTab, async (newVal) => {
  console.log('[CustService] Tab切换:', newVal, '→ 重新加载会话列表');
  
  // 清空当前状态
  messageList.value = [];
  activeSession.value = null;
  activeSessionId.value = 0;
  studentInfo.value = null;
  merchantInfo.value = null;
  
  // 重新拉取对应类型的会话列表
  await fetchSessionList();
  
  // fetchSessionList 内部已处理：有会话时自动 selectSession 第一个 → 触发 getMessageHistory
});

// 新增：统一的 WebSocket 连接管理
function reconnectChat() {
  disconnectChat();
  // 全局监听通知 + 当前选中的会话消息广播
  connectChat((notify) => {
    handleGlobalNotify(notify);
  }, activeSessionId.value, (data) => {
    if (data.sessionId === activeSessionId.value) {
      handleSessionMessage(data);
    }
  });
}

// 新增：提取会话消息处理逻辑
function handleSessionMessage(data) {
  const existIdx = messageList.value.findIndex(m => m.msgNo === data.msgNo);
  // 优先使用后端返回的 senderRole 判断发送者，fallback 到 senderType 判断
  let sender;
  if (data.senderRole === 'waiter' || data.senderRole === 'system') {
    sender = 'waiter';
  } else if (data.senderRole === 'user') {
    sender = 'customer';
  } else {
    // fallback：senderType === 2 为客服，其余为客户
    sender = data.senderType === 2 ? 'waiter' : 'customer';
  }

  const newMsg = {
    msgId: data.msgId,
    msgNo: data.msgNo,
    sender: sender,
    type: data.msgType || 'text',
    content: data.content,
    time: data.sendTime,
    payload: data.payload ? (typeof data.payload === 'string' ? JSON.parse(data.payload) : data.payload) : null
  };

  if (existIdx > -1) {
    messageList.value[existIdx] = newMsg;
  } else {
    messageList.value.push(newMsg);
  }
  scrollToBottom();
  
  // 收到客户消息标记已读
  if (sender === 'customer' && data.msgId) {
    markMessageRead(activeSessionId.value, data.msgId);
  }
}

// 修改：处理全局通知，更新左侧列表状态
function handleGlobalNotify(data) {
  if (!data) return;
  
  // 强制将会话ID转为数字进行匹配，防止类型不一致
  const targetSessionId = Number(data.sessionId);
  let session = sessionList.value.find(s => Number(s.id) === targetSessionId);
  
  // 判断消息发送者是否为坐席
  const isFromWaiter = data.senderRole === 'waiter' || data.senderRole === 'system' || data.senderType === 2;

  // 格式化最后一条消息显示
  let lastMsgText = '';
  if (data.msgType === 'text') {
    lastMsgText = data.content;
  } else if (data.msgType === 'image') {
    lastMsgText = '[图片]';
  } else if (data.msgType === 'file') {
    lastMsgText = '[文件]';
  } else if (data.msgType === 'job_card') {
    lastMsgText = '[岗位推荐]';
  } else if (data.msgType === 'order_card') {
    lastMsgText = '[结算单]';
  } else {
    lastMsgText = data.content || '[新消息]';
  }

  if (session) {
    session.lastMsg = lastMsgText;
    session.lastTime = data.sendTime || getFullTime();
    
    // 如果不是当前选中的会话，且消息来自客户（非坐席自己发的），增加未读数
    if (targetSessionId !== Number(activeSessionId.value) && !isFromWaiter) {
      session.unread = (session.unread || 0) + 1;
    }
    
    // 将有新消息的会话置顶
    const idx = sessionList.value.indexOf(session);
    if (idx > 0) {
      sessionList.value.splice(idx, 1);
      sessionList.value.unshift(session);
    }
  } else {
    // 如果会话列表中没有（可能是新会话通知），立即重新加载一次列表
    fetchSessionList();
  }
  
  // 如果收到的是当前选中的会话的消息，且本地消息流中还没这条（通过msgNo去重）
  if (targetSessionId === Number(activeSessionId.value)) {
    const isExist = messageList.value.some(m => m.msgNo === data.msgNo);
    if (!isExist) {
      handleSessionMessage(data);
    }
  }
}

onMounted(() => {
  fetchSessionList();
  
  // 启动全局结算单倒计时
  countdownTimer = setInterval(() => {
    messageList.value.forEach(msg => {
      if (msg.type === 'order_card' && msg.payload.status !== '已失效' && typeof msg.payload.countdown === 'number') {
        if (msg.payload.countdown > 0) {
          msg.payload.countdown--;
        } else {
          msg.payload.status = '已失效';
        }
      }
    });
  }, 1000);

  // 初始化 WebSocket 连接（监听全局通知）
  reconnectChat();
});

onBeforeUnmount(() => {
  stopResizing();
  if (countdownTimer) clearInterval(countdownTimer);
});
</script>

<style scoped lang="scss">
/* 基础容器 */
.chat-workbench-container {
  height: calc(100vh - 40px);
  padding: 12px;
  background-color: #f1f5f9;
  display: flex;
}

.chat-workbench-card {
  flex: 1; display: flex; background: #fff; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.06); overflow: hidden;
}

/* 左侧栏 */
.chat-sidebar {
  width: 300px; border-right: 1px solid #f1f5f9; display: flex; flex-direction: column;
  .sidebar-header {
    padding: 20px 20px 10px;
    .tab-wrap {
      display: flex; margin-bottom: 20px; border-bottom: 2px solid #f8fafc;
      .tab-item {
        flex: 1; padding: 10px 0; text-align: center; cursor: pointer; color: #94a3b8; font-size: 14px; position: relative;
        &.active { color: #2563eb; font-weight: 700; &::after { content: ''; position: absolute; bottom: -2px; left: 0; width: 100%; height: 2px; background: #2563eb; } }
      }
    }
  }
  .session-list-container {
    flex: 1; overflow: hidden;
    .session-item {
      display: flex; padding: 16px 20px; cursor: pointer; border-bottom: 1px solid #f8fafc; transition: 0.2s;
      &:hover { background: #f8fafc; }
      &.active { background: #eff6ff; border-left: 4px solid #2563eb; padding-left: 16px; }
      .avatar-wrap { position: relative; margin-right: 14px; .online-indicator { position: absolute; right: 2px; bottom: 2px; width: 10px; height: 10px; background: #10b981; border: 2px solid #fff; border-radius: 50%; } }
      .session-info {
        flex: 1; min-width: 0;
        .top-line { display: flex; justify-content: space-between; .name { font-weight: 700; color: #1e293b; font-size: 14px; } .time { font-size: 12px; color: #cbd5e1; } }
        .bottom-line { 
          margin-top: 6px; font-size: 13px; color: #94a3b8; display: flex; justify-content: space-between; align-items: center;
          .item-unread :deep(.el-badge__content) { transform: scale(0.9) translate(4px, -2px); }
        }
      }
    }
  }
}

/* 中间栏 */
.chat-main-area {
  flex: 1; display: flex; flex-direction: column; background: #fdfdfd; border-right: 1px solid #f1f5f9;
  .chat-main-header {
    height: 64px; border-bottom: 1px solid #f1f5f9; display: flex; justify-content: space-between; align-items: center; padding: 0 24px;
    .title-wrap { .title { margin: 0; font-size: 18px; color: #0f172a; } .user-status { font-size: 12px; color: #94a3b8; display: flex; align-items: center; margin-top: 2px; .dot { width: 6px; height: 6px; background: #10b981; border-radius: 50%; margin-right: 6px; } } }
    .header-actions { display: flex; align-items: center; gap: 12px; font-size: 13px; color: #64748b; }
  }

  .message-feed {
    flex: 1; overflow-y: auto; padding: 24px; background: #fbfbfc;
    background-image: radial-gradient(#e5e7eb 1px, transparent 1px); background-size: 24px 24px;
    .message-row {
      display: flex; margin-bottom: 24px;
      &.row-right { flex-direction: row-reverse; .msg-content-box { margin-right: 12px; align-items: flex-end; .msg-bubble { background: #2563eb; color: #fff; border-radius: 12px 2px 12px 12px; } } }
      &.row-left { .msg-content-box { margin-left: 12px; align-items: flex-start; .msg-bubble { background: #fff; border: 1px solid #eef2f6; border-radius: 2px 12px 12px 12px; } } }
      .msg-content-box {
        max-width: 70%; display: flex; flex-direction: column;
        .time-stamp { font-size: 11px; color: #cbd5e1; margin-bottom: 4px; }
        .msg-bubble { padding: 12px 16px; font-size: 14px; box-shadow: 0 2px 4px rgba(0,0,0,0.02); line-height: 1.5; }
        
        .image-bubble {
          padding: 0 !important; background: transparent !important; overflow: hidden; border-radius: 8px;
          .chat-img { max-width: 240px; max-height: 240px; display: block; cursor: zoom-in; transition: 0.3s; &:hover { filter: brightness(0.9); } }
        }

        .file-bubble {
          width: 260px; padding: 12px !important; flex-direction: column;
          background: #fff !important; border: 1px solid #eef2f6 !important;
          .file-main { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
          .file-info { 
            flex: 1; min-width: 0; 
            .f-name { font-weight: 600; color: #1e293b !important; font-size: 14px; } 
            .f-size { color: #94a3b8 !important; font-size: 12px; margin-top: 2px; } 
          }
          .file-actions { 
            border-top: 1px solid #f1f5f9; padding-top: 8px; display: flex; justify-content: center; align-items: center; 
            .el-button { font-weight: 600; color: #2563eb !important; } 
          }
        }
      }
    }
  }

  /* 岗位卡片优化 */
  .msg-card {
    border-radius: 12px; background: #fff; border: 1px solid #eef2f6; overflow: hidden; box-shadow: 0 4px 12px rgba(0,0,0,0.03);
    &.job-card {
      padding: 16px; width: 260px;
      .card-top { display: flex; justify-content: space-between; margin-bottom: 12px; .j-title { font-weight: 700; color: #1e293b; } .j-salary { color: #2563eb; font-weight: 700; } }
      .j-tags { display: flex; gap: 6px; margin-bottom: 15px; .j-tag { font-size: 11px; color: #64748b; background: #f1f5f9; padding: 2px 6px; border-radius: 4px; } }
      .j-extra-info {
        margin-bottom: 12px; font-size: 13px; color: #64748b;
        .ex-item { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; .el-icon { font-size: 14px; } }
      }
      .j-company-info { 
        padding-top: 12px; border-top: 1px solid #f8fafc; display: flex; align-items: center; gap: 8px; font-size: 12px; color: #94a3b8; 
        .c-logo { overflow: hidden; border-radius: 4px; border: 1px solid #f1f5f9; line-height: 0; flex-shrink: 0;} .c-name { flex: 1; color: #1e293b; font-weight: 600; font-size: 14px; display: flex; align-items: center; gap: 4px; } 
      }
    }
  }

  .order-card {
    width: 280px; overflow: hidden;
    &.is-expired { opacity: 0.9; }
    .order-header { 
      padding: 12px 16px; border-bottom: 1px solid #f8fafc; display: flex; justify-content: space-between; align-items: center;
      .o-title { font-weight: 800; color: #1e293b; font-size: 15px; }
      .expired-text { color: #1e293b; font-size: 14px; font-weight: 500;}
      .o-header-right { 
        display: flex; align-items: center; gap: 8px; 
        .o-timer { color: #f59e0b; font-size: 13px; font-weight: 800; font-family: 'DM Mono', monospace; }
      }
    }
    .order-body { 
      padding: 16px; font-size: 14px; 
      .o-subtitle { color: #94a3b8; font-size: 12px; margin-bottom: 12px; }
      .o-row { display: flex; margin-bottom: 8px; .o-label { color: #94a3b8; width: 70px; } .o-val { color: #1e293b; font-weight: 500;} .o-price { font-weight: 800; color: #ef4444; font-size: 16px; } } 
    }
    .order-footer-btn { 
      margin: 0 16px 16px; height: 44px; background: #2563eb; color: #fff; border-radius: 22px; 
      display: flex; align-items: center; justify-content: center; font-weight: 800; cursor: pointer;
      &.expired-btn { background: #ffb900 !important; color: #fff; cursor: not-allowed; }
    }
  }

  /* 输入框区域 */
  .input-panel-wrapper {
    background: #fff; border-top: 1px solid #f1f5f9; display: flex; flex-direction: column; position: relative;
    .resizer { position: absolute; top: -3px; left: 0; right: 0; height: 6px; cursor: ns-resize; background: transparent; z-index: 10; &:hover { background: #2563eb44; } }
    .action-toolbar { 
      display: flex; gap: 16px; padding: 12px 24px; align-items: center;
      .tool-btn { color: #64748b; cursor: pointer; &:hover { color: #2563eb; } }
      .spacer { flex: 1; }
      .history-trigger { font-size: 13px; color: #64748b; display: flex; align-items: center; gap: 6px; cursor: pointer; &:hover { color: #2563eb; } }
    }
    .input-editor { flex: 1; padding: 0 24px; textarea { width: 100%; height: 100%; border: none; outline: none; resize: none; font-size: 14px; line-height: 1.6; } }
    .input-footer { 
      padding: 12px 24px; display: flex; justify-content: space-between; align-items: center;
      .hot-key { font-size: 12px; color: #cbd5e1; }
      .btn-group { display: flex; gap: 12px; }
      .send-action { border-radius: 6px; font-weight: 700; padding: 12px 28px; font-size: 14px; }
      :deep(.el-button) { padding: 12px 24px; font-size: 14px; height: auto; }
    }
  }
}

/* 右侧栏 */
.chat-profile-panel {
  width: 360px; background: #fff; display: flex; flex-direction: column;
  .summary-card {
    padding: 30px 24px; text-align: center;
    .avatar-ring { display: inline-block; padding: 4px; border: 2px dashed #e2e8f0; border-radius: 50%; margin-bottom: 16px; }
    .uname { margin: 0; font-size: 20px; font-weight: 800; color: #0f172a; }
    .tag-row { 
      margin-top: 12px; display: flex; flex-direction: column; align-items: center; gap: 10px;
      .u-tag { font-size: 12px; padding: 4px 12px; border-radius: 20px; &.mini { background: #eff6ff; color: #2563eb; } &.merchant { background: #ecfdf5; color: #10b981; } }
    }
  }
  .info-block {
    padding: 20px 24px; border-bottom: 1px solid #f8fafc;
    &.no-border { border: none; }
    .b-head { font-size: 14px; font-weight: 800; color: #1e293b; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; .el-icon { color: #2563eb; } }
    .b-body.contact { 
      .row { display: flex; margin-bottom: 10px; font-size: 13px; .l { color: #94a3b8; width: 65px; flex-shrink: 0; } .v { color: #1e293b; font-weight: 600; word-break: break-all; } }
      .entry-proof { .proof-label { font-size: 13px; color: #94a3b8; } }
    }
    .stat-matrix {
      display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 16px;
      .stat-item { background: #f8fafc; border-radius: 8px; padding: 12px 4px; text-align: center; .num { font-size: 18px; font-weight: 800; color: #2563eb; } .lab { font-size: 11px; color: #94a3b8; margin-top: 4px; } }
    }
    .sub-list { font-size: 12px; color: #64748b; .sl-item { display: flex; justify-content: space-between; margin-bottom: 8px; } }
    .mini-order {
      display: flex; justify-content: space-between; align-items: center; padding: 14px; background: #fdfdfd; border: 1px solid #f1f5f9; border-radius: 10px; margin-bottom: 12px; transition: 0.3s;
      &:hover { border-color: #2563eb; background: #fff; box-shadow: 0 4px 10px rgba(0,0,0,0.04); }
      .o-main { 
        flex: 1; min-width: 0;
        .oname { font-size: 14px; font-weight: 700; color: #1e293b; margin-bottom: 4px; } 
        .ometa { font-size: 11px; color: #94a3b8; } 
      }
      .o-side {
        display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
        .order-action-btn { font-size: 12px; padding: 0; height: auto; }
      }
    }
    .see-more { width: 100%; font-size: 12px; margin-top: 10px; }
  }

  /* 状态标签视觉增强 */
  :deep(.el-tag) {
    border-radius: 4px; border: none; font-weight: 700;
    &.el-tag--success { background: #ecfdf5; color: #10b981; }
    &.el-tag--warning { background: #fffbeb; color: #d97706; }
    &.el-tag--danger { background: #fef2f2; color: #ef4444; }
    &.el-tag--info { background: #f8fafc; color: #94a3b8; }
  }
}

/* 表情面板精修 (一次性调整好) */
.emoji-picker-stage {
  width: 370px; display: flex; flex-direction: column; overflow: hidden;
  .picker-header { padding: 12px 16px; background: #f8fafc; border-bottom: 1px solid #f1f5f9; font-size: 13px; font-weight: 800; color: #475569; }
  .picker-body {
    display: grid; grid-template-columns: repeat(7, 1fr); gap: 12px; padding: 16px 20px; max-height: 240px; overflow-y: auto; overflow-x: hidden;
    justify-items: center;
    &::-webkit-scrollbar { width: 4px; }
    &::-webkit-scrollbar-thumb { background: #e2e8f0; border-radius: 4px; }
    .emoji-node { font-size: 24px; cursor: pointer; text-align: center; transition: 0.15s; border-radius: 6px; padding: 4px; &:hover { background: #eff6ff; transform: scale(1.25); } }
  }
}

/* 全量档案抽屉 (图3风格) */
.archive-content {
  padding: 0 40px 40px;
  .archive-header-card {
    background: #fdfdfd; border: 1px solid #eef2f6; border-radius: 16px; padding: 30px; display: flex; gap: 30px; align-items: center; margin-bottom: 30px;
    .h-left { text-align: center; .h-tag { margin-top: 10px; font-size: 12px; color: #2563eb; background: #eff6ff; padding: 2px 8px; border-radius: 4px; } }
    .h-main { 
      flex: 1; .m-title { font-size: 24px; font-weight: 900; color: #0f172a; margin-bottom: 24px; display: flex; align-items: center; gap: 10px; }
      .m-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px 60px; font-size: 14px; label { color: #94a3b8; width: 120px; display: inline-block; } color: #1e293b; font-weight: 500;}
    }
  }
  .archive-tabs {
    :deep(.el-tabs__item) { font-size: 15px; font-weight: 600; padding: 0 30px; }
    .pane-inner { padding: 20px 0; .s-head { font-size: 18px; font-weight: 800; margin-bottom: 16px; display: flex; align-items: center; gap: 10px; &::before { content:''; width:4px; height:18px; background:#2563eb; border-radius:2px; } } }
  }
}


.job-card {
  cursor: pointer; transition: 0.2s;
  &:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.08); }
}

.order-body {
  .o-price { color: #2563eb !important; }
}
/* 历史线程气泡 */
.history-thread {
  padding: 30px; background: #f8fafc; min-height: 100%; display: flex; flex-direction: column; gap: 24px;
  .bubble-pack {
    max-width: 80%;
    &.customer { align-self: flex-start; .bubble { background: #fff; border: 1px solid #eef2f6; border-radius: 2px 16px 16px 16px; } }
    &.waiter { align-self: flex-end; .bubble { background: #2563eb; color: #fff; border-radius: 16px 2px 16px 16px; } }
    .bubble { padding: 16px 20px; .b-meta { font-size: 11px; margin-bottom: 8px; display: flex; justify-content: space-between; gap: 20px; opacity: 0.6; } .b-text { font-size: 14px; line-height: 1.6; } }
  }
}

.text-ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mt-20 { margin-top: 20px; }
.drawer-p20 { padding: 20px; }
</style>

<style lang="scss">
/* 全局浮窗重置 */
.emoji-popover-refined {
  padding: 0 !important; border-radius: 12px !important; box-shadow: 0 20px 40px rgba(0,0,0,0.15) !important; border: 1px solid #eef2f6 !important;
}
.biz-card-popover {
  padding: 6px 0 !important; .biz-card-menu { .menu-item { padding: 12px 20px; font-size: 14px; cursor: pointer; display:flex; align-items:center; gap:10px; &:hover { background: #f8fafc; color:#2563eb; } } }
}
.archive-drawer-modern {
  .el-drawer__header { margin-bottom: 0; padding: 20px 40px; border-bottom: 1px solid #f1f5f9; span { font-weight: 800; color: #0f172a; } }
}

/* 任务选择弹窗全局样式 (修正 Teleport 导致的失效) */
.job-selector-dialog {
  .el-dialog__body { padding: 0 !important; }
  .job-selector-body { height: 600px; display: flex; flex-direction: column; overflow: hidden; }
  
  .filter-tabs-wrapper {
    background: #fff; border-bottom: 1px solid #f1f5f9;
    .filter-tabs {
      display: flex; padding: 0 20px;
      .f-tab { 
        padding: 15px 20px; cursor: pointer; color: #64748b; font-size: 15px; position: relative;
        &.active { color: #2563eb; font-weight: bold; &::after { content:''; position: absolute; bottom: 0; left: 20px; right: 20px; height: 3px; background: #2563eb; border-radius: 2px; } }
      }
    }
    .search-box { padding: 5px 20px 10px; }
  }

  .job-list-scroll-container { flex: 1; overflow: hidden; background: #f8fafc; }
  .job-list-scroll {
    height: 100%; overflow-y: auto; padding: 25px 20px 20px;
    
    .job-mini-item {
      background: #fff; border-radius: 12px; padding: 20px; margin-bottom: 12px; border: 1px solid #f1f5f9;
      display: flex; align-items: center; justify-content: space-between; cursor: pointer; transition: 0.2s;
      &:hover { border-color: #2563eb; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.08); }
      
      .j-main {
        flex: 1; min-width: 0;
        .j-title-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; .t { font-size: 16px; font-weight: bold; color: #1e293b; } .p { color: #2563eb; font-weight: bold; } }
        .j-sec-row { display: flex; gap: 8px; margin-bottom: 12px; overflow-x: auto; .tag { flex-shrink: 0; font-size: 12px; color: #64748b; background: #f1f5f9; padding: 2px 8px; border-radius: 4px; } }
        .j-corp { 
          display: flex; align-items: center; gap: 8px; font-size: 13px; color: #94a3b8; 
          .cl { width: 24px !important; height: 24px !important; border-radius: 4px; object-fit: cover; flex-shrink: 0; }
          .cn { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        }
      }
      .el-button { margin-left: 20px; flex-shrink: 0; }
    }
  }
  
  .job-selector-footer {
     padding: 15px 20px; background: #fff; border-top: 1px solid #f1f5f9; display: flex; justify-content: flex-end;
  }
}
</style>
