<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="能源类型" prop="energyTypeId">
        <el-select v-model="queryParams.energyTypeId" placeholder="请选择能源类型">
          <el-option v-for="item in energyTypeList" :key="item.energyTypeId" :label="item.name" :value="item.energyTypeId" />
        </el-select>
      </el-form-item>
      <el-form-item label="费率" prop="rate">
        <el-input
          v-model="queryParams.rate"
          placeholder="请输入费率"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="货币单位" prop="currency">
        <el-select v-model="queryParams.currency" placeholder="请选择货币单位">
          <el-option v-for="item in dict.type.currency_unit" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="生效日期" prop="effectiveDate">
        <el-date-picker clearable
          v-model="queryParams.effectiveDate"
          type="date"
          value-format="yyyy-MM-dd"
          placeholder="请选择生效日期">
        </el-date-picker>
      </el-form-item>
      <el-form-item label="失效日期" prop="expiryDate">
        <el-date-picker clearable
          v-model="queryParams.expiryDate"
          type="date"
          value-format="yyyy-MM-dd"
          placeholder="请选择失效日期">
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="energyRateList" @selection-change="handleSelectionChange" @row-click="handleRowClick">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="" align="center" prop="energyRateId" v-if="false"/>
      <el-table-column label="能源类型" align="center" prop="energyTypeId">
        <template slot-scope="scope">
          <span>{{ getEnergyName(scope.row.energyTypeId) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="费率信息" align="left" min-width="280">
        <template slot-scope="scope">
          <div class="rate-info-detail">
            <!-- 固定费率 -->
            <div v-if="parseInt(scope.row.usePeakValley) === 0 && parseInt(scope.row.useTieredPricing) === 0" class="rate-item">
              <span class="rate-label">固定费率:</span>
              <span class="rate-value">¥{{ scope.row.rate }}/{{ getEnergyUnit(scope.row.energyTypeId) }}</span>
            </div>
            
            <!-- 峰谷时段费率 -->
            <div v-if="parseInt(scope.row.usePeakValley) === 1 && parseInt(scope.row.useTieredPricing) === 0" class="rate-item">
              <span class="rate-label">峰谷电价:</span>
              <div v-if="getRatePeriods(scope.row.energyRateId).length > 0" class="period-rates">
                <span v-for="period in getRatePeriods(scope.row.energyRateId)" :key="period.periodId" class="period-badge" :style="{ backgroundColor: getPeriodBgColor(period.periodType) }">
                  {{ getPeriodName(period.periodType) }}: ¥{{ period.rate }}
                </span>
              </div>
              <div v-else class="config-warning">
                <span>⚙ 未配置峰谷电价，请点击"配置"按钮进行设置</span>
              </div>
            </div>
            
            <!-- 梯度收费 -->
            <div v-if="parseInt(scope.row.useTieredPricing) === 1 && parseInt(scope.row.usePeakValley) === 0" class="rate-item">
              <span class="rate-label">梯度电价:</span>
              <div class="tier-rates">
                <span v-if="!scope.row.tiers || scope.row.tiers.length === 0" style="color: #999;">未配置</span>
                <span v-for="tier in scope.row.tiers" :key="tier.tierId" class="tier-badge">
                  第{{ tier.tierLevel }}档: {{ tier.minUsage }}-{{ tier.maxUsage ? tier.maxUsage : '∞' }} ¥{{ tier.rate }}
                </span>
              </div>
            </div>
            
            <!-- 梯度+峰谷组合 -->
            <div v-if="parseInt(scope.row.useTieredPricing) === 1 && parseInt(scope.row.usePeakValley) === 1" class="rate-item">
              <span class="rate-label">梯度+峰谷:</span>
              <div class="combo-rates">
                <div v-for="tier in scope.row.tiers" :key="tier.tierId" class="combo-tier-row">
                  <div class="tier-header">第{{ tier.tierLevel }}档 ({{ tier.minUsage }}-{{ tier.maxUsage ? tier.maxUsage : '∞' }})</div>
                  <div class="tier-rates-container">
                    <span v-if="tier.tierPeriodRates && Object.keys(tier.tierPeriodRates).length > 0">
                      <span v-for="(rate, periodId) in tier.tierPeriodRates" :key="periodId" class="rate-badge">
                        ¥{{ rate }}
                      </span>
                    </span>
                    <span v-else style="color: #999; font-size: 12px;">未配置</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="货币单位" align="center" prop="currency">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.currency_unit" :value="scope.row.currency" />
        </template>
      </el-table-column>
      <el-table-column label="生效日期" align="center" prop="effectiveDate" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.effectiveDate, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="失效日期" align="center" prop="expiryDate" width="180">
        <template slot-scope="scope">
          <span v-if="scope.row.expiryDate" class="expiry-date">{{ parseTime(scope.row.expiryDate, '{y}-{m}-{d}') }}</span>
          <el-tag v-else type="success" size="small">至今生效</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="峰谷时段" align="center" prop="usePeakValley">
        <template slot-scope="scope">
          <el-tag :type="scope.row.usePeakValley === 1 ? 'success' : 'info'">
            {{ scope.row.usePeakValley === 1 ? '是' : '否' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="梯度收费" align="center" prop="useTieredPricing">
        <template slot-scope="scope">
          <el-tag :type="scope.row.useTieredPricing === 1 ? 'success' : 'info'">
            {{ scope.row.useTieredPricing === 1 ? '是' : '否' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="备注" align="center" prop="remark" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-setting"
            @click="handleConfig(scope.row)"
          >配置</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 费率可视化展示（浮动） -->
    <div v-if="selectedRateRow" class="rate-visualization-floating">
      <div class="visualization-header">
        <span class="visualization-title">
          {{ getEnergyName(selectedRateRow.energyTypeId) }} - 费率分布
        </span>
        <el-button size="mini" @click="selectedRateRow = null" style="color: #666; border: none; background: transparent;">✕</el-button>
      </div>

      <!-- 峰谷电费率展示（梯度+峰谷组合模式下不显示） -->
      <div v-if="selectedRateRow && parseInt(selectedRateRow.usePeakValley) === 1 && parseInt(selectedRateRow.useTieredPricing) === 0" class="visualization-section">
        <div class="section-subtitle">峰谷电费率分布</div>
        <div v-if="selectedPeriodList && selectedPeriodList.length > 0" class="bar-chart">
          <div class="chart-container">
            <div v-for="period in selectedPeriodList" :key="period.periodId" class="bar-item">
              <div class="bar-wrapper">
                <div 
                  class="bar" 
                  :style="{
                    height: period.rate ? (period.rate / selectedMaxPeriodRate) * 100 + '%' : '5%',
                    backgroundColor: getPeriodBgColor(period.periodType)
                  }">
                </div>
              </div>
              <div class="bar-label">
                <div class="time">{{ period.startTime }}-{{ period.endTime }}</div>
                <div class="rate">¥{{ period.rate || 0 }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 梯度电费率展示 -->
      <div v-if="selectedRateRow && parseInt(selectedRateRow.useTieredPricing) === 1" class="visualization-section">
        <div class="section-subtitle">梯度电费率分布</div>
        <div v-if="selectedTierList && selectedTierList.length > 0" class="bar-chart">
          <div class="chart-container">
            <div v-for="tier in selectedTierList" :key="tier.tierId" class="bar-item">
              <div class="bar-wrapper">
                <div 
                  class="bar tier-bar" 
                  :style="{
                    height: tier.rate ? (tier.rate / selectedMaxTierRate) * 100 + '%' : '5%'
                  }">
                </div>
              </div>
              <div class="bar-label">
                <div class="tier-info">第{{ tier.tierLevel }}梯</div>
                <div class="usage">{{ tier.minUsage }}-{{ tier.maxUsage ? tier.maxUsage : '∞' }}</div>
                <div class="rate">¥{{ tier.rate || 0 }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 固定费率展示 -->
      <div v-if="parseInt(selectedRateRow.usePeakValley) === 0 && parseInt(selectedRateRow.useTieredPricing) === 0" class="visualization-section">
        <div class="section-subtitle">📌 固定费率</div>
        <div class="fixed-rate-display">
          <div class="rate-box">
            <span class="rate-label">费率</span>
            <span class="rate-value">¥{{ selectedRateRow.rate }}/{{ getEnergyUnit(selectedRateRow.energyTypeId) }}</span>
          </div>
        </div>
      </div>
    </div>

    <!-- 添加或修改能源费率对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body @close="cancel">
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="能源类型" prop="energyTypeId">
          <el-select v-model="form.energyTypeId" placeholder="请选择能源类型">
            <el-option v-for="item in energyTypeList" :key="item.energyTypeId" :label="item.name" :value="item.energyTypeId" />
          </el-select>
        </el-form-item>
        <el-form-item label="基础费率" prop="rate">
          <el-input 
            v-model="form.rate" 
            placeholder="请输入费率"
            :disabled="form.usePeakValley === 1 || form.useTieredPricing === 1"
            @focus="onRateFieldFocus" />
          <span v-if="form.usePeakValley === 1 || form.useTieredPricing === 1" class="tip-text">
            ⓘ 已启用峰谷或梯度，基础费率由配置决定
          </span>
        </el-form-item>
        <el-form-item label="货币单位" prop="currency">
          <el-select v-model="form.currency" placeholder="请选择货币单位">
            <el-option v-for="item in dict.type.currency_unit" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="生效日期" prop="effectiveDate">
          <el-date-picker clearable
            v-model="form.effectiveDate"
            type="datetime"
            value-format="yyyy-MM-dd HH:mm:ss"
            placeholder="请选择生效日期">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="失效日期" prop="expiryDate">
          <el-date-picker clearable
            v-model="form.expiryDate"
            type="datetime"
            value-format="yyyy-MM-dd HH:mm:ss"
            placeholder="请选择失效日期">
          </el-date-picker>
        </el-form-item>
        <el-divider></el-divider>
        <el-form-item label="峰谷时段" prop="usePeakValley">
          <el-switch v-model="form.usePeakValley" :active-value="1" :inactive-value="0"></el-switch>
          <span class="ml10">{{ form.usePeakValley === 1 ? '启用' : '禁用' }}</span>
        </el-form-item>
        <el-form-item label="梯度收费" prop="useTieredPricing">
          <el-switch v-model="form.useTieredPricing" :active-value="1" :inactive-value="0"></el-switch>
          <span class="ml10">{{ form.useTieredPricing === 1 ? '启用' : '禁用' }}</span>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 费率配置对话框（分步骤向导式） -->
    <el-dialog title="费率配置向导" :visible.sync="configOpen" width="900px" :fullscreen="false" append-to-body @close="closeConfig">
      <!-- 步骤条 -->
      <el-steps :active="configStep" process-status="process" align-center class="wizard-steps">
        <el-step title="选择模式" icon="el-icon-setting"></el-step>
        <el-step v-if="form.usePeakValley === 1" title="配置峰谷" icon="el-icon-time"></el-step>
        <el-step v-if="form.useTieredPricing === 1" title="配置梯度" icon="el-icon-s-unfold"></el-step>
        <el-step title="预览保存" icon="el-icon-check"></el-step>
      </el-steps>

      <!-- 步骤内容 -->
      <div class="wizard-content" style="margin-top: 30px;">
        <!-- 第1步：选择模式 -->
        <div v-if="configStep === 0" class="step-content">
          <div class="mode-selection">
            <h3>请选择计价模式</h3>
            <div class="mode-cards">
              <div class="mode-card" @click="selectMode('fixed')" :class="{ active: form.usePeakValley === 0 && form.useTieredPricing === 0 }">
                <div class="mode-icon">📌</div>
                <div class="mode-name">固定费率</div>
                <div class="mode-desc">使用统一的费率</div>
              </div>
              <div class="mode-card" @click="selectMode('peak')" :class="{ active: form.usePeakValley === 1 && form.useTieredPricing === 0 }">
                <div class="mode-icon">📊</div>
                <div class="mode-name">峰谷分时</div>
                <div class="mode-desc">按时段设置费率</div>
              </div>
              <div class="mode-card" @click="selectMode('tier')" :class="{ active: form.usePeakValley === 0 && form.useTieredPricing === 1 }">
                <div class="mode-icon">📈</div>
                <div class="mode-name">梯度收费</div>
                <div class="mode-desc">按用量设置费率</div>
              </div>
              <div class="mode-card" @click="selectMode('combo')" :class="{ active: form.usePeakValley === 1 && form.useTieredPricing === 1 }">
                <div class="mode-icon">🔗</div>
                <div class="mode-name">峰谷+梯度</div>
                <div class="mode-desc">组合计价模式</div>
              </div>
            </div>
          </div>
        </div>

        <!-- 第2步：配置峰谷（仅在峰谷模式下显示） -->
        <div v-if="configStep === 1 && form.usePeakValley === 1" class="step-content">
          <div class="peak-valley-config">
            <h3>配置峰谷时段</h3>
            <el-alert
              title="峰谷时段说明"
              type="info"
              description="根据不同时段设置不同的费率。例如：8:00-12:00为峰时段（1.5元/度），12:00-18:00为平时段（1.0元/度），18:00-22:00为谷时段（0.5元/度）。"
              :closable="false"
              class="mb15">
            </el-alert>

            <div class="period-actions mb15">
              <el-button type="primary" size="small" icon="el-icon-plus" @click="addPeriod">添加时段</el-button>
              <span class="ml10" style="color: #909399;">已配置 {{ periodList.length }} 个时段</span>
            </div>

            <el-table :data="periodList" border stripe max-height="400" size="small">
              <el-table-column label="时段类型" align="center" min-width="110">
                <template slot-scope="scope">
                  <el-select v-model="scope.row.periodType" placeholder="请选择" size="small" style="width: 100%;">
                    <el-option label="🔴 峰" :value="0" />
                    <el-option label="🔵 谷" :value="1" />
                    <el-option label="🟡 平" :value="2" />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column label="时段名称" align="center" min-width="120">
                <template slot-scope="scope">
                  <el-input 
                    v-model="scope.row.periodName" 
                    placeholder="如：峰时段"
                    maxlength="15"
                    size="small"
                    style="width: 100%;" />
                </template>
              </el-table-column>
              <el-table-column label="开始时间" align="center" min-width="130">
                <template slot-scope="scope">
                  <el-time-picker 
                    v-model="scope.row.startTime" 
                    format="HH:mm" 
                    value-format="HH:mm" 
                    placeholder="HH:mm"
                    size="small"
                    style="width: 100%;"
                    @change="validatePeriodTime(scope.$index)" />
                </template>
              </el-table-column>
              <el-table-column label="结束时间" align="center" min-width="130">
                <template slot-scope="scope">
                  <el-time-picker 
                    v-model="scope.row.endTime" 
                    format="HH:mm" 
                    value-format="HH:mm" 
                    placeholder="HH:mm"
                    size="small"
                    style="width: 100%;"
                    @change="validatePeriodTime(scope.$index)" />
                </template>
              </el-table-column>
              <!-- 仅在非组合模式下显示费率列 -->
              <el-table-column v-if="form.useTieredPricing === 0" label="费率" align="center" min-width="120">
                <template slot-scope="scope">
                  <el-input-number 
                    v-model="scope.row.rate" 
                    :precision="4" 
                    :step="0.01"
                    :min="0"
                    size="small"
                    placeholder="如：1.5"
                    style="width: 100%;" />
                </template>
              </el-table-column>
              <el-table-column label="操作" align="center" min-width="80">
                <template slot-scope="scope">
                  <el-button size="mini" type="danger" icon="el-icon-delete" @click="removePeriod(scope.$index)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>

        <!-- 第2或3步：配置梯度 -->
        <div v-if="(configStep === 1 && form.useTieredPricing === 1 && form.usePeakValley === 0) || (configStep === 2 && form.useTieredPricing === 1)" class="step-content">
          <div class="tier-config">
            <h3>配置梯度收费</h3>
            <el-alert
              title="梯度收费说明"
              type="info"
              description="根据用量区间设置不同的费率。例如：0-100度按1.0元/度收费，100-200度按1.5元/度收费，200度以上按2.0元/度收费。"
              :closable="false"
              class="mb15">
            </el-alert>
            
            <div class="tier-actions mb15">
              <el-button type="primary" size="small" icon="el-icon-plus" @click="addTier">添加梯度</el-button>
              <span class="ml10" style="color: #909399;">已配置 {{ tierList.length }} 个梯度</span>
            </div>

            <el-table :data="tierList" border stripe max-height="400" size="small">
              <el-table-column label="梯度等级" align="center" min-width="100">
                <template slot-scope="scope">
                  <span class="tier-level-badge">第{{ scope.row.tierLevel }}梯</span>
                </template>
              </el-table-column>
              <el-table-column label="最小用量" align="center" min-width="140">
                <template slot-scope="scope">
                  <div class="tier-input-wrapper">
                    <el-input-number 
                      v-model="scope.row.minUsage" 
                      :precision="2" 
                      :step="0.01"
                      :min="0"
                      size="small"
                      placeholder="如：0"
                      style="width: 100%;"
                      @change="onTierMinUsageChange(scope.$index)" />
                    <span v-if="getTierValidationError(scope.$index, 'min')" class="tier-error">
                      {{ getTierValidationError(scope.$index, 'min') }}
                    </span>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="最大用量" align="center" min-width="140">
                <template slot-scope="scope">
                  <div class="tier-input-wrapper">
                    <el-input-number 
                      v-model="scope.row.maxUsage" 
                      :precision="2" 
                      :step="0.01"
                      size="small"
                      :placeholder="scope.$index === tierList.length - 1 ? '无上限' : '自动填充'"
                      style="width: 100%;"
                      @change="onTierMaxUsageChange(scope.$index)" />
                    <span v-if="getTierValidationError(scope.$index, 'max')" class="tier-error">
                      {{ getTierValidationError(scope.$index, 'max') }}
                    </span>
                  </div>
                </template>
              </el-table-column>
              <!-- 仅在非组合模式下显示费率列 -->
              <el-table-column v-if="form.usePeakValley === 0" label="费率" align="center" min-width="140">
                <template slot-scope="scope">
                  <el-input-number 
                    v-model="scope.row.rate" 
                    :precision="4" 
                    :step="0.01"
                    :min="0"
                    size="small"
                    placeholder="如：1.5"
                    style="width: 100%;" />
                </template>
              </el-table-column>
              <!-- 组合模式下显示配置峰谷按钮 -->
              <el-table-column v-if="form.usePeakValley === 1" label="配置峰谷" align="center" min-width="140">
                <template slot-scope="scope">
                  <el-button 
                    size="mini" 
                    type="primary" 
                    icon="el-icon-edit"
                    @click="editTierPeriods(scope.row, scope.$index)">
                    配置峰谷
                  </el-button>
                </template>
              </el-table-column>
              <el-table-column label="操作" align="center" min-width="80">
                <template slot-scope="scope">
                  <el-button size="mini" type="danger" icon="el-icon-delete" @click="removeTier(scope.$index)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>

        <!-- 最后一步：预览和保存 -->
        <div v-if="isLastStep" class="step-content">
          <div class="preview-section">
            <h3>预览配置信息</h3>
            
            <!-- 模式说明 -->
            <div class="preview-card">
              <div class="card-title">计价模式</div>
              <div class="card-content">
                <span v-if="form.useTieredPricing === 0 && form.usePeakValley === 0" class="tip-badge fixed-mode">
                  📌 固定费率模式
                </span>
                <span v-else-if="form.useTieredPricing === 0 && form.usePeakValley === 1" class="tip-badge peak-mode">
                  📊 峰谷分时模式
                </span>
                <span v-else-if="form.useTieredPricing === 1 && form.usePeakValley === 0" class="tip-badge tier-mode">
                  📈 梯度收费模式
                </span>
                <span v-else class="tip-badge combo-mode">
                  🔗 梯度+峰谷组合模式
                </span>
              </div>
            </div>

            <!-- 峰谷预览 -->
            <div v-if="form.usePeakValley === 1" class="preview-card">
              <div class="card-title">峰谷时段</div>
              <div class="card-content">
                <div v-for="period in periodList" :key="period.periodId" class="preview-item">
                  <span class="period-badge" :style="{ backgroundColor: getPeriodBgColor(period.periodType) }">
                    {{ getPeriodName(period.periodType) }}
                  </span>
                  <span>{{ period.startTime }} - {{ period.endTime }}</span>
                  <!-- 仅在非组合模式下显示费率 -->
                  <span v-if="form.useTieredPricing === 0" class="rate-value">¥{{ period.rate }}/{{ energyUnit }}</span>
                </div>
              </div>
            </div>

            <!-- 梯度预览 -->
            <div v-if="form.useTieredPricing === 1" class="preview-card">
              <div class="card-title">梯度收费</div>
              <div class="card-content">
                <!-- 仅梯度模式：显示梯度费率 -->
                <div v-if="form.usePeakValley === 0">
                  <div v-for="tier in tierList" :key="tier.tierId" class="preview-item">
                    <span class="tier-badge">第{{ tier.tierLevel }}梯</span>
                    <span>{{ tier.minUsage }} - {{ tier.maxUsage ? tier.maxUsage : '∞' }} {{ energyUnit }}</span>
                    <span class="rate-value">¥{{ tier.rate }}/{{ energyUnit }}</span>
                  </div>
                </div>
                <!-- 组合模式：显示梯度的峰谷费率 -->
                <div v-else>
                  <div v-for="tier in tierList" :key="tier.tierId" class="tier-group">
                    <div class="tier-header">第{{ tier.tierLevel }}梯 ({{ tier.minUsage }} - {{ tier.maxUsage ? tier.maxUsage : '∞' }} {{ energyUnit }})</div>
                    <div v-for="period in periodList" :key="`${tier.tierId}-${period.periodId}`" class="preview-item" style="margin-left: 20px;">
                      <span class="period-badge" :style="{ backgroundColor: getPeriodBgColor(period.periodType) }">
                        {{ getPeriodName(period.periodType) }}
                      </span>
                      <span>{{ period.startTime }} - {{ period.endTime }}</span>
                      <span class="rate-value">¥{{ tier.tierPeriodRates && tier.tierPeriodRates[period.periodId || period._key] ? tier.tierPeriodRates[period.periodId || period._key] : 0 }}/{{ energyUnit }}</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div slot="footer" class="dialog-footer">
        <el-button v-if="configStep > 0" @click="prevStep">上 一 步</el-button>
        <el-button v-if="configStep < 3" type="primary" @click="nextStep">下 一 步</el-button>
        <el-button v-if="configStep === 3" :loading="buttonLoading" type="primary" @click="saveConfig">保 存 配 置</el-button>
        <el-button @click="closeConfig">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 梯度-时段费率编辑对话框 -->
    <el-dialog 
      v-if="currentTier"
      :title="`第${currentTier.tierLevel}梯 (${currentTier.minUsage}~${currentTier.maxUsage ? currentTier.maxUsage : '∞'}${energyUnit}) 的峰谷费率配置`"
      :visible.sync="tierPeriodDialogOpen" 
      width="900px" 
      append-to-body 
      @close="closeTierPeriodDialog">
      
      <el-alert
        title="梯度峰谷费率说明"
        type="info"
        description="为该梯度的每个时段（峰/谷/平）设置不同的费率。例如：第1梯度的峰时段1.5元/度，谷时段0.5元/度。"
        :closable="false"
        class="mb15">
      </el-alert>

      <el-table :data="currentTierPeriods" border stripe max-height="400" size="small">
        <el-table-column label="时段类型" align="center" width="100">
          <template slot-scope="scope">
            <el-select v-model="scope.row.periodType" placeholder="请选择" size="small" style="width: 100%;" disabled>
              <el-option label="🔴 峰" :value="0" />
              <el-option label="🔵 谷" :value="1" />
              <el-option label="🟡 平" :value="2" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="时段名称" align="center" width="120">
          <template slot-scope="scope">
            <span>{{ scope.row.periodName }}</span>
          </template>
        </el-table-column>
        <el-table-column label="时间范围" align="center" width="140">
          <template slot-scope="scope">
            <span style="font-size: 12px;">{{ scope.row.startTime }} - {{ scope.row.endTime }}</span>
          </template>
        </el-table-column>
        <el-table-column label="费率" align="center" width="140">
          <template slot-scope="scope">
            <el-input-number 
              v-model="scope.row.rate" 
              :precision="4" 
              :step="0.01"
              :min="0"
              size="small"
              placeholder="如：1.5"
              style="width: 100%;" />
          </template>
        </el-table-column>
        <el-table-column label="说明" align="center" min-width="150">
          <template slot-scope="scope">
            <span style="color: #606266; font-size: 11px;">
              {{ scope.row.startTime }} - {{ scope.row.endTime }}<br/>
              @ {{ scope.row.rate }} 元/{{ energyUnit }}
            </span>
          </template>
        </el-table-column>
      </el-table>

      <div slot="footer" class="dialog-footer">
        <el-button :loading="buttonLoading" type="primary" @click="saveTierPeriods">保 存</el-button>
        <el-button @click="closeTierPeriodDialog">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listEnergyRate, getEnergyRate, delEnergyRate, addEnergyRate, updateEnergyRate, getRateTiers, getRateTimePeriods, saveTiers, saveTimePeriods, getTierPeriodLinks, saveTierPeriodLinks } from "@/api/ems/energyRate";
import { listEnergyType } from "@/api/ems/energyType";

export default {
  name: "EnergyRate",
  dicts: ['currency_unit'],
  data() {
    return {
      energyTypeList: [],
      // 按钮loading
      buttonLoading: false,
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 能源费率表格数据
      energyRateList: [],
      // 费率详情缓存（energyRateId -> {tiers, periods, tierPeriodRates}）
      rateDetailsCache: {},
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 是否显示配置对话框
      configOpen: false,
      // 梯度费率列表
      tierList: [],
      // 时段费率列表
      periodList: [],
      // 能源单位
      energyUnit: '度',
      // 梯度-时段关联对话框
      tierPeriodDialogOpen: false,
      // 当前编辑的梯度
      currentTier: null,
      // 当前梯度的峰谷费率列表
      currentTierPeriods: [],
      // 向导步骤（0=选择模式, 1=配置峰谷或梯度, 2=配置梯度(组合模式), 3=预览保存）
      configStep: 0,
      // 选中的费率行（用于显示条形图）
      selectedRateRow: null,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        energyTypeId: undefined,
        rate: undefined,
        currency: undefined,
        effectiveDate: undefined,
        expiryDate: undefined,
      },
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        energyTypeId: [
          { required: true, message: "能源类型不能为空", trigger: "change" }
        ],
        effectiveDate: [
          { required: true, message: "生效日期不能为空", trigger: "change" }
        ],
        rate: [
          { 
            validator: (rule, value, callback) => {
              // 如果启用了梯度或峰谷，基础费率不是必需的
              if (this.form.usePeakValley === 1 || this.form.useTieredPricing === 1) {
                callback();
              } else {
                // 固定费率模式下，基础费率是必需的
                if (!value) {
                  callback(new Error("固定费率模式下，基础费率不能为空"));
                } else if (value < 0) {
                  callback(new Error("基础费率不能为负数"));
                } else {
                  callback();
                }
              }
            },
            trigger: "change"
          }
        ]
      }
    };
  },
  computed: {
    /** 选中行的时段列表 */
    selectedPeriodList() {
      if (!this.selectedRateRow) return [];
      const periods = this.rateDetailsCache[this.selectedRateRow.energyRateId]?.periods || [];
      return periods;
    },
    /** 选中行的梯度列表 */
    selectedTierList() {
      if (!this.selectedRateRow) return [];
      // 直接使用列表返回的梯度数据
      return this.selectedRateRow.tiers || [];
    },
    /** 选中行的最大时段费率 */
    selectedMaxPeriodRate() {
      if (this.selectedPeriodList.length === 0) return 1;
      const max = Math.max(...this.selectedPeriodList.map(item => item.rate || 0));
      return max > 0 ? max : 1;
    },
    /** 选中行的最大梯度费率 */
    selectedMaxTierRate() {
      if (this.selectedTierList.length === 0) return 1;
      const max = Math.max(...this.selectedTierList.map(item => item.rate || 0));
      return max > 0 ? max : 1;
    },
    /** 是否是最后一步 */
    isLastStep() {
      if (!this.form) return false;
      return this.configStep === 3;
    }
  },
  created() {
    this.getList();
    this.getEnergyTypeList();
  },
  methods: {
    /** 查询能源费率（currency 为 INT：0=CNY,1=USD,2=EUR）列表 */
    getList() {
      this.loading = true;
      listEnergyRate(this.queryParams).then(response => {
        this.energyRateList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    getEnergyTypeList() {
      listEnergyType({ pageNum: 1, pageSize: 9999 }).then(response => {
        this.energyTypeList = response.rows;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        energyRateId: undefined,
        energyTypeId: undefined,
        rate: undefined,
        currency: undefined,
        effectiveDate: undefined,
        expiryDate: undefined,
        createBy: undefined,
        updateBy: undefined,
        createTime: undefined,
        updateTime: undefined,
        delFlag: undefined,
        remark: undefined
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.energyRateId)
      this.single = selection.length!==1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加能源费率";
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.loading = true;
      this.reset();
      const energyRateId = row.energyRateId || this.ids
      getEnergyRate(energyRateId).then(response => {
        this.loading = false;
        this.form = response.data;
        this.open = true;
        this.title = "修改能源费率";
      });
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.buttonLoading = true;
          if (this.form.energyRateId != null) {
            updateEnergyRate(this.form).then(response => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            }).finally(() => {
              this.buttonLoading = false;
            });
          } else {
            addEnergyRate(this.form).then(response => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            }).finally(() => {
              this.buttonLoading = false;
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const energyRateIds = row.energyRateId || this.ids;
      this.$modal.confirm('是否确认删除能源费率（currency 为 INT：0=CNY,1=USD,2=EUR）编号为"' + energyRateIds + '"的数据项？').then(() => {
        this.loading = true;
        return delEnergyRate(energyRateIds);
      }).then(() => {
        this.loading = false;
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {
      }).finally(() => {
        this.loading = false;
      });
    },
    getEnergyName(id) {
      const item = this.energyTypeList.find(item => item.energyTypeId === id);
      return item?.name ?? '';
    },
    getEnergyUnit(id) {
      return this.energyTypeList.find(item => item.energyTypeId === id)?.unit ?? '度';
    },
    /** 获取费率的梯度列表 */
    getRateTiers(energyRateId) {
      if (!this.rateDetailsCache[energyRateId]) {
        this.rateDetailsCache[energyRateId] = { tiers: [], periods: [], tierPeriodRates: {} };
        getRateTiers(energyRateId).then(response => {
          this.$set(this.rateDetailsCache[energyRateId], 'tiers', response.data || []);
        });
      }
      return this.rateDetailsCache[energyRateId].tiers || [];
    },
    /** 获取费率的时段列表 */
    getRatePeriods(energyRateId) {
      if (!this.rateDetailsCache[energyRateId]) {
        this.rateDetailsCache[energyRateId] = { tiers: [], periods: [], tierPeriodRates: {} };
      }
      if (!this.rateDetailsCache[energyRateId].periods || this.rateDetailsCache[energyRateId].periods.length === 0) {
        getRateTimePeriods(energyRateId).then(response => {
          this.$set(this.rateDetailsCache[energyRateId], 'periods', response.data || []);
        });
      }
      return this.rateDetailsCache[energyRateId].periods || [];
    },
    /** 获取时段名称 */
    getPeriodName(periodType) {
      const names = {
        0: '峰',
        1: '谷',
        2: '平'
      };
      return names[periodType] || '未知';
    },
    /** 获取时段背景颜色 */
    getPeriodBgColor(periodType) {
      const colors = {
        0: '#FF6B6B',  // 峰 - 红色
        1: '#4ECDC4',  // 谷 - 青色
        2: '#FFD93D'   // 平 - 黄色
      };
      return colors[periodType] || '#409EFF';
    },
    /** 获取梯度-时段的费率 */
    getTierPeriodRate(tierId, periodId) {
      if (!this.selectedRateRow || !this.selectedRateRow.tiers) return '-';
      // 从梯度对象中查找对应的梯度
      const tier = this.selectedRateRow.tiers.find(t => t.tierId === tierId);
      if (!tier || !tier.tierPeriodRates) return '-';
      // 从梯度的时段费率映射中获取该时段的费率
      const rate = tier.tierPeriodRates[periodId];
      return rate !== undefined && rate !== null ? rate : '-';
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('ems/energyRate/export', {
        ...this.queryParams
      }, `energyRate_${new Date().getTime()}.xlsx`)
    },
    /** 配置按钮操作 */
    handleConfig(row) {
      this.loading = true;
      this.form = JSON.parse(JSON.stringify(row));
      this.tierList = [];
      this.periodList = [];
      this.configStep = 0;  // 重置步骤
      
      // 获取能源单位
      const energyType = this.energyTypeList.find(item => item.energyTypeId === row.energyTypeId);
      this.energyUnit = energyType ? energyType.unit : '度';
      
      // 根据模式直接跳到对应步骤
      if (this.form.usePeakValley === 0 && this.form.useTieredPricing === 0) {
        // 固定费率模式，直接到预览
        this.configStep = 3;
        this.loading = false;
        this.configOpen = true;
      } else if (this.form.usePeakValley === 1 && this.form.useTieredPricing === 0) {
        // 峰谷模式，进入峰谷配置
        this.configStep = 1;
        getRateTimePeriods(row.energyRateId).then(response => {
          this.periodList = response.data || [];
          if (this.periodList.length === 0) {
            this.addPeriod();
          }
          this.loading = false;
          this.configOpen = true;
        });
      } else if (this.form.usePeakValley === 0 && this.form.useTieredPricing === 1) {
        // 梯度模式，进入梯度配置
        this.configStep = 1;
        getRateTiers(row.energyRateId).then(response => {
          this.tierList = response.data || [];
          if (this.tierList.length === 0) {
            this.addTier();
          }
          this.loading = false;
          this.configOpen = true;
        });
      } else {
        // 组合模式（峰谷+梯度），进入峰谷配置
        this.configStep = 1;
        getRateTimePeriods(row.energyRateId).then(response => {
          this.periodList = response.data || [];
          if (this.periodList.length === 0) {
            this.addPeriod();
          }
          // 加载梯度费率（需要在时段加载完成后）
          this.loadTiersWithPeriods(row.energyRateId);
        });
      }
    },
    /** 加载梯度费率及其峰谷关联 */
    loadTiersWithPeriods(energyRateId) {
      if (this.form.useTieredPricing === 1) {
        getRateTiers(energyRateId).then(response => {
          this.tierList = response.data || [];
          if (this.tierList.length === 0) {
            this.addTier();
            this.loading = false;
            this.configOpen = true;
            return;
          }
          
          // 如果是梯度+峰谷组合模式，需要加载每个梯度的峰谷费率
          if (this.form.usePeakValley === 1) {
            this.loadTierPeriodRates();
          } else {
            this.loading = false;
            this.configOpen = true;
          }
        });
      } else {
        this.loading = false;
        this.configOpen = true;
      }
    },
    /** 加载梯度的峰谷费率关联 */
    loadTierPeriodRates() {
      // 为每个梯度加载其对应的峰谷费率
      const promises = this.tierList.map(tier => {
        return getTierPeriodLinks(tier.tierId).then(response => {
          tier.tierPeriodRates = {};
          if (response.data && response.data.length > 0) {
            response.data.forEach(link => {
              tier.tierPeriodRates[link.periodId] = link.rate;
            });
          }
        }).catch(() => {
          tier.tierPeriodRates = {};
        });
      });
      
      Promise.all(promises).then(() => {
        this.loading = false;
        this.configOpen = true;
      }).catch(() => {
        this.loading = false;
        this.configOpen = true;
      });
    },
    /** 添加梯度 */
    addTier() {
      const tierLevel = this.tierList.length + 1;
      this.tierList.push({
        tierLevel: tierLevel,
        minUsage: 0,
        maxUsage: null,
        rate: 0
      });
    },
    /** 删除梯度 */
    removeTier(index) {
      this.tierList.splice(index, 1);
    },
    /** 添加时段 */
    addPeriod() {
      this.periodList.push({
        periodType: 0,
        periodName: '',
        startTime: '00:00',
        endTime: '23:59',
        rate: 0
      });
    },
    /** 删除时段 */
    removePeriod(index) {
      this.periodList.splice(index, 1);
    },
    /** 保存配置 */
    saveConfig() {
      // 验证梯度数据
      if (this.form.useTieredPricing === 1) {
        if (!this.validateTiers()) {
          return;
        }
      }
      
      // 验证时段数据
      if (this.form.usePeakValley === 1) {
        if (!this.validatePeriods()) {
          return;
        }
      }
      
      this.buttonLoading = true;
      
      // 先保存梯度费率，然后再保存时段费率和梯度-时段关联
      const savePromise = new Promise((resolve, reject) => {
        const promises = [];
        
        // 1. 保存梯度费率
        if (this.form.useTieredPricing === 1 && this.tierList.length > 0) {
          // 处理梯度数据：最后一个梯度的 maxUsage 应该为 null
          const tiersToSave = this.tierList.map((tier, index) => {
            const tierCopy = JSON.parse(JSON.stringify(tier));
            if (index === this.tierList.length - 1) {
              // 最后一个梯度的 maxUsage 设为 null
              tierCopy.maxUsage = null;
            }
            // 为了避免唯一约束冲突，清除 tierId 让后端重新生成
            // 这样可以确保后端执行 INSERT 而不是 UPDATE
            // 但需要先删除旧梯度
            delete tierCopy.tierId;
            return tierCopy;
          });
          
          promises.push(
            saveTiers(this.form.energyRateId, tiersToSave).then(response => {
              // 梯度保存成功后，更新本地梯度的 tierId（保留 tierPeriodRates）
              if (response.data && Array.isArray(response.data)) {
                // 按 tier_level 匹配，更新 tierId
                response.data.forEach((savedTier) => {
                  const localTier = this.tierList.find(t => t.tierLevel === savedTier.tierLevel);
                  if (localTier) {
                    // 保留本地的 tierPeriodRates，只更新 tierId
                    localTier.tierId = savedTier.tierId;
                    localTier.minUsage = savedTier.minUsage;
                    localTier.maxUsage = savedTier.maxUsage;
                    localTier.rate = savedTier.rate;
                  }
                });
              }
              return response;
            })
          );
        }
        
        // 2. 保存时段费率
        if (this.form.usePeakValley === 1 && this.periodList.length > 0) {
          // 组合模式下不需要费率，仅峰谷模式需要费率
          const validPeriods = this.form.useTieredPricing === 0 
            ? this.periodList.filter(p => p.periodType !== null && p.periodType !== undefined && p.rate)
            : this.periodList.filter(p => p.periodType !== null && p.periodType !== undefined);
          if (validPeriods.length > 0) {
            // 分离新增和已有的时段
            const newPeriods = validPeriods.filter(p => !p.periodId);
            const existingPeriods = validPeriods.filter(p => p.periodId);
            
            // 如果有新增时段，需要先保存时段定义再保存费率
            if (newPeriods.length > 0) {
              // 新增时段需要先保存到 ems_time_period 表
              const saveNewPeriodsPromise = new Promise((resolve, reject) => {
                // 调用后端保存时段定义的接口（假设存在）
                // 这里暂时直接保存费率，后端需要处理 periodId 为 null 的情况
                const periodsToSave = validPeriods.map(p => {
                  const periodCopy = { ...p };
                  periodCopy.periodId = p.periodId || null;  // 新增时段的 periodId 为 null
                  // 在组合模式下，清除费率（不需要保存到 ems_rate_time_period_link）
                  if (this.form.useTieredPricing === 1) {
                    periodCopy.rate = null;
                  }
                  return periodCopy;
                });
                saveTimePeriods(this.form.energyRateId, periodsToSave).then(response => {
                  // 保存成功后，更新本地 periodList 中的 periodId
                  if (response.data && Array.isArray(response.data)) {
                    response.data.forEach((savedPeriod, index) => {
                      if (validPeriods[index] && !validPeriods[index].periodId) {
                        validPeriods[index].periodId = savedPeriod.periodId;
                      }
                    });
                  }
                  resolve(response);
                }).catch(reject);
              });
              promises.push(saveNewPeriodsPromise);
            } else {
              // 只有已有的时段，直接保存
              const periodsToSave = validPeriods.map(p => {
                const periodCopy = { ...p };
                // 在组合模式下，清除费率（不需要保存到 ems_rate_time_period_link）
                if (this.form.useTieredPricing === 1) {
                  periodCopy.rate = null;
                }
                return periodCopy;
              });
              promises.push(saveTimePeriods(this.form.energyRateId, periodsToSave));
            }
          }
        }
        
        if (promises.length === 0) {
          this.$modal.msgWarning('请至少配置一种收费方式');
          this.buttonLoading = false;
          reject('没有需要保存的数据');
          return;
        }
        
        // 等待梯度和时段都保存完成
        Promise.all(promises).then(() => {
          // 3. 保存梯度-时段关联费率（梯度+峰谷组合模式）
          const tierPeriodPromises = [];
          if (this.form.useTieredPricing === 1 && this.form.usePeakValley === 1) {
            console.log('开始保存梯度-时段关联，梯度数量:', this.tierList.length);
            this.tierList.forEach((tier, index) => {
              console.log(`梯度${index}: tierId=${tier.tierId}, tierPeriodRates=${tier.tierPeriodRates ? Object.keys(tier.tierPeriodRates).length : 0}个`);
              if (tier.tierId && tier.tierPeriodRates && Object.keys(tier.tierPeriodRates).length > 0) {
                // 将 tierPeriodRates 对象转换为数组格式
                // 需要使用 periodList 中的实际 periodId，而不是 tierPeriodRates 的 key
                const tierPeriodLinks = this.periodList.map(period => {
                  // 使用 periodId 或 _key 作为 key 查找费率
                  const key = period.periodId || period._key;
                  const rate = tier.tierPeriodRates[key];
                  if (rate !== undefined && rate !== null) {
                    return {
                      tierId: tier.tierId,
                      periodId: period.periodId,  // 使用真实的 periodId
                      rate: rate
                    };
                  }
                  return null;
                }).filter(link => link !== null);
                
                console.log('保存梯度-时段关联: tierId=' + tier.tierId + ', links=', tierPeriodLinks);
                if (tierPeriodLinks.length > 0) {
                  tierPeriodPromises.push(saveTierPeriodLinks(tier.tierId, tierPeriodLinks));
                }
              }
            });
            console.log('梯度-时段关联Promise数量:', tierPeriodPromises.length);
          }
          
          if (tierPeriodPromises.length > 0) {
            Promise.all(tierPeriodPromises).then(() => {
              resolve();
            }).catch(reject);
          } else {
            resolve();
          }
        }).catch(reject);
      });
      
      savePromise.then(() => {
        this.$modal.msgSuccess('保存成功');
        // 保存成功后，重新加载当前费率的配置
        const energyRateId = this.form.energyRateId;
        
        // 重新加载时段和梯度-时段关联数据（梯度已在保存时更新）
        const reloadPromises = [];
        if (this.form.usePeakValley === 1) {
          reloadPromises.push(
            getRateTimePeriods(energyRateId).then(response => {
              this.periodList = response.data || [];
            })
          );
        }
        
        // 如果是组合模式，需要重新加载梯度-时段关联
        if (this.form.useTieredPricing === 1 && this.form.usePeakValley === 1) {
          reloadPromises.push(
            new Promise((resolve) => {
              this.loadTierPeriodRates();
              resolve();
            })
          );
        }
        
        Promise.all(reloadPromises).then(() => {
          // 延迟关闭，确保对话框完全关闭
          setTimeout(() => {
            this.closeConfig();
            this.getList();
          }, 500);
        }).catch(() => {
          this.$modal.msgWarning('数据刷新失败，请手动刷新');
          setTimeout(() => {
            this.closeConfig();
            this.getList();
          }, 500);
        });
      }).catch(() => {
        this.$modal.msgError('保存失败');
      }).finally(() => {
        this.buttonLoading = false;
      });
    },
    /** 将时间字符串转换为分钟数（便于比较） */
    timeToMinutes(timeStr) {
      if (!timeStr) return 0;
      const [hours, minutes] = timeStr.split(':').map(Number);
      return hours * 60 + minutes;
    },
    /** 检查是否跨天 */
    isCrossDay(startTime, endTime) {
      if (!startTime || !endTime) return false;
      const startMin = this.timeToMinutes(startTime);
      const endMin = this.timeToMinutes(endTime);
      return startMin > endMin;  // 开始时间 > 结束时间 说明跨天
    },
    /** 验证时段时间范围和交叉 */
    validatePeriodTime(periodIndex) {
      const period = this.periodList[periodIndex];
      if (!period) return;
      
      // 如果两个时间都有，检查是否交叉
      if (period.startTime && period.endTime) {
        const startMin = this.timeToMinutes(period.startTime);
        const endMin = this.timeToMinutes(period.endTime);
        const isCross = this.isCrossDay(period.startTime, period.endTime);
        
        // 如果是跨天时段，提示用户
        if (isCross) {
          // 跨天时段是允许的，但要提示用户
          // 不需要报错，只是记录跨天状态
          period.crossDay = 1;
        } else {
          period.crossDay = 0;
        }
        
        // 检查与其他时段是否交叉（需要考虑跨天情况）
        for (let i = 0; i < this.periodList.length; i++) {
          if (i === periodIndex) continue;
          
          const otherPeriod = this.periodList[i];
          if (!otherPeriod.startTime || !otherPeriod.endTime) continue;
          
          const otherStartMin = this.timeToMinutes(otherPeriod.startTime);
          const otherEndMin = this.timeToMinutes(otherPeriod.endTime);
          const otherIsCross = this.isCrossDay(otherPeriod.startTime, otherPeriod.endTime);
          
          // 简化交叉检查：如果都不跨天，用简单逻辑；如果有跨天，需要特殊处理
          let hasConflict = false;
          if (!isCross && !otherIsCross) {
            // 都不跨天：检查是否有重叠
            hasConflict = startMin < otherEndMin && endMin > otherStartMin;
          } else if (isCross && otherIsCross) {
            // 都跨天：都包含午夜，肯定有冲突
            hasConflict = true;
          } else {
            // 一个跨天一个不跨天：需要特殊检查
            if (isCross) {
              // 当前跨天，其他不跨天
              hasConflict = !(otherEndMin <= startMin || otherStartMin >= endMin);
            } else {
              // 当前不跨天，其他跨天
              hasConflict = !(endMin <= otherStartMin || startMin >= otherEndMin);
            }
          }
          
          if (hasConflict) {
            this.$modal.msgWarning(`第${periodIndex + 1}个时段与第${i + 1}个时段时间交叉，请调整`);
            return;
          }
        }
        
        // 如果当前时段完整，自动填充下一个时段的开始时间
        if (periodIndex < this.periodList.length - 1) {
          const nextPeriod = this.periodList[periodIndex + 1];
          if (!nextPeriod.startTime) {
            // 下一个时段的开始时间 = 当前时段的结束时间 + 1分钟
            const endMin = this.timeToMinutes(period.endTime);
            const nextMin = endMin + 1;
            const hours = Math.floor(nextMin / 60) % 24;  // 防止超过24小时
            const minutes = nextMin % 60;
            nextPeriod.startTime = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
          }
        }
      }
    },
    /** 验证所有时段数据 */
    validatePeriods() {
      if (this.periodList.length === 0) {
        return true;
      }
      
      for (let i = 0; i < this.periodList.length; i++) {
        const period = this.periodList[i];
        
        // 检查时段类型（periodType 是必需的）
        if (period.periodType === null || period.periodType === undefined) {
          this.$modal.msgError(`第${i + 1}个时段：时段类型不能为空`);
          return false;
        }
        
        // 检查开始时间
        if (!period.startTime) {
          this.$modal.msgError(`第${i + 1}个时段：开始时间不能为空`);
          return false;
        }
        
        // 检查结束时间
        if (!period.endTime) {
          this.$modal.msgError(`第${i + 1}个时段：结束时间不能为空`);
          return false;
        }
        
        // 检查时间范围（支持跨天）
        const startMin = this.timeToMinutes(period.startTime);
        const endMin = this.timeToMinutes(period.endTime);
        const isCross = this.isCrossDay(period.startTime, period.endTime);
        
        // 跨天时段是允许的（如 22:00 - 02:00），不需要报错
        // 只有当不跨天且结束时间 <= 开始时间时才报错
        if (!isCross && startMin >= endMin) {
          this.$modal.msgError(`第${i + 1}个时段：结束时间必须晚于开始时间`);
          return false;
        }
        
        // 仅在非组合模式下检查费率
        if (this.form.useTieredPricing === 0) {
          if (period.rate === null || period.rate === undefined) {
            this.$modal.msgError(`第${i + 1}个时段：费率不能为空`);
            return false;
          }
          
          if (period.rate < 0) {
            this.$modal.msgError(`第${i + 1}个时段：费率不能为负数`);
            return false;
          }
        }
      }
      
      return true;
    },
    /** 选择计价模式 */
    selectMode(mode) {
      switch(mode) {
        case 'fixed':
          this.form.usePeakValley = 0;
          this.form.useTieredPricing = 0;
          this.configStep = 3;  // 直接到预览
          break;
        case 'peak':
          this.form.usePeakValley = 1;
          this.form.useTieredPricing = 0;
          this.configStep = 1;
          if (this.periodList.length === 0) {
            this.addPeriod();
          }
          break;
        case 'tier':
          this.form.usePeakValley = 0;
          this.form.useTieredPricing = 1;
          this.configStep = 1;
          if (this.tierList.length === 0) {
            this.addTier();
          }
          break;
        case 'combo':
          this.form.usePeakValley = 1;
          this.form.useTieredPricing = 1;
          this.configStep = 1;
          if (this.periodList.length === 0) {
            this.addPeriod();
          }
          if (this.tierList.length === 0) {
            this.addTier();
          }
          break;
      }
    },
    /** 下一步 */
    nextStep() {
      // 验证当前步骤的数据
      if (this.configStep === 1 && this.form.usePeakValley === 1 && this.form.useTieredPricing === 0) {
        // 峰谷模式，验证时段
        if (!this.validatePeriods()) {
          return;
        }
        this.configStep = 3;  // 直接到预览
      } else if (this.configStep === 1 && this.form.usePeakValley === 0 && this.form.useTieredPricing === 1) {
        // 梯度模式，验证梯度
        if (!this.validateTiers()) {
          return;
        }
        this.configStep = 3;  // 直接到预览
      } else if (this.configStep === 1 && this.form.usePeakValley === 1 && this.form.useTieredPricing === 1) {
        // 组合模式，验证时段后进入梯度配置
        if (!this.validatePeriods()) {
          return;
        }
        this.configStep = 2;
      } else if (this.configStep === 2) {
        // 梯度配置，验证梯度后进入预览
        if (!this.validateTiers()) {
          return;
        }
        this.configStep = 3;
      }
    },
    /** 上一步 */
    prevStep() {
      if (this.configStep > 0) {
        if (this.configStep === 3) {
          // 从预览回到配置
          if (this.form.usePeakValley === 1 && this.form.useTieredPricing === 1) {
            this.configStep = 2;  // 组合模式回到梯度配置
          } else if (this.form.usePeakValley === 1 || this.form.useTieredPricing === 1) {
            this.configStep = 1;  // 单一模式回到配置
          } else {
            this.configStep = 0;  // 固定费率回到模式选择
          }
        } else if (this.configStep === 2) {
          // 从梯度配置回到峰谷配置
          this.configStep = 1;
        } else if (this.configStep === 1) {
          // 回到模式选择
          this.configStep = 0;
        }
      }
    },
    /** 关闭配置对话框 */
    closeConfig() {
      this.configOpen = false;
      this.configStep = 0;
      this.tierList = [];
      this.periodList = [];
      this.energyUnit = '度';
    },
    /** 表格行点击事件 */
    handleRowClick(row) {
      // 如果点击的是同一行，则关闭条形图
      if (this.selectedRateRow && this.selectedRateRow.energyRateId === row.energyRateId) {
        this.selectedRateRow = null;
      } else {
        // 显示该行的条形图
        this.selectedRateRow = row;
      }
    },
    /** 费率字段焦点事件 */
    onRateFieldFocus() {
      if (this.form.usePeakValley === 1 || this.form.useTieredPricing === 1) {
        this.$modal.msgInfo('已启用峰谷或梯度收费，请在配置页面设置具体费率');
      }
    },
    /** 编辑梯度的峰谷费率 */
    editTierPeriods(tier, tierIndex) {
      this.currentTier = tier;
      this.currentTierPeriods = this.periodList.map((period, index) => {
        // 使用 periodId 作为 key（必须有 periodId）
        const key = period.periodId;
        return {
          ...period,
          _key: key,  // 保存原始 key 用于后续保存
          rate: tier.tierPeriodRates && tier.tierPeriodRates[key] ? tier.tierPeriodRates[key] : null
        };
      });
      this.tierPeriodDialogOpen = true;
    },
    /** 保存梯度的峰谷费率 */
    saveTierPeriods() {
      // 将当前梯度的峰谷费率保存到梯度对象中
      if (!this.currentTier.tierPeriodRates) {
        this.currentTier.tierPeriodRates = {};
      }
      this.currentTierPeriods.forEach(period => {
        // 使用 periodId 作为 key（必须有 periodId）
        const key = period.periodId;
        this.currentTier.tierPeriodRates[key] = period.rate;
      });
      console.log('保存梯度峰谷费率: tierId=' + this.currentTier.tierId + ', rates=', this.currentTier.tierPeriodRates);
      this.closeTierPeriodDialog();
    },
    /** 关闭梯度-时段编辑对话框 */
    closeTierPeriodDialog() {
      this.tierPeriodDialogOpen = false;
      this.currentTier = null;
      this.currentTierPeriods = [];
    },
    /** 获取最大费率 */
    getMaxRate(list) {
      if (!list || list.length === 0) return 1;
      const max = Math.max(...list.map(item => item.rate || 0));
      return max > 0 ? max : 1;
    },
    /** 获取梯度验证错误信息 */
    getTierValidationError(tierIndex, field) {
      const tier = this.tierList[tierIndex];
      if (!tier) return '';
      
      if (field === 'min') {
        if (tier.minUsage === null || tier.minUsage === undefined) {
          return '最小用量必填';
        }
        if (tier.minUsage < 0) {
          return '不能为负数';
        }
      } else if (field === 'max') {
        // 最后一个梯度的最大值可以为空（表示无上限）
        if (tierIndex === this.tierList.length - 1) {
          return '';
        }
        
        if (tier.maxUsage === null || tier.maxUsage === undefined) {
          return '最大用量必填';
        }
        
        if (tier.minUsage !== null && tier.minUsage !== undefined) {
          if (tier.maxUsage <= tier.minUsage) {
            return '必须大于最小用量';
          }
        }
      }
      
      return '';
    },
    /** 验证所有梯度数据 */
    validateTiers() {
      if (this.tierList.length === 0) {
        return true;
      }
      
      for (let i = 0; i < this.tierList.length; i++) {
        const tier = this.tierList[i];
        
        // 检查最小用量
        if (tier.minUsage === null || tier.minUsage === undefined) {
          this.$modal.msgError(`第${i + 1}梯：最小用量不能为空`);
          return false;
        }
        
        if (tier.minUsage < 0) {
          this.$modal.msgError(`第${i + 1}梯：最小用量不能为负数`);
          return false;
        }
        
        // 检查最大用量（最后一个梯度可以为空）
        if (i < this.tierList.length - 1) {
          if (tier.maxUsage === null || tier.maxUsage === undefined) {
            this.$modal.msgError(`第${i + 1}梯：最大用量不能为空`);
            return false;
          }
          
          if (tier.maxUsage <= tier.minUsage) {
            this.$modal.msgError(`第${i + 1}梯：最大用量必须大于最小用量`);
            return false;
          }
        }
        
        // 检查费率（仅梯度模式）
        if (this.form.usePeakValley === 0) {
          if (tier.rate === null || tier.rate === undefined) {
            this.$modal.msgError(`第${i + 1}梯：费率不能为空`);
            return false;
          }
          
          if (tier.rate < 0) {
            this.$modal.msgError(`第${i + 1}梯：费率不能为负数`);
            return false;
          }
        }
      }
      
      return true;
    },
    /** 梯度最小值变化时的联动处理 */
    onTierMinUsageChange(tierIndex) {
      const currentTier = this.tierList[tierIndex];
      if (currentTier.minUsage === null || currentTier.minUsage === undefined) {
        return;
      }
      
      // 如果当前梯度没有设置最大值，自动设置为当前最小值 + 最小单位
      if (currentTier.maxUsage === null || currentTier.maxUsage === undefined) {
        currentTier.maxUsage = parseFloat((currentTier.minUsage + 0.01).toFixed(2));
      }
      
      // 自动为下一个梯度设置最小值（当前最大值 + 最小单位）
      if (tierIndex < this.tierList.length - 1) {
        const nextTier = this.tierList[tierIndex + 1];
        // 只有在下一个梯度的最小值为空时才自动填充
        if (nextTier.minUsage === null || nextTier.minUsage === undefined) {
          nextTier.minUsage = parseFloat((currentTier.maxUsage + 0.01).toFixed(2));
        }
      }
    },
    /** 梯度最大值变化时的联动处理 */
    onTierMaxUsageChange(tierIndex) {
      const currentTier = this.tierList[tierIndex];
      if (currentTier.maxUsage === null || currentTier.maxUsage === undefined) {
        return;
      }
      
      // 自动为下一个梯度设置最小值（当前最大值 + 最小单位）
      if (tierIndex < this.tierList.length - 1) {
        const nextTier = this.tierList[tierIndex + 1];
        // 更新下一个梯度的最小值为当前最大值 + 最小单位
        nextTier.minUsage = parseFloat((currentTier.maxUsage + 0.01).toFixed(2));
      }
    }
  }
};

</script>

<style scoped>
.tier-level-badge {
  display: inline-block;
  background-color: #f56c6c;
  color: white;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: bold;
}

.tier-actions,
.period-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  color: #909399;
}

.empty-state i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.5;
}

.empty-state p {
  font-size: 14px;
  margin: 0;
}

.mb10 {
  margin-bottom: 10px;
}

.mb15 {
  margin-bottom: 15px;
}

.ml10 {
  margin-left: 10px;
}

/* 表格优化 */
.el-table {
  font-size: 13px;
}

.el-table /deep/ .el-input-number {
  width: 100%;
}

.el-table /deep/ .el-select {
  width: 100%;
}

.el-table /deep/ .el-time-picker {
  width: 100%;
}

/* 对话框优化 */
.el-dialog /deep/ .el-dialog__body {
  padding: 20px;
  max-height: 600px;
  overflow-y: auto;
}

/* Alert 优化 */
.el-alert {
  border-radius: 4px;
}

/* 提示文本 */
.tip-text {
  display: block;
  color: #e6a23c;
  font-size: 12px;
  margin-top: 4px;
}

/* 费率信息样式 */
.rate-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.rate-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: bold;
  text-align: center;
}

.rate-badge.peak {
  background-color: #f56c6c;
  color: white;
}

.rate-badge.tier {
  background-color: #409eff;
  color: white;
}

.rate-badge.fixed {
  background-color: #67c23a;
  color: white;
}

/* 向导式样式 */
.wizard-steps {
  margin-bottom: 30px;
}

.wizard-content {
  min-height: 400px;
}

.step-content {
  animation: fadeIn 0.3s ease-in;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 模式选择卡片 */
.mode-selection {
  text-align: center;
}

.mode-selection h3 {
  margin-bottom: 30px;
  font-size: 18px;
  color: #303133;
}

.mode-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 20px;
  margin-bottom: 20px;
}

.mode-card {
  padding: 20px;
  border: 2px solid #ebeef5;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  text-align: center;
  background-color: #fff;
}

.mode-card:hover {
  border-color: #409eff;
  box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.1);
  transform: translateY(-2px);
}

.mode-card.active {
  border-color: #409eff;
  background-color: #f0f9ff;
  box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.2);
}

.mode-icon {
  font-size: 32px;
  margin-bottom: 10px;
}

.mode-name {
  font-weight: bold;
  font-size: 14px;
  color: #303133;
  margin-bottom: 8px;
}

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

/* 预览卡片 */
.preview-section {
  padding: 20px;
}

.preview-card {
  margin-bottom: 20px;
  padding: 15px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background-color: #fafafa;
}

.card-title {
  font-weight: bold;
  font-size: 14px;
  color: #303133;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 2px solid #409eff;
}

.card-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.preview-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  font-size: 13px;
}

.preview-item .period-badge,
.preview-item .tier-badge {
  min-width: 60px;
  text-align: center;
}

.preview-item .rate-value {
  margin-left: auto;
  color: #409eff;
  font-weight: bold;
}

/* 配置页面样式 */
.config-section {
  padding: 15px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background-color: #fafafa;
}

.section-title {
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 2px solid #409eff;
}

.section-title i {
  margin-right: 8px;
  color: #409eff;
  font-size: 16px;
}

/* 模式提示 */
.mode-tips {
  margin-bottom: 20px;
  padding: 12px 16px;
  background-color: #f0f9ff;
  border-left: 4px solid #409eff;
  border-radius: 4px;
}

.tip-badge {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 13px;
  font-weight: 500;
}

.tip-badge.fixed-mode {
  background-color: #f0f9ff;
  color: #0a5cff;
  border: 1px solid #b3d8ff;
}

.tip-badge.peak-mode {
  background-color: #fef0f0;
  color: #f56c6c;
  border: 1px solid #fde2e2;
}

.tip-badge.tier-mode {
  background-color: #f0f9ff;
  color: #409eff;
  border: 1px solid #b3d8ff;
}

.tip-badge.combo-mode {
  background-color: #f4f4f5;
  color: #606266;
  border: 1px solid #dcdfe6;
}

/* 费率可视化样式 */
.rate-visualization {
  margin: 20px 0;
  padding: 20px;
  background-color: #fafafa;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

.visualization-section {
  margin-bottom: 20px;
}

.visualization-section:last-child {
  margin-bottom: 0;
}

.visualization-title {
  font-size: 14px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 2px solid #409eff;
}

.bar-chart {
  padding: 20px 10px;
  background-color: #ffffff;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

.chart-container {
  display: flex;
  align-items: flex-end;
  justify-content: space-around;
  height: 250px;
  gap: 15px;
}

.bar-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
  max-width: 80px;
}

.bar-wrapper {
  width: 100%;
  height: 200px;
  background-color: #f5f7fa;
  border-radius: 4px 4px 0 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 5px 0;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
}

.bar {
  width: 100%;
  max-width: 60px;
  min-height: 5%;
  border-radius: 4px 4px 0 0;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.bar:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transform: scaleY(1.05);
}

.bar-label {
  margin-top: 10px;
  text-align: center;
  font-size: 12px;
  width: 100%;
}

.bar-label .time {
  color: #606266;
  font-size: 11px;
  margin-bottom: 4px;
}

.bar-label .tier-info {
  color: #303133;
  font-weight: bold;
  margin-bottom: 2px;
}

.bar-label .usage {
  color: #909399;
  font-size: 11px;
  margin-bottom: 4px;
}

.bar-label .rate {
  color: #409eff;
  font-weight: bold;
  font-size: 13px;
}

.tier-bar {
  background: linear-gradient(180deg, #409eff 0%, #66b1ff 100%);
}

/* 梯度输入框验证样式 */
.tier-input-wrapper {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.tier-error {
  color: #f56c6c;
  font-size: 11px;
  line-height: 1;
}

/* 费率信息详情样式 */
.rate-info-detail {
  padding: 8px 0;
}

.rate-item {
  margin-bottom: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-start;
}

.rate-label {
  font-weight: 600;
  color: #303133;
  min-width: 80px;
  display: inline-block;
}

.rate-value {
  color: #409eff;
  font-weight: 600;
  font-size: 13px;
}

/* 时段费率样式 */
.period-rates {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1;
}

.period-badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 3px;
  color: white;
  font-size: 12px;
  font-weight: 500;
}

/* 梯度费率样式 */
.tier-rates {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
}

.tier-badge {
  display: inline-block;
  padding: 4px 8px;
  background-color: #f0f9ff;
  border-left: 3px solid #409eff;
  color: #303133;
  font-size: 12px;
  border-radius: 2px;
}

/* 梯度分组样式 */
.tier-group {
  margin-bottom: 12px;
  padding: 8px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.tier-header {
  font-weight: 600;
  color: #303133;
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px solid #dcdfe6;
}

/* 组合模式样式 */
.combo-rates {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}

.combo-tier-row {
  padding: 8px;
  background-color: #f9fafb;
  border-radius: 3px;
  border-left: 3px solid #8c8c8c;
}

.tier-header {
  font-weight: 600;
  color: #262626;
  font-size: 13px;
  margin-bottom: 6px;
}

.tier-rates-container {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.rate-badge {
  display: inline-block;
  padding: 4px 10px;
  background-color: #5b8cde;
  color: white;
  border-radius: 2px;
  font-size: 12px;
  font-weight: 500;
  transition: all 0.2s ease;
}

.rate-badge:hover {
  background-color: #4a7bc4;
  box-shadow: 0 2px 4px rgba(91, 140, 222, 0.2);
}

.combo-tier {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  padding: 4px 0;
  border-bottom: 1px solid #ebeef5;
}

.combo-tier:last-child {
  border-bottom: none;
}

.tier-range {
  display: inline-block;
  min-width: 120px;
  color: #606266;
  font-size: 12px;
  font-weight: 500;
}

.combo-period {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 3px;
  color: white;
  font-size: 11px;
  font-weight: 500;
}

/* 配置警告样式 */
.config-warning {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background-color: #fef0f0;
  border: 1px solid #fde2e2;
  border-radius: 3px;
  color: #f56c6c;
  font-size: 12px;
}

.config-warning i {
  font-size: 14px;
}

.expiry-date {
  color: #606266;
}

/* 浮动条形图样式 */
.rate-visualization-floating {
  margin-top: 30px;
  padding: 20px;
  background-color: #fff;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  animation: slideDown 0.3s ease-in;
}

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

.visualization-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: 2px solid #d9d9d9;
}

.visualization-title {
  font-size: 16px;
  font-weight: bold;
  color: #262626;
}

.visualization-section {
  margin-bottom: 20px;
}

.visualization-section:last-child {
  margin-bottom: 0;
}

.section-subtitle {
  font-size: 14px;
  font-weight: bold;
  color: #595959;
  margin-bottom: 15px;
  padding-left: 10px;
  border-left: 3px solid #8c8c8c;
}

/* 条形图容器 */
.bar-chart {
  width: 100%;
  height: 280px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 20px;
  background-color: #f5f5f5;
  border-radius: 2px;
  border: 1px solid #e8e8e8;
}

.chart-container {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 30px;
  width: 100%;
  height: 100%;
}

.bar-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  flex: 1;
  max-width: 80px;
}

.bar-wrapper {
  width: 100%;
  height: 150px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background-color: #ffffff;
  border-radius: 2px 2px 0 0;
  border: 1px solid #e8e8e8;
  border-bottom: none;
  flex-shrink: 0;
}

.bar {
  width: 60%;
  background: #5b8cde;
  border-radius: 2px 2px 0 0;
  transition: all 0.3s ease;
  min-height: 5%;
  max-height: 100%;
  overflow: hidden;
}

.bar:hover {
  opacity: 0.85;
  box-shadow: 0 2px 6px rgba(91, 140, 222, 0.25);
}

.bar.tier-bar {
  background: #7b9e89;
}

.bar-label {
  width: 100%;
  text-align: center;
  font-size: 12px;
}

.bar-label .time,
.bar-label .tier-info,
.bar-label .usage {
  color: #606266;
  margin-bottom: 4px;
}

.bar-label .rate {
  color: #409eff;
  font-weight: bold;
  font-size: 13px;
}

/* 固定费率显示 */
.fixed-rate-display {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 40px 20px;
  background-color: #fafafa;
  border-radius: 4px;
}

.rate-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  padding: 30px 50px;
  background-color: #fff;
  border: 2px solid #409eff;
  border-radius: 8px;
}

.rate-box .rate-label {
  font-size: 14px;
  color: #606266;
}

.rate-box .rate-value {
  font-size: 28px;
  font-weight: bold;
  color: #409eff;
}
</style>
