<template>
  <div class="page-container">
    <el-card shadow="never" class="table-card">
      <template #header>
        <div class="card-header">
          <div class="left-panel">
            <span class="title">履约者池</span>
            <el-tag type="info" effect="plain" style="margin-left: 10px;">共 {{ total }} 人</el-tag>
          </div>
          <div class="right-panel">
            <el-button type="success" icon="Download" @click="handleExport"
              v-hasPermi="['fulfiller:pool:exportExcel']">导出Excel</el-button>
            <el-button type="primary" icon="Plus" style="margin-right: 16px" @click="handleCreate"
              v-hasPermi="['fulfiller:pool:add']">新增履约者</el-button>
            <el-input v-model="searchKey" placeholder="搜索姓名/手机号/身份证" class="search-input" prefix-icon="Search" clearable
              @keyup.enter="handleSearch" @clear="handleSearch" />
            <el-cascader v-model="filterCascaderValue" :options="areaTreeOptions"
              :props="{ checkStrictly: true, value: 'id', label: 'name' }" placeholder="所属站点" clearable
              style="width: 350px; margin-left: 10px;" @change="handleFilterCascaderChange" />
          </div>
        </div>

        <!-- Tab切换 (无图标) -->
        <el-tabs v-model="activeTab" class="status-tabs" @tab-click="handleTabClick">
          <el-tab-pane label="全部" name="all" />
          <el-tab-pane label="休息" name="resting" />
          <el-tab-pane label="接单中" name="busy" />
          <el-tab-pane label="禁用" name="disabled" />
        </el-tabs>
      </template>

      <el-table v-loading="loading" :data="tableData" style="width: 100%"
        :header-cell-style="{ background: '#f5f7fa' }">
        <el-table-column label="基本信息" width="280">
          <template #default="scope">
            <div class="user-info">
              <el-avatar :size="45" :src="scope.row.avatarUrl">{{ scope.row.name.charAt(0) }}</el-avatar>
              <div class="text-col">
                <div class="name-row">
                  <span class="name">{{ scope.row.name }}</span>
                  <span class="gender-tag">
                    <el-icon v-if="scope.row.gender === '0'" color="#409eff">
                      <Male />
                    </el-icon>
                    <el-icon v-else color="#f56c6c">
                      <Female />
                    </el-icon>
                  </span>
                </div>
                <div class="tags-row" style="margin: 3px 0">
                  <!-- work type -->
                  <el-tag size="small" :type="scope.row.workType === 'full_time' ? 'warning' : 'info'" effect="light"
                    style="margin-right: 5px">
                    {{ scope.row.workType === 'full_time' ? '全职专送' : '兼职众包' }}
                  </el-tag>
                  <!-- 等级展示 -->
                  <el-tag size="small" :type="getLevelType(scope.row.levelName)" effect="plain" class="level-tag">
                    {{ getLevelText(scope.row.levelName) }}
                  </el-tag>
                </div>
                <div class="sub-text">{{ scope.row.phone }}</div>
              </div>
            </div>
          </template>
        </el-table-column>

        <el-table-column label="资质信息" width="220">
          <template #default="scope">
            <div class="auth-row">
              <div class="auth-card" :class="{ active: scope.row.authId }">
                <el-icon>
                  <Postcard />
                </el-icon> 身份证
              </div>
              <div class="auth-card" :class="{ active: scope.row.authQual }">
                <el-icon>
                  <Medal />
                </el-icon> 资质证
              </div>
            </div>
            <div style="margin-top:5px;">
              <el-tag v-if="scope.row.authId" type="success" size="small" effect="plain">已认证</el-tag>
              <el-tag v-else type="info" size="small" effect="plain">未认证</el-tag>
            </div>
            <div class="sub-text" style="margin-top:5px;">ID: {{ scope.row.idCard }}</div>
          </template>
        </el-table-column>

        <el-table-column label="服务区域" width="180">
          <template #default="scope">
            <div class="text-col">
              <span style="font-size: 13px; color: #333;">{{ getStationPathText(scope.row.stationId).cityAndRegion
              }}</span>
              <span style="font-size: 12px; color: #999;">{{ getStationPathText(scope.row.stationId).station }}</span>
            </div>
          </template>
        </el-table-column>

        <el-table-column label="服务类型" width="150">
          <template #default="scope">
            <el-tag v-for="st in getServiceTypeList(scope.row.serviceTypes)" :key="st" size="small" type="warning"
              effect="light" style="margin-right:4px;margin-bottom:4px;">
              {{ st }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column label="技能标签" min-width="180">
          <template #default="scope">
            <el-tag v-for="tag in scope.row.tags" :key="tag.id" :type="tag.colorType" size="small" class="skill-tag"
              effect="plain">
              {{ tag.name }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column label="订单数据" width="180">
          <template #default="scope">
            <div class="finance-item">服务单: <span class="num">{{ scope.row.orderCount }}</span></div>
            <div class="finance-item">拒/转单: <span class="num error">{{ scope.row.rejectCount }}</span></div>
          </template>
        </el-table-column>

        <el-table-column label="账户资产" width="160">
          <template #default="scope">
            <div class="finance-item">积分: <span class="num">{{ scope.row.points }}</span></div>
            <div class="finance-item">余额: <span class="num">¥{{ (scope.row.balance / 100).toFixed(2) }}</span></div>
          </template>
        </el-table-column>

        <el-table-column prop="status" label="状态" width="100">
          <template #default="scope">
            <div class="status-cell">
              <div class="status-dot" :class="scope.row.status"></div>
              <span class="status-text">{{ getStatusText(scope.row.status) }}</span>
            </div>
          </template>
        </el-table-column>

        <el-table-column label="操作" width="240" fixed="right">
          <template #default="scope">
            <div class="op-cell">
              <el-button link type="primary" size="small" @click="handleDetail(scope.row)"
                v-hasPermi="['fulfiller:pool:query']">详情</el-button>
              <el-button link type="primary" size="small" @click="handleEdit(scope.row)"
                v-hasPermi="['fulfiller:pool:edit']">编辑</el-button>
              <el-button link type="warning" size="small" @click="handleReward(scope.row)"
                v-hasPermi="['fulfiller:pool:reward']">奖惩</el-button>
              <el-dropdown trigger="click" @command="(cmd) => handleCommand(cmd, scope.row)">
                <el-button link type="primary">更多<el-icon class="el-icon--right"><arrow-down /></el-icon></el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="adjustPoints"
                      v-hasPermi="['fulfiller:pool:editScore']">修改积分</el-dropdown-item>
                    <el-dropdown-item command="adjustBalance"
                      v-hasPermi="['fulfiller:pool:editBalance']">余额增减</el-dropdown-item>
                    <el-dropdown-item v-if="scope.row.status !== 'disabled'" command="disable" divided
                      style="color: #f56c6c" v-hasPermi="['fulfiller:pool:disable']">禁用账号</el-dropdown-item>
                    <el-dropdown-item v-else command="enable" divided style="color: #67c23a"
                      v-hasPermi="['fulfiller:pool:enable']">启用账号</el-dropdown-item>
                    <el-dropdown-item command="violation"
                      v-hasPermi="['fulfiller:pool:violationLog']">违规记录</el-dropdown-item>
                    <el-dropdown-item command="resetPwd"
                      v-hasPermi="['fulfiller:pool:resetPassword']">重置密码</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
          :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" :total="total"
          @size-change="handleSizeChange" @current-change="handleCurrentChange" />
      </div>
    </el-card>

    <!-- 详情侧边栏 Drawer -->
    <el-drawer v-model="detailVisible" title="履约者档案详情" size="750px" direction="rtl" custom-class="detail-drawer">
      <div class="drawer-content" v-if="currentItem">
        <!-- 头部概览 -->
        <div class="user-header-card">
          <el-avatar :size="70" :src="currentItem.avatarUrl" class="header-avatar">{{ currentItem.name?.charAt(0)
          }}</el-avatar>
          <div class="header-info">
            <div class="top-row">
              <span class="user-name">{{ currentItem.name }}</span>
              <el-tag size="small" :type="currentItem.gender === '0' ? '' : 'danger'" effect="plain" round
                style="margin-left: 8px;">
                {{ currentItem.gender === '0' ? '男' : '女' }}
              </el-tag>
              <span class="status-badge" :class="currentItem.status">{{ getStatusText(currentItem.status) }}</span>
            </div>
            <div class="sub-row">
              <span class="info-item"><el-icon>
                  <Iphone />
                </el-icon> {{ currentItem.phone }}</span>
              <span class="divider">|</span>
              <span class="info-item"><el-icon>
                  <Location />
                </el-icon> {{ currentItem ? getStationPathText(currentItem.stationId).cityAndRegion : '-' }}/{{
                  currentItem
                    ? getStationPathText(currentItem.stationId).station : '-' }}</span>
            </div>
            <div class="tags-row">
              <el-tag size="small" :type="getLevelType(currentItem.levelName)" effect="dark">{{
                getLevelText(currentItem.levelName) }}</el-tag>
              <el-tag size="small" type="warning" effect="plain" v-if="currentItem.workType === 'full_time'"
                style="margin-left:5px">全职专送</el-tag>
            </div>
            <div class="tags-row" style="margin-top:8px;">
              <el-tag v-for="st in getServiceTypeList(currentItem.serviceTypes)" :key="st" size="small" type="warning"
                effect="light" style="margin-right:6px;">
                {{ st }}
              </el-tag>
            </div>
          </div>
        </div>

        <!-- 核心数据指标 -->
        <div class="data-metrics-row">
          <div class="metric-item">
            <div class="val text-primary">{{ currentItem.points }}</div>
            <div class="lbl">当前积分</div>
          </div>
          <div class="divider-v"></div>
          <div class="metric-item">
            <div class="val text-danger">¥{{ (currentItem.balance / 100).toFixed(2) }}</div>
            <div class="lbl">账户余额</div>
          </div>
          <div class="divider-v"></div>
          <div class="metric-item">
            <div class="val">{{ currentItem.orderCount }}</div>
            <div class="lbl">服务单量</div>
          </div>
          <div class="divider-v"></div>
          <div class="metric-item">
            <div class="val text-warning">{{ currentItem.rejectCount || 0 }}</div>
            <div class="lbl">拒绝单量</div>
          </div>
        </div>

        <el-tabs v-model="activeDetailTab" class="detail-tabs">
          <el-tab-pane label="档案概览" name="info">
            <div class="tab-content-wrapper">
              <div class="section-block">
                <div class="section-title">基础信息</div>
                <el-descriptions :column="2" border>
                  <el-descriptions-item label="身份证号">{{ currentItem.idCard }}</el-descriptions-item>
                  <el-descriptions-item label="真实姓名">{{ currentItem.realName || currentItem.name
                  }}</el-descriptions-item>
                  <el-descriptions-item label="归属站点">{{ currentItem ? getStationPathText(currentItem.stationId).station
                    :
                    '-' }}</el-descriptions-item>
                  <el-descriptions-item label="证件有效期">{{ currentItem.idCardExpiry || '-' }}</el-descriptions-item>
                  <el-descriptions-item label="入驻时间">{{ currentItem.createTime }}</el-descriptions-item>
                  <el-descriptions-item label="工作性质">{{ currentItem.workType === 'full_time' ? '全职' : '兼职'
                  }}</el-descriptions-item>
                </el-descriptions>
              </div>

              <div class="section-block">
                <div class="section-title">实名认证</div>
                <div class="cert-row">
                  <div class="cert-item" @click="handleViewImage(currentItem.idCardFrontUrl)">
                    <el-image :src="currentItem.idCardFrontUrl || ''" fit="cover" class="cert-img">
                      <template #error>
                        <div class="img-slot"><el-icon>
                            <Picture />
                          </el-icon></div>
                      </template>
                    </el-image>
                    <div class="cert-name">身份证人像面</div>
                  </div>
                  <div class="cert-item" @click="handleViewImage(currentItem.idCardBackUrl)">
                    <el-image :src="currentItem.idCardBackUrl || ''" fit="cover" class="cert-img">
                      <template #error>
                        <div class="img-slot"><el-icon>
                            <Picture />
                          </el-icon></div>
                      </template>
                    </el-image>
                    <div class="cert-name">身份证国徽面</div>
                  </div>
                </div>
              </div>

              <div class="section-block">
                <div class="section-title">资质认证</div>
                <div class="cert-row" v-if="qualImageUrlList.length">
                  <div class="cert-item" v-for="(img, index) in qualImageUrlList" :key="index"
                    @click="handleViewImage(img)">
                    <el-image :src="img" fit="cover" class="cert-img">
                      <template #error>
                        <div class="img-slot"><el-icon>
                            <Picture />
                          </el-icon></div>
                      </template>
                    </el-image>
                  </div>
                </div>
                <div v-else class="empty-text">暂无资质图片</div>
              </div>
              <div class="section-block">
                <div class="section-title">技能标签</div>
                <div class="tag-list">
                  <el-tag v-for="tag in currentItem.tags" :key="tag.id" :type="tag.colorType" size="large"
                    style="margin-right: 12px; margin-bottom: 8px;">{{ tag.name }}</el-tag>
                </div>
              </div>
            </div>
          </el-tab-pane>

          <el-tab-pane label="服务订单" name="orders">
            <div class="tab-content-wrapper">
              <el-table v-loading="logLoading" :data="serviceOrderData" stripe style="width: 100%"
                :header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
                <el-table-column prop="code" label="订单号" width="160" show-overflow-tooltip />
                <el-table-column label="服务项目" show-overflow-tooltip>
                  <template #default="{ row }">
                    {{ getServiceName(row.service) }}
                  </template>
                </el-table-column>
                <el-table-column prop="fulfillmentCommission" label="收入" width="100">
                  <template #default="{ row }">
                    <span style="color: #67c23a; font-weight: bold; font-size: 15px;">+{{ (row.fulfillmentCommission /
                      100).toFixed(2)
                    }}</span>
                  </template>
                </el-table-column>
                <el-table-column prop="serviceTime" label="时间" width="160" show-overflow-tooltip />
                <el-table-column prop="status" label="状态" width="90">
                  <template #default="{ row }">
                    <el-tag :type="getSubOrderStatusType(row.status)" size="small">
                      {{ getSubOrderStatusName(row.status) }}
                    </el-tag>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-tab-pane>

          <el-tab-pane label="积分记录" name="pointLogs">
            <div class="tab-content-wrapper">
              <el-table v-loading="logLoading" :data="pointsLogData" stripe style="width: 100%"
                :header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
                <el-table-column prop="createTime" label="变动时间" width="180" />
                <el-table-column prop="bizType" label="业务类型" width="120">
                  <template #default="{ row }">
                    <el-tag :type="getPointsBizTypeTag(row.bizType)" size="small" effect="plain">{{
                      getPointsBizTypeName(row.bizType) }}</el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="amount" label="变动数值" width="120">
                  <template #default="{ row }">
                    <span
                      :style="{ color: ['reward', fulfillerEnums.ActionType.ADD].includes(row.type) ? '#67c23a' : '#f56c6c', fontWeight: 'bold', fontSize: '15px' }">
                      {{ ['reward', fulfillerEnums.ActionType.ADD].includes(row.type) ? '+' : '-' }}{{ row.amount }}
                    </span>
                  </template>
                </el-table-column>
                <el-table-column prop="reason" label="变动原因" show-overflow-tooltip />
                <el-table-column prop="operatorId" label="操作人" width="120" />
              </el-table>
            </div>
          </el-tab-pane>

          <el-tab-pane label="余额变动" name="balanceLogs">
            <div class="tab-content-wrapper">
              <el-table v-loading="logLoading" :data="balanceLogData" stripe style="width: 100%"
                :header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
                <el-table-column prop="createTime" label="变动时间" width="180" show-overflow-tooltip />
                <el-table-column prop="subType" label="资金类型" width="120">
                  <template #default="{ row }">
                    <el-tag :type="getBalanceBizTypeTag(row.subType)" size="small" effect="plain">{{
                      getBalanceBizTypeName(row.bizType) }}</el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="amount" label="变动金额" width="120">
                  <template #default="{ row }">
                    <span
                      :style="{ color: ['reward', fulfillerEnums.ActionType.ADD].includes(row.type) ? '#67c23a' : '#f56c6c', fontWeight: 'bold', fontSize: '15px' }">
                      {{ ['reward', fulfillerEnums.ActionType.ADD].includes(row.type) ? '+' : '-' }}{{ (row.amount /
                        100).toFixed(2) }}
                    </span>
                  </template>
                </el-table-column>
                <el-table-column prop="balanceAfter" label="变动后余额" width="120">
                  <template #default="{ row }">
                    <span>¥{{ (row.balanceAfter / 100).toFixed(2) }}</span>
                  </template>
                </el-table-column>
                <el-table-column prop="reason" label="备注说明" show-overflow-tooltip />
                <el-table-column prop="operatorId" label="操作人" width="100" />
              </el-table>
            </div>
          </el-tab-pane>

          <el-tab-pane label="奖惩记录" name="rewards">
            <div class="tab-content-wrapper">
              <el-table v-loading="logLoading" :data="rewardLogData" stripe style="width: 100%"
                :header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
                <el-table-column prop="createTime" label="操作时间" width="180" />
                <el-table-column prop="bizType" label="奖惩类型" width="100">
                  <template #default="{ row }">
                    <el-tag :type="fulfillerEnums.RewardBizType[row.bizType]?.tagType || 'info'" size="small"
                      effect="plain">
                      {{ getRewardBizTypeName(row.bizType) }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="target" label="关联项目" width="100">
                  <template #default="{ row }">
                    <el-tag type="info" size="small" effect="plain">{{ row.target === 'points' ? '积分' : '余额' }}</el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="amount" label="涉及数值" width="120">
                  <template #default="{ row }">
                    <span
                      :style="{ color: ['reward', fulfillerEnums.ActionType.ADD].includes(row.type) ? '#67c23a' : '#f56c6c', fontWeight: 'bold' }">
                      {{ ['reward', fulfillerEnums.ActionType.ADD].includes(row.type) ? '+' : '-' }}{{ row.target ===
                        'balance' ? (row.amount / 100).toFixed(2) : row.amount }} {{ row.target === 'points' ? '分' : '元'
                      }}
                    </span>
                  </template>
                </el-table-column>
                <el-table-column prop="reason" label="奖惩原因" show-overflow-tooltip />
                <el-table-column prop="operatorName" label="操作人" width="100" />
              </el-table>
            </div>
          </el-tab-pane>

          <el-tab-pane label="违规记录" name="violation">
            <div class="tab-content-wrapper">
              <el-table v-loading="logLoading" :data="violationLogData" stripe style="width: 100%"
                :header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
                <el-table-column prop="violationTime" label="违规时间" width="180">
                </el-table-column>
                <el-table-column prop="count" label="违规次数" width="100" />
                <el-table-column prop="reason" label="违规原因" show-overflow-tooltip />
                <!--                <el-table-column prop="operatorName" label="操作人" width="100" />-->
              </el-table>
            </div>
          </el-tab-pane>

          <el-tab-pane label="投诉记录" name="complaints">
            <div class="tab-content-wrapper">
              <el-table v-loading="logLoading" :data="complaintLogData" stripe style="width: 100%"
                :header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
                <el-table-column prop="createTime" label="投诉时间" width="180" />
                <el-table-column prop="orderCode" label="订单号" width="160" show-overflow-tooltip />
                <el-table-column prop="reason" label="投诉原因" show-overflow-tooltip />
                <el-table-column label="投诉图片" width="180">
                  <template #default="{ row }">
                    <div v-if="row.photoUrls" style="display: flex; gap: 4px; flex-wrap: wrap;">
                      <ImagePreview v-for="(url, i) in row.photoUrls.split(',').filter(Boolean)" :key="i" :src="url"
                        :width="40" :height="40" />
                    </div>
                    <span v-else style="color:#c0c4cc;">-</span>
                  </template>
                </el-table-column>
                <!--                <el-table-column prop="createBy" label="操作人" width="100" />-->
              </el-table>
              <div style="margin-top: 20px; display: flex; justify-content: flex-end;">
                <el-pagination v-model:current-page="complaintPagination.pageNum"
                  v-model:page-size="complaintPagination.pageSize" :page-sizes="[10, 20, 50]"
                  layout="total, sizes, prev, pager, next" :total="complaintPagination.total"
                  @size-change="loadComplaintLogs" @current-change="loadComplaintLogs" />
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-drawer>

    <!-- 编辑弹窗 -->
    <el-dialog v-model="editDialog.visible" title="编辑履约者" width="600px" top="5vh">
      <el-form :model="editDialog.form" label-width="90px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="姓名" required>
              <el-input v-model="editDialog.form.name" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="手机号" required>
              <el-input v-model="editDialog.form.phone" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="性别">
              <el-radio-group v-model="editDialog.form.gender">
                <el-radio label="0">男</el-radio>
                <el-radio label="1">女</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="身份证号">
              <el-input v-model="editDialog.form.idCard" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="所属站点">
          <el-cascader v-model="editDialog.cascaderValue" :options="areaTreeOptions"
            :props="{ value: 'id', label: 'name' }" placeholder="请选择站点" clearable style="width: 100%"
            @change="handleEditCascaderChange" />
        </el-form-item>

        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="等级">
              <el-input v-model="editDialog.form.level" placeholder="等级" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="当前状态">
              <el-select v-model="editDialog.form.status" style="width: 100%">
                <el-option label="接单中" value="busy" />
                <el-option label="休息" value="resting" />
                <el-option label="禁用" value="disabled" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="技能标签">
          <el-select v-model="editDialog.form.tagIds" multiple placeholder="请选择技能标签" style="width: 100%">
            <el-option v-for="tag in allTags" :key="tag.id" :label="tag.name" :value="tag.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="服务类型">
          <el-select v-model="editDialog.serviceTypeIds" multiple placeholder="请选择服务类型" style="width: 100%">
            <el-option v-for="item in serviceOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="认证状态">
          <el-checkbox v-model="editDialog.form.authId">身份证认证</el-checkbox>
          <el-checkbox v-model="editDialog.form.authQual">专业资质认证</el-checkbox>
        </el-form-item>

      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="editDialog.visible = false">取消</el-button>
          <el-button type="primary" @click="saveEdit">保存变更</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 奖惩弹窗 -->
    <el-dialog v-model="rewardDialog.visible" title="人工奖惩操作" width="450px">
      <div class="user-preview-box">
        当前操作对象：<b>{{ rewardDialog.userName }}</b>
      </div>
      <el-form :model="rewardDialog.form" label-width="80px" style="margin-top: 20px;">
        <el-form-item label="操作类型">
          <el-radio-group v-model="rewardDialog.form.type">
            <el-radio :label="fulfillerEnums.ActionType.ADD">增加</el-radio>
            <el-radio :label="fulfillerEnums.ActionType.REDUCE">减少</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="调整项目">
          <el-radio-group v-model="rewardDialog.form.target">
            <el-radio label="points">积分</el-radio>
            <el-radio label="balance">金额 (元)</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="数额" required>
          <el-input-number v-model="rewardDialog.form.amount" :min="1" />
        </el-form-item>
        <el-form-item label="原因备注" required>
          <el-input v-model="rewardDialog.form.reason" type="textarea" placeholder="请输入奖惩原因..." />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="rewardDialog.visible = false">取消</el-button>
          <el-button type="primary" @click="submitReward">确认执行</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 新增履约者弹窗 -->
    <el-dialog v-model="createDialog.visible" title="新增履约者" width="500px">
      <el-form :model="createDialog.form" label-width="80px">
        <el-form-item label="姓名" required>
          <el-input v-model="createDialog.form.name" placeholder="请输入真实姓名" />
        </el-form-item>
        <el-form-item label="手机号" required>
          <el-input v-model="createDialog.form.phone" placeholder="作为登录账号" />
        </el-form-item>
        <el-form-item label="登录密码" required>
          <el-input v-model="createDialog.form.password" show-password placeholder="设置初始密码" />
        </el-form-item>
        <el-form-item label="性别">
          <el-radio-group v-model="createDialog.form.gender">
            <el-radio label="0">男</el-radio>
            <el-radio label="1">女</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="所属站点">
          <el-cascader v-model="createDialog.cascaderValue" :options="areaTreeOptions"
            :props="{ value: 'id', label: 'name' }" placeholder="请选择站点" clearable style="width: 100%"
            @change="handleCreateCascaderChange" />
        </el-form-item>
        <el-form-item label="技能标签">
          <el-select v-model="createDialog.form.tagIds" multiple placeholder="请选择技能标签" style="width: 100%">
            <el-option v-for="tag in allTags" :key="tag.id" :label="tag.name" :value="tag.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="服务类型">
          <el-select v-model="createDialog.serviceTypeIds" multiple placeholder="请选择服务类型" style="width: 100%">
            <el-option v-for="item in serviceOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createDialog.visible = false">取消</el-button>
        <el-button type="primary" @click="submitCreate">确认创建</el-button>
      </template>
    </el-dialog>

    <!-- 违规记录弹窗 -->
    <el-dialog v-model="violationDialog.visible" title="新增违规记录" width="450px">
      <el-form :model="violationDialog.form" label-width="80px">
        <el-form-item label="违规次数" required>
          <el-input-number v-model="violationDialog.form.count" :min="1" style="width: 100%" />
        </el-form-item>
        <el-form-item label="扣罚积分" required>
          <el-input-number v-model="violationDialog.form.points" :min="0" style="width: 100%" placeholder="违规扣罚积分" />
        </el-form-item>
        <el-form-item label="违规时间" required>
          <el-date-picker v-model="violationDialog.form.violationTime" type="datetime" placeholder="请选择违规时间"
            format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
        </el-form-item>
        <el-form-item label="违规原因" required>
          <el-input v-model="violationDialog.form.reason" type="textarea" :rows="3" placeholder="请输入违规原因说明" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="violationDialog.visible = false">取消</el-button>
        <el-button type="primary" @click="submitViolation">确认提交</el-button>
      </template>
    </el-dialog>

    <!-- 积分调整弹窗 -->
    <el-dialog v-model="pointsDialog.visible" title="修改积分" width="400px">
      <el-form :model="pointsDialog.form" label-width="80px">
        <el-form-item label="当前积分">
          <strong>{{ pointsDialog.currentRow?.points }}</strong>
        </el-form-item>
        <el-form-item label="调整方式">
          <el-radio-group v-model="pointsDialog.form.type">
            <el-radio :label="fulfillerEnums.ActionType.ADD">增加</el-radio>
            <el-radio :label="fulfillerEnums.ActionType.REDUCE">扣除</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="调整数值" required>
          <el-input-number v-model="pointsDialog.form.amount" :min="1" />
        </el-form-item>
        <el-form-item label="调整原因" required>
          <el-input v-model="pointsDialog.form.reason" type="textarea" placeholder="请输入备注说明" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="pointsDialog.visible = false">取消</el-button>
        <el-button type="primary" @click="submitPointsAdjust">确认调整</el-button>
      </template>
    </el-dialog>

    <!-- 余额调整弹窗 -->
    <el-dialog v-model="balanceDialog.visible" title="余额增减" width="450px">
      <el-form :model="balanceDialog.form" label-width="80px">
        <el-form-item label="当前余额">
          <span style="color: #f56c6c; font-weight: bold">¥{{ (balanceDialog.currentRow?.balance / 100).toFixed(2)
          }}</span>
        </el-form-item>
        <el-form-item label="扣减类型">
          <el-radio-group v-model="balanceDialog.form.type"
            @change="balanceDialog.form.subType = balanceDialog.form.type === fulfillerEnums.ActionType.ADD ? 'admin_reward' : 'admin_punish'">
            <el-radio :label="fulfillerEnums.ActionType.ADD">增加</el-radio>
            <el-radio :label="fulfillerEnums.ActionType.REDUCE">减少</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="调整类型">
          <el-radio-group v-model="balanceDialog.form.subType">
            <template v-if="balanceDialog.form.type === fulfillerEnums.ActionType.ADD">
              <el-radio label="admin_reward">奖励</el-radio>
              <el-radio label="admin_ajust">其他 (后台调整)</el-radio>
            </template>
            <template v-else>
              <el-radio label="admin_punish">惩罚</el-radio>
              <el-radio label="salary">工资发放</el-radio>
              <el-radio label="admin_ajust">其他 (后台调整)</el-radio>
            </template>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="金额" required>
          <el-input-number v-model="balanceDialog.form.amount" :min="0.01" :precision="2" :step="10" />
        </el-form-item>
        <el-form-item label="备注说明" required>
          <el-input v-model="balanceDialog.form.reason" type="textarea" placeholder="请输入资金变动说明" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="balanceDialog.visible = false">取消</el-button>
        <el-button type="primary" @click="submitBalanceAdjust">确认执行</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted, getCurrentInstance } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  listFulfiller, getFulfiller, addFulfiller, updateFulfiller,
  changeStatus, resetPwd, reward, adjustPoints, adjustBalance,
  listPointsLog, listBalanceLog, listRewardLog, exportFulfiller
} from '@/api/fulfiller/pool'
import { addViolation, listViolationByFulfiller } from '@/api/fulfiller/violation'
import type { FlfViolationVO } from '@/api/fulfiller/violation/types'
import { pageComplaintByFulfiller } from '@/api/fulfiller/complaint'
import { listSubOrderOnFulfiller } from '@/api/order/subOrder/index'
import { listAllService } from '@/api/service/list/index'
import type {
  FlfFulfillerVO, FlfFulfillerForm, FlfFulfillerQuery,
  FlfRewardForm, FlfAdjustPointsForm, FlfAdjustBalanceForm,
  FlfPointsLogVO, FlfBalanceLogVO, FlfRewardLogVO
} from '@/api/fulfiller/pool/types'
import { listAllTag } from '@/api/fulfiller/tag'
import type { FlfTagVO } from '@/api/fulfiller/tag/types'
import { listAreaStation as listOnStore } from '@/api/system/areaStation'
import type { AreaStationVO as SysAreaStationOnStoreVo } from '@/api/system/areaStation/types'
import fulfillerEnums from '@/json/fulfiller.json'
import ImageUpload from '@/components/ImageUpload/index.vue'
import ImagePreview from '@/components/ImagePreview/index.vue'
import { listAllLevelRights, addLevelRights, updateLevelRights, delLevelRights, changeLevelRightsStatus } from '@/api/fulfiller/levelRights';
import { listAllLevelConfig, addLevelConfig, updateLevelConfig, delLevelConfig } from '@/api/fulfiller/levelConfig';
import { useIntervalRefresh } from '@/hooks/useIntervalRefresh';

// 获取全局实例，用于调用 proxy.download
const { proxy } = getCurrentInstance() as any

const loading = ref(false)
const searchKey = ref('')
const activeTab = ref('all')
const total = ref(0)
const tableData = ref<FlfFulfillerVO[]>([])
const allTags = ref<FlfTagVO[]>([])
const areaStationList = ref<SysAreaStationOnStoreVo[]>([])
const areaTreeOptions = computed(() => {
  const buildTree = (data: any[], parentId: any): any[] => {
    return data
      .filter(item => String(item.parentId) === String(parentId))
      .map(item => {
        const children = buildTree(data, item.id);
        const res: any = { id: item.id, name: item.name };
        if (children && children.length > 0) res.children = children;
        return res;
      });
  };
  return buildTree(areaStationList.value, 0);
});
const filterCascaderValue = ref<any[]>([])

const queryParams = reactive<FlfFulfillerQuery>({
  pageNum: 1,
  pageSize: 10
})

// Drawer State
const detailVisible = ref(false)
const activeDetailTab = ref('info')
const currentItem = ref<FlfFulfillerVO | null>(null)

/** 资质图片URL列表（从逗号分隔字符串解析） */
const qualImageUrlList = computed(() => {
  if (!currentItem.value?.qualImageUrls) return []
  return currentItem.value.qualImageUrls.split(',').filter(Boolean)
})

// Log data for detail tabs
const pointsLogData = ref<FlfPointsLogVO[]>([])
const balanceLogData = ref<FlfBalanceLogVO[]>([])
const rewardLogData = ref<FlfRewardLogVO[]>([])
const violationLogData = ref<FlfViolationVO[]>([])
const complaintLogData = ref<any[]>([])
const complaintPagination = reactive({ pageNum: 1, pageSize: 20, total: 0 })
const serviceOrderData = ref<any[]>([])
const serviceOptions = ref<any[]>([])
const logLoading = ref(false)

/** 获取站点完整路径显示文本 */
const getStationPathText = (stationId: number | string | undefined) => {
  if (!stationId || !areaStationList.value.length) return { cityAndRegion: '-', station: '-' }
  const station = areaStationList.value.find(item => item.id == stationId)
  if (!station) return { cityAndRegion: '-', station: '-' }
  const region = areaStationList.value.find(item => item.id == station.parentId)
  if (!region) return { cityAndRegion: '-', station: station.name || '-' }
  const city = areaStationList.value.find(item => item.id == region.parentId)
  const cityAndRegion = city ? `${city.name}/${region.name}` : region.name
  return { cityAndRegion, station: station.name || '-' }
}

/** 查询列表 */
const getList = async (isPolling: any = false) => {
  const isAutoPoll = isPolling === true;
  if (!isAutoPoll) {
    loading.value = true
  }
  try {
    const params: FlfFulfillerQuery = {
      pageNum: queryParams.pageNum,
      pageSize: queryParams.pageSize,
      status: activeTab.value === 'all' ? undefined : activeTab.value,
      keyword: searchKey.value || undefined,
      stationId: queryParams.stationId || undefined
    }
    const res = await listFulfiller(params)
    tableData.value = res.rows
    total.value = res.total
  } finally {
    if (!isAutoPoll) {
      loading.value = false
    }
  }
}

/** 导出为Excel */
const handleExport = () => {
  proxy?.download(
    'fulfiller/fulfiller/export',
    {
      status: activeTab.value === 'all' ? undefined : activeTab.value,
      keyword: searchKey.value || undefined,
      stationId: queryParams.stationId || undefined
    },
    '履约者列表.xlsx'
  )
}

/** 加载全部标签(选择器用) */
const loadAllTags = async () => {
  try {
    const res = await listAllTag({ category: 'fulfiller' })
    allTags.value = res.data || []
  } catch { /* ignore */ }
}

/** 加载区域站点数据并构建级联树 */
const loadAreaStations = async () => {
  try {
    const res = await listOnStore()
    areaStationList.value = res.data || []
  } catch { /* ignore */ }
}

// stationOptions, loadStationsByAreaId 已废弃，现通过级联选择器统一控制


/** 根据级联值获取cityCode和cityName */
const getCityInfoFromCascader = (cascaderValue: any[]) => {
  if (!cascaderValue || cascaderValue.length === 0) return { cityCode: '', cityName: '' }
  const lastId = cascaderValue[cascaderValue.length - 1]
  const names: string[] = []
  for (const id of cascaderValue) {
    const item = areaStationList.value.find(i => i.id == id)
    if (item) names.push(item.name || '')
  }
  return { cityCode: String(lastId), cityName: names.join(' ') }
}

/** 搜索框回车/清除触发查询 */
const handleSearch = () => {
  queryParams.pageNum = 1
  getList()
}

const handleSizeChange = (val: number) => { queryParams.pageSize = val; getList() }
const handleCurrentChange = (val: number) => { queryParams.pageNum = val; getList() }

/** 积分业务类型标签颜色 */
const getPointsBizTypeTag = (type: string) => {
  return fulfillerEnums.PointsBizType[type]?.tagType || 'info'
}

/** 积分业务类型中文名称 */
const getPointsBizTypeName = (type: string) => {
  return fulfillerEnums.PointsBizType[type]?.label || type
}

/** 余额资金类型颜色 */
const getBalanceBizTypeTag = (type: string) => {
  return fulfillerEnums.BalanceBizType[type]?.tagType || 'info'
}

/** 余额资金类型中文名称 */
const getBalanceBizTypeName = (type: string) => {
  return fulfillerEnums.BalanceBizType[type]?.label || type
}

/** 奖惩业务类型名称 */
const getRewardBizTypeName = (type: string) => {
  return fulfillerEnums.RewardBizType[type]?.label || type
}

/** 加载服务项目列表用于名称映射 */
const loadServiceOptions = async () => {
  try {
    const res = await listAllService()
    serviceOptions.value = res.data || []
  } catch { /* ignore */ }
}

const getServiceName = (serviceId: number | string) => {
  const item = serviceOptions.value.find(i => i.id === serviceId)
  return item ? item.name : '未知服务'
}

/** 获取服务类型名称列表（从逗号分隔字符串解析） @Author: Antigravity */
const getServiceTypeList = (serviceTypes: string | undefined): string[] => {
  if (!serviceTypes) return []
  const ids = serviceTypes.split(',').filter(Boolean)
  return ids.map(id => getServiceName(id))
}

const getSubOrderStatusName = (status: number) => {
  const map: Record<number, string> = { 0: '待派单', 1: '待接单', 2: '待服务', 3: '服务中', 4: '已完成', 5: '已取消' }
  return map[status] || '未知'
}

const getSubOrderStatusType = (status: number) => {
  const map: Record<number, string> = { 0: 'info', 1: 'warning', 2: 'primary', 3: 'success', 4: 'success', 5: 'danger' }
  return map[status] || 'info'
}

const rewardDialog = reactive({
  visible: false,
  userName: '',
  fulfillerId: 0 as number | string,
  form: { type: fulfillerEnums.ActionType.ADD, target: 'points', amount: 10, reason: '' }
})

const editDialog = reactive({
  visible: false,
  form: {} as FlfFulfillerForm,
  cascaderValue: [] as any[],
  stationOptions: [] as SysAreaStationOnStoreVo[],
  serviceTypeIds: [] as any[] // 服务类型多选辅助数组（提交时转为逗号字符串）
})

const createDialog = reactive({
  visible: false,
  form: {
    name: '', phone: '', password: '', cityCode: '', cityName: '', stationId: undefined as any, gender: '0', workType: 'full_time'
  },
  cascaderValue: [] as any[],
  stationOptions: [] as SysAreaStationOnStoreVo[],
  serviceTypeIds: [] as any[] // 服务类型多选辅助数组（提交时转为逗号字符串）
})

const pointsDialog = reactive({
  visible: false,
  currentRow: null as FlfFulfillerVO | null,
  form: { type: fulfillerEnums.ActionType.ADD, amount: 0, reason: '' }
})

const balanceDialog = reactive({
  visible: false,
  currentRow: null as FlfFulfillerVO | null,
  form: { type: fulfillerEnums.ActionType.ADD, subType: 'admin_reward', amount: 0, reason: '' }
})

const violationDialog = reactive({
  visible: false,
  fulfillerId: 0 as number | string,
  form: {
    count: 1,
    violationTime: '',
    reason: '',
    points: 0
  }
})

const getStatusText = (status: string) => {
  const map: Record<string, string> = { busy: '接单中', resting: '休息', disabled: '禁用', frozen: '冻结' }
  return map[status] || '未知'
}

const getLevelText = (levelName: string) => {
  return levelName || '普通'
}

const getLevelType = (levelName: string) => {
  if (!levelName) return 'info'
  if (levelName.includes('金')) return 'warning'
  if (levelName.includes('银')) return 'info'
  if (levelName.includes('铜')) return 'danger'
  return 'info'
}

const handleTabClick = (tab: any) => {
  activeTab.value = tab.paneName
  queryParams.pageNum = 1
  getList()
}

/** 加载日志数据 */
const loadLogs = async (fulfillerId: string | number) => {
  logLoading.value = true
  try {
    const [pRes, bRes, rRes, sRes, vRes] = await Promise.all([
      listPointsLog(fulfillerId, { pageNum: 1, pageSize: 20 }),
      listBalanceLog(fulfillerId, { pageNum: 1, pageSize: 20 }),
      listRewardLog(fulfillerId, { pageNum: 1, pageSize: 20 }),
      listSubOrderOnFulfiller(fulfillerId),
      listViolationByFulfiller({ fulfillerId, pageNum: 1, pageSize: 20 })
    ])
    pointsLogData.value = pRes.rows || []
    balanceLogData.value = bRes.rows || []
    rewardLogData.value = rRes.rows || []
    serviceOrderData.value = sRes.data || []
    violationLogData.value = vRes.rows || []
  } catch { /* ignore */ } finally {
    logLoading.value = false
  }
  loadComplaintLogs(fulfillerId)
}

const loadComplaintLogs = async (fulfillerId?: string | number) => {
  const id = fulfillerId || currentItem.value?.id
  if (!id) return
  logLoading.value = true
  try {
    const res = await pageComplaintByFulfiller({
      fulfiller: id,
      pageNum: complaintPagination.pageNum,
      pageSize: complaintPagination.pageSize
    })
    complaintLogData.value = res.rows || []
    complaintPagination.total = res.total || 0
  } catch { /* ignore */ } finally {
    logLoading.value = false
  }
}

const handleDetail = async (row: FlfFulfillerVO) => {
  try {
    const res = await getFulfiller(row.id)
    currentItem.value = res.data
  } catch {
    currentItem.value = { ...row }
  }
  activeDetailTab.value = 'info'
  detailVisible.value = true
  loadLogs(row.id)
}

const handleEdit = (row: FlfFulfillerVO) => {
  editDialog.form = {
    id: row.id,
    name: row.name,
    phone: row.phone,
    gender: row.gender,
    idCard: row.idCard,
    cityCode: row.cityCode,
    cityName: row.cityName,
    stationId: row.stationId,
    level: row.level,
    status: row.status,
    authId: row.authId,
    authQual: row.authQual,
    tagIds: row.tags ? row.tags.map(t => t.id) : []
  }
  // 将后端逗号字符串 serviceTypes 解析为数组用于多选回显
  editDialog.serviceTypeIds = row.serviceTypes ? row.serviceTypes.split(',').filter(Boolean) : []
  if (row.stationId || row.cityCode) {
    const targetId = row.stationId || Number(row.cityCode)
    const path: any[] = []
    let currentId = targetId
    while (currentId && String(currentId) !== '0') {
      path.unshift(currentId)
      const node = areaStationList.value.find(i => String(i.id) === String(currentId))
      if (node) {
        currentId = node.parentId
      } else {
        break
      }
    }
    editDialog.cascaderValue = path
  }
  editDialog.visible = true
}

const handleCreate = () => {
  createDialog.form = {
    name: '', phone: '', password: '', cityCode: '', cityName: '', stationId: undefined, gender: '0', workType: 'full_time', tagIds: []
  }
  createDialog.serviceTypeIds = [] // 重置服务类型辅助数组
  createDialog.cascaderValue = []
  createDialog.stationOptions = []
  createDialog.visible = true
}

const submitCreate = async () => {
  if (!createDialog.form.name || !createDialog.form.phone || !createDialog.form.password) {
    ElMessage.warning('请填写完整信息')
    return
  }
  // 将选中的服务类型数组转为逗号拼接字符串后提交
  ; (createDialog.form as any).serviceTypes = createDialog.serviceTypeIds.join(',')
  try {
    await addFulfiller(createDialog.form as FlfFulfillerForm)
    createDialog.visible = false
    ElMessage.success('创建成功')
    getList()
  } catch { /* handled by interceptor */ }
}

const saveEdit = async () => {
  // 将选中的服务类型数组转为逗号拼接字符串后提交
  ; (editDialog.form as any).serviceTypes = editDialog.serviceTypeIds.join(',')
  try {
    await updateFulfiller(editDialog.form)
    ElMessage.success('更新成功')
    editDialog.visible = false
    getList()
  } catch { /* handled by interceptor */ }
}

const handleReward = (row: FlfFulfillerVO) => {
  rewardDialog.userName = row.name
  rewardDialog.fulfillerId = row.id
  rewardDialog.form = { type: fulfillerEnums.ActionType.ADD, target: 'points', amount: 10, reason: '' }
  rewardDialog.visible = true
}

const submitReward = async () => {
  try {
    // 余额目标时将元转为分
    const amount = rewardDialog.form.target === 'balance'
      ? Math.round(rewardDialog.form.amount * 100)
      : rewardDialog.form.amount
    await reward({
      fulfillerId: rewardDialog.fulfillerId,
      type: rewardDialog.form.type,
      target: rewardDialog.form.target,
      amount: amount,
      reason: rewardDialog.form.reason,
      bizType: rewardDialog.form.type === fulfillerEnums.ActionType.ADD ? 'admin_reward' : 'admin_punish'
    } as any)
    ElMessage.success('操作成功')
    rewardDialog.visible = false
    getList()
  } catch { /* handled by interceptor */ }
}

const handleCommand = async (cmd: string, row: FlfFulfillerVO) => {
  if (cmd === 'adjustPoints') {
    pointsDialog.currentRow = row
    pointsDialog.form = { type: fulfillerEnums.ActionType.ADD, amount: 0, reason: '' }
    pointsDialog.visible = true
  } else if (cmd === 'adjustBalance') {
    balanceDialog.currentRow = row
    balanceDialog.form = { type: fulfillerEnums.ActionType.ADD, subType: 'admin_reward', amount: 0, reason: '' }
    balanceDialog.visible = true
  } else if (cmd === 'disable') {
    await ElMessageBox.confirm(`确定禁用履约者【${row.name}】吗？禁用后将无法接单。`, '提示', { type: 'warning' })
    try {
      await changeStatus(row.id, 'disabled')
      ElMessage.success('账号已禁用')
      getList()
    } catch { /* handled by interceptor */ }
  } else if (cmd === 'enable') {
    await ElMessageBox.confirm(`确定启用履约者【${row.name}】吗？`, '提示', { type: 'success' })
    try {
      await changeStatus(row.id, 'resting')
      ElMessage.success('账号已启用')
      getList()
    } catch { /* handled by interceptor */ }
  } else if (cmd === 'resetPwd') {
    await ElMessageBox.confirm('确定重置密码为默认密码 [123456] 吗？', '提示', { type: 'info' })
    try {
      await resetPwd(row.id, '123456')
      ElMessage.success('密码重置成功')
    } catch { /* handled by interceptor */ }
  } else if (cmd === 'violation') {
    violationDialog.fulfillerId = row.id
    // 获取当前履约者等级对应的违规扣罚积分
    const getDefaultPoints = async () => {
      try {
        const levelConfigRes = await listAllLevelConfig()
        const currentLevelConfig = levelConfigRes.data.find((config: any) => config.lvNo === row.level)
        const defaultPoints = currentLevelConfig?.degradeViolationsScore || 0
        return defaultPoints
      } catch {
        return 0
      }
    }

    getDefaultPoints().then(defaultPoints => {
      violationDialog.form = {
        count: 1,
        violationTime: new Date().toISOString().replace('T', ' ').split('.')[0],
        reason: '',
        points: defaultPoints
      }
      violationDialog.visible = true
    })
  }
}

const submitViolation = async () => {
  if (!violationDialog.form.violationTime || !violationDialog.form.reason) {
    ElMessage.warning('请填写完整信息')
    return
  }
  try {
    await addViolation({
      fulfiller: violationDialog.fulfillerId,
      ...violationDialog.form
    } as any)
    ElMessage.success('添加违规记录成功')
    violationDialog.visible = false
  } catch { /* handled by interceptor */ }
}

const submitPointsAdjust = async () => {
  if (!pointsDialog.currentRow) return
  try {
    await adjustPoints({
      fulfillerId: pointsDialog.currentRow.id,
      type: pointsDialog.form.type,
      amount: pointsDialog.form.amount,
      reason: pointsDialog.form.reason,
      bizType: pointsDialog.form.type === fulfillerEnums.ActionType.ADD ? 'admin_reward' : 'admin_punish'
    } as any)
    ElMessage.success('积分调整成功')
    pointsDialog.visible = false
    getList()
  } catch { /* handled by interceptor */ }
}

const submitBalanceAdjust = async () => {
  if (!balanceDialog.currentRow) return
  try {
    // 将元转为分
    await adjustBalance({
      fulfillerId: balanceDialog.currentRow.id,
      type: balanceDialog.form.type,
      subType: balanceDialog.form.subType,
      amount: Math.round(balanceDialog.form.amount * 100),
      reason: balanceDialog.form.reason
    })
    ElMessage.success('余额调整成功')
    balanceDialog.visible = false
    getList()
  } catch { /* handled by interceptor */ }
}

const handleViewImage = (url: string) => {
  // Already handled by el-image preview
}

/** 顶部筛选：级联选择变化时 */
const handleFilterCascaderChange = (val: any[]) => {
  if (val && val.length > 0) {
    const lastId = val[val.length - 1]
    const node = areaStationList.value.find(item => item.id === lastId)
    if (node && node.type === 2) {
      queryParams.stationId = lastId
      queryParams.cityCode = String(node.parentId)
    } else {
      queryParams.cityCode = String(lastId)
      queryParams.stationId = undefined
    }
  } else {
    queryParams.cityCode = undefined
    queryParams.stationId = undefined
  }
  handleSearch()
}

/** 编辑对话框：级联选择变化时 */
const handleEditCascaderChange = (val: any[]) => {
  if (val && val.length > 0) {
    const lastId = val[val.length - 1]
    const node = areaStationList.value.find(item => item.id === lastId)
    if (node) {
      editDialog.form.stationId = lastId
      editDialog.form.cityCode = String(node.parentId)
      const { cityName } = getCityInfoFromCascader(val)
      editDialog.form.cityName = cityName
    }
  } else {
    editDialog.form.stationId = undefined
    editDialog.form.cityCode = undefined
    editDialog.form.cityName = undefined
  }
}

/** 新增对话框：级联选择变化时 */
const handleCreateCascaderChange = (val: any[]) => {
  if (val && val.length > 0) {
    const lastId = val[val.length - 1]
    const node = areaStationList.value.find(item => item.id === lastId)
    if (node) {
      createDialog.form.stationId = lastId
      createDialog.form.cityCode = String(node.parentId)
      const { cityName } = getCityInfoFromCascader(val)
      createDialog.form.cityName = cityName
    }
  } else {
    createDialog.form.stationId = undefined
    createDialog.form.cityCode = undefined
    createDialog.form.cityName = undefined
  }
}

onMounted(() => {
  getList()
  loadAllTags()
  loadAreaStations()
  loadServiceOptions()
})

// 统一数据轮询 @Author: Antigravity
useIntervalRefresh(() => getList(true), 5000);
</script>

<style scoped>
.page-container {
  padding: 20px;
}

.table-card {
  border-radius: 8px;
  border: none;
}

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

.status-tabs {
  margin-top: -15px;
}

:deep(.el-tabs__header) {
  margin-bottom: 0;
}

:deep(.el-tabs__nav-wrap::after) {
  height: 1px;
  background-color: #f0f2f5;
}

.title {
  font-size: 18px;
  font-weight: bold;
  color: #303133;
}

.right-panel {
  display: flex;
  align-items: center;
}

.search-input {
  width: 240px;
}

/* Table Content Styles */
.user-info {
  display: flex;
  align-items: center;
}

.text-col {
  margin-left: 10px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.name-row {
  font-weight: bold;
  font-size: 14px;
  color: #333;
  display: flex;
  align-items: center;
}

.gender-tag {
  margin-left: 5px;
  display: flex;
  align-items: center;
}

.sub-text {
  font-size: 12px;
  color: #999;
  margin-top: 2px;
}

.auth-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.auth-card {
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  background: #f4f4f5;
  color: #909399;
  display: flex;
  align-items: center;
  gap: 4px;
}

.auth-card.active {
  background: #ecf5ff;
  color: #409eff;
}

.auth-card.need-review {
  background: #fef0f0;
  color: #f56c6c;
  border: 1px dashed #f56c6c;
}

.finance-item {
  font-size: 13px;
  color: #606266;
  line-height: 1.6;
}

.num {
  font-weight: bold;
  font-family: DIN, sans-serif;
  margin-left: 5px;
  color: #303133;
}

.num.error {
  color: #f56c6c;
}

.status-cell {
  display: flex;
  align-items: center;
}

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

.status-dot.resting {
  background: #e6a23c;
}

.status-dot.busy {
  background: #409eff;
}

.status-dot.disabled {
  background: #f56c6c;
}

.status-dot.frozen {
  background: #909399;
}

.op-cell {
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
}

/* Drawer Styles */
.user-header-card {
  display: flex;
  align-items: center;
  padding: 20px;
  background: linear-gradient(135deg, #f5f7fa 0%, #eef1f6 100%);
  border-radius: 8px;
  margin-bottom: 25px;
}

.header-info {
  margin-left: 20px;
  flex: 1;
}

.top-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.user-name {
  font-size: 20px;
  font-weight: bold;
  color: #303133;
}

.status-badge {
  margin-left: auto;
  font-size: 12px;
  padding: 4px 10px;
  border-radius: 12px;
  background: #e1f3d8;
  color: #67c23a;
}

.status-badge.resting {
  background: #faecd8;
  color: #e6a23c;
}

.status-badge.disabled {
  background: #fde2e2;
  color: #f56c6c;
}

.status-badge.busy {
  background: #d9ecff;
  color: #409eff;
}

.status-badge.frozen {
  background: #f0f9eb;
  color: #909399;
}

.sub-row {
  display: flex;
  align-items: center;
  font-size: 13px;
  color: #606266;
  margin-bottom: 8px;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.divider {
  margin: 0 10px;
  color: #dcdfe6;
}

.tags-row {
  display: flex;
  align-items: center;
  gap: 5px;
}

.data-metrics-row {
  display: flex;
  justify-content: space-around;
  padding: 15px 0;
  margin-bottom: 10px;
  background: #fff;
  border-bottom: 1px solid #f0f0f0;
}

.metric-item {
  text-align: center;
  flex: 1;
}

.val {
  font-size: 20px;
  font-weight: bold;
  color: #303133;
  font-family: DIN, sans-serif;
  margin-bottom: 4px;
}

.lbl {
  font-size: 12px;
  color: #909399;
}

.text-primary {
  color: #409eff;
}

.text-danger {
  color: #f56c6c;
}

.text-warning {
  color: #e6a23c;
}

.divider-v {
  width: 1px;
  background: #e0e0e0;
  height: 30px;
  align-self: center;
}

.detail-tabs {
  margin-top: 0;
}

.section-block {
  margin-bottom: 25px;
}

.section-title {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 15px;
  border-left: 4px solid #409eff;
  padding-left: 10px;
}

.cert-row {
  display: flex;
  gap: 15px;
}

.cert-item {
  text-align: center;
  cursor: pointer;
}

.cert-img {
  width: 120px;
  height: 80px;
  border-radius: 6px;
  border: 1px solid #dcdfe6;
  background: #f5f7fa;
}

.img-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  color: #909399;
  font-size: 24px;
}

.cert-name {
  font-size: 12px;
  color: #606266;
  margin-top: 5px;
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
}

.tab-content-wrapper {
  padding: 10px 0;
}

:deep(.el-table .el-table__cell) {
  padding: 12px 0;
}
</style>
