<template>
  <div class="business-report-page">
    <!-- 筛选条件 -->
    <div class="search-box-container">
      <el-card class="report-card" shadow="never">
        <el-form @submit.native.prevent :inline="true" class="search-form">
          <el-form-item label="时间范围">
            <el-date-picker 
              v-model="query.startTime" 
              type="datetime" 
              value-format="yyyy-MM-dd HH:mm:ss" 
              format="yyyy-MM-dd HH:mm:ss" 
              placeholder="开始时间"
              style="width: 200px;"
            />
            <span style="margin: 0 8px; color: #DCDFE6;">-</span>
            <el-date-picker 
              v-model="query.endTime" 
              type="datetime" 
              value-format="yyyy-MM-dd HH:mm:ss" 
              format="yyyy-MM-dd HH:mm:ss" 
              placeholder="结束时间"
              style="width: 200px;"
            />
          </el-form-item>
          <el-form-item label="门店">
            <el-select
              v-model="query.storeIds"
              multiple
              collapse-tags
              placeholder="全部门店"
              filterable
              clearable
              style="width: 260px;">
              <el-option
                v-for="store in storeOptions"
                :key="store.id"
                :label="store.dm"
                :value="store.id">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" @click="search()">查 询</el-button>
            <el-button icon="el-icon-refresh-right" @click="reset()">重 置</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>

    <!-- 第一个报表：业务统计仪表盘 -->
    <el-card class="report-card" shadow="never" v-loading="loading1">
      <div slot="header" class="card-header">
        <i class="el-icon-data-analysis"></i>
        <span>业务统计</span>
      </div>
      <div class="gauge-dashboard" v-if="businessData">
        <el-row :gutter="24">
          <el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" v-for="(item, index) in gaugeItems" :key="index">
            <div class="gauge-item-wrapper">
              <div class="gauge-item">
                <div class="gauge-chart-container">
                  <div :id="`gaugeChart${index + 1}`" class="gauge-chart"></div>
                  <div class="gauge-value-overlay">
                    <div class="gauge-value-large">{{ item.displayValue }}</div>
                    <div class="gauge-label-text">{{ item.title }}</div>
                  </div>
                </div>
              </div>
            </div>
          </el-col>
        </el-row>
      </div>
    </el-card>

    <!-- 第二个报表：客户类型统计 -->
    <el-card class="report-card" shadow="never" v-loading="loading2">
      <div slot="header" class="card-header">
        <i class="el-icon-user"></i>
        <span>客户类型统计</span>
      </div>
      <div class="customer-stats-container" v-if="customerData">
        <el-row :gutter="24">
          <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4">
            <div class="stat-card stat-card-purple">
              <div class="stat-icon">
                <i class="el-icon-star-on"></i>
              </div>
              <div class="stat-content">
                <div class="stat-label">拓客总人数</div>
                <div class="stat-value">{{ customerData.TotalInviteCount || 0 }}</div>
              </div>
            </div>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4" style="margin-bottom: 24px;">
            <div class="stat-card stat-card-blue">
              <div class="stat-icon">
                <i class="el-icon-s-custom"></i>
              </div>
              <div class="stat-content">
                <div class="stat-label">新客数量</div>
                <div class="stat-value">{{ customerData.NewCustomerCount || 0 }}</div>
              </div>
            </div>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4" style="margin-bottom: 24px;">
            <div class="stat-card stat-card-cyan">
              <div class="stat-icon">
                <i class="el-icon-user-solid"></i>
              </div>
              <div class="stat-content">
                <div class="stat-label">散客数</div>
                <div class="stat-value">{{ customerData.CasualCustomerCount || 0 }}</div>
              </div>
            </div>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4" style="margin-bottom: 24px;">
            <div class="stat-card stat-card-green">
              <div class="stat-icon">
                <i class="el-icon-user"></i>
              </div>
              <div class="stat-content">
                <div class="stat-label">会员数</div>
                <div class="stat-value">{{ customerData.MemberCount || 0 }}</div>
              </div>
            </div>
          </el-col>
          <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4" style="margin-bottom: 24px;">
            <div class="conversion-rate-card">
              <div class="donut-wrapper">
                <div class="donut-chart" :style="getDonutStyle(customerData.MemberCount / customerData.TotalInviteCount)">
                  <div class="donut-center">
                    <div class="conversion-title">会员转化率</div>
                    <div class="percentage">{{ formatPercent((customerData.MemberCount / customerData.TotalInviteCount) * 100) }}%</div>
                  </div>
                </div>
              </div>
            </div>
          </el-col>
        </el-row>
      </div>
    </el-card>

    <!-- 第三个和第四个报表：并排显示 -->
    <el-row :gutter="24">
      <!-- 第三个报表：门店业绩对比（柱状图） -->
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <el-card class="report-card" shadow="never" v-loading="loading3">
          <div slot="header" class="card-header">
            <i class="el-icon-trophy"></i>
            <span>门店业绩对比</span>
          </div>
          <div 
            id="storePerformanceChart" 
            class="chart-container-half" 
            v-if="performanceData && performanceData.length > 0">
          </div>
        </el-card>
      </el-col>

      <!-- 第四个报表：品项统计对比（蝴蝶图） -->
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <el-card class="report-card" shadow="never" v-loading="loading4">
          <div slot="header" class="card-header">
            <i class="el-icon-goods"></i>
            <span>品项统计对比</span>
          </div>
          <div class="butterfly-chart-container" v-if="itemStatisticsData && itemStatisticsData.length > 0">
            <!-- 图例 -->
            <div class="chart-legend">
              <div class="legend-item">
                <span class="legend-color legend-purple"></span>
                <span class="legend-text">开单金额</span>
              </div>
              <div class="legend-item">
                <span class="legend-color legend-orange"></span>
                <span class="legend-text">消耗金额</span>
              </div>
            </div>
            
            <!-- 图表内容 -->
            <div class="butterfly-chart-content">
              <div class="chart-left">
                <div 
                  v-for="(item, index) in sortedItemData" 
                  :key="index" 
                  class="chart-row">
                  <div 
                    class="bar-left" 
                    :style="{width: getButterflyBarWidth(item.BillingAmount, maxValue) + '%'}">
                    <span class="bar-value">{{ item.BillingAmount || 0 }}</span>
                  </div>
                </div>
              </div>
              
              <div class="chart-center">
                <div 
                  v-for="(item, index) in sortedItemData" 
                  :key="index" 
                  class="category-name">
                  {{ item.ItemName || item.ItemId }}
                </div>
              </div>
              
              <div class="chart-right">
                <div 
                  v-for="(item, index) in sortedItemData" 
                  :key="index" 
                  class="chart-row">
                  <div 
                    class="bar-right" 
                    :style="{width: getButterflyBarWidth(item.ConsumeAmount, maxValue) + '%'}">
                    <span class="bar-value">{{ item.ConsumeAmount || 0 }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>
    
    <!-- 第六个和第九个报表：并排显示 -->
    <el-row :gutter="24">
      <!-- 第六个报表：客户到店次数分布 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <el-card class="report-card" shadow="never" v-loading="loading6">
          <div slot="header" class="card-header">
            <i class="el-icon-s-marketing"></i>
            <span>客户到店次数分布</span>
          </div>
          <div 
            id="customerVisitFrequencyChart" 
            class="chart-container-half" 
            v-if="customerVisitFrequencyData && customerVisitFrequencyData.length > 0">
          </div>
          <div v-else style="text-align: center; padding: 40px; color: #909399;">
            暂无数据
          </div>
        </el-card>
      </el-col>

      <!-- 第九个报表：拓客转化漏斗图 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <el-card class="report-card" shadow="never" v-loading="loading9">
          <div slot="header" class="card-header">
            <i class="el-icon-data-line"></i>
            <span>拓客转化漏斗图</span>
          </div>
          <div v-if="tkStatisticsData" class="funnel-container">
            <!-- 漏斗图 -->
            <div id="tkFunnelChart" class="funnel-chart-container-half"></div>
            
            <!-- 转化率指标卡片 -->
            <div class="conversion-rate-cards">
              <div class="conversion-card">
                <div class="conversion-label">拓客沟通率</div>
                <div class="conversion-value">{{ formatPercent(getTkInviteRate()) }}%</div>
                <!-- <div class="conversion-detail">{{ tkStatisticsData.YaoyCount || 0 }} / {{ tkStatisticsData.TkCount || 0 }}</div> -->
              </div>
              <div class="conversion-card">
                <div class="conversion-label">沟通到店率</div>
                <div class="conversion-value">{{ formatPercent(getInviteStoreRate()) }}%</div>
                <!-- <div class="conversion-detail">{{ tkStatisticsData.DdCount || 0 }} / {{ tkStatisticsData.YaoyCount || 0 }}</div> -->
              </div>
              <div class="conversion-card">
                <div class="conversion-label">预约转化率</div>
                <div class="conversion-value">{{ formatPercent(getStoreConversionRate()) }}%</div>
                <!-- <div class="conversion-detail">{{ tkStatisticsData.XfCount || 0 }} / {{ tkStatisticsData.YyCount || 0 }}</div> -->
              </div>
            </div>
          </div>
          <div v-else style="text-align: center; padding: 40px; color: #909399;">
            暂无数据
          </div>
        </el-card>
      </el-col>
    </el-row>
    <!-- 第五个报表：门店项目统计 -->
    <el-card class="report-card" shadow="never" v-loading="loading5">
      <div slot="header" class="card-header">
        <div style="display: flex; align-items: center; justify-content: space-between; width: 100%;">
          <div style="display: flex; align-items: center;">
            <i class="el-icon-s-data"></i>
            <span>门店项目统计</span>
          </div>
          <el-button
            type="text"
            icon="el-icon-setting"
            style="padding: 0; margin-left: 20px;"
            @click="showFieldConfigDialog = true">
            字段配置
          </el-button>
        </div>
      </div>
      <div v-if="storeItemStatisticsData && storeItemStatisticsData.length > 0">
        <el-table
          :data="storeItemStatisticsData"
          border
          stripe
          style="width: 100%"
          :header-cell-style="{ background: '#f5f7fa', color: '#303133', fontWeight: '600' }"
          @sort-change="handleSortChange">
          <el-table-column
            v-if="isFieldVisible('StoreName')"
            prop="StoreName"
            label="门店名称"
            min-width="150"
            align="center">
          </el-table-column>
          <el-table-column
            v-if="isFieldVisible('BillingAmount')"
            prop="BillingAmount"
            label="开单金额"
            min-width="120"
            align="center"
            sortable="custom">
            <template slot-scope="scope">
              <span>¥{{ formatMoney(scope.row.BillingAmount) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            v-if="isFieldVisible('ConsumePersonCount')"
            prop="ConsumePersonCount"
            label="消耗人次"
            min-width="120"
            align="center"
            sortable="custom">
          </el-table-column>
          <el-table-column
            v-if="isFieldVisible('ConsumeProjectCount')"
            prop="ConsumeProjectCount"
            label="消耗项目数"
            min-width="120"
            align="center"
            sortable="custom">
          </el-table-column>
          <el-table-column
            v-if="isFieldVisible('AvgProjectPerConsume')"
            prop="AvgProjectPerConsume"
            label="客单项目数"
            min-width="120"
            align="center"
            sortable="custom">
            <template slot-scope="scope">
              <span>{{ formatMoney(scope.row.AvgProjectPerConsume) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            v-if="isFieldVisible('ConsumeAmount')"
            prop="ConsumeAmount"
            label="消耗金额"
            min-width="120"
            align="center"
            sortable="custom">
            <template slot-scope="scope">
              <span>¥{{ formatMoney(scope.row.ConsumeAmount) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            v-if="isFieldVisible('AvgAmountPerConsume')"
            prop="AvgAmountPerConsume"
            label="消耗客单价"
            min-width="120"
            align="center"
            sortable="custom">
            <template slot-scope="scope">
              <span>¥{{ formatMoney(scope.row.AvgAmountPerConsume) }}</span>
            </template>
          </el-table-column>
          <el-table-column
            v-if="isFieldVisible('ConsumeRate')"
            prop="ConsumeRate"
            label="消耗率"
            min-width="120"
            align="center"
            sortable="custom">
            <template slot-scope="scope">
              <span>{{ formatPercent((scope.row.ConsumeRate || 0) ) }}%</span>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-else style="text-align: center; padding: 40px; color: #909399;">
        暂无数据
      </div>

      <!-- 字段配置对话框 -->
      <el-dialog
        title="字段配置"
        :visible.sync="showFieldConfigDialog"
        width="500px"
        :close-on-click-modal="false">
        <div class="field-config-content">
          <div class="field-config-actions" style="margin-bottom: 15px;">
            <el-button type="text" size="small" @click="selectAllFields">全选</el-button>
            <el-button type="text" size="small" @click="unselectAllFields">全不选</el-button>
          </div>
          <el-checkbox-group v-model="selectedFields">
            <div
              v-for="field in availableFields"
              :key="field.prop"
              class="field-config-item">
              <el-checkbox :label="field.prop">{{ field.label }}</el-checkbox>
            </div>
          </el-checkbox-group>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="showFieldConfigDialog = false">取消</el-button>
          <el-button type="primary" @click="confirmFieldConfig">确定</el-button>
        </span>
      </el-dialog>
    </el-card>


    <!-- 第七个报表：健康师开单排名 -->
    <el-card shadow="never" class="report-card" v-loading="loading7">
      <div slot="header" class="card-header">
        <i class="el-icon-trophy"></i>
        <span>健康师开单排名</span>
      </div>
      <div v-if="healthCoachBillingRankingData && healthCoachBillingRankingData.length > 0">
        <el-table
          :data="healthCoachBillingRankingData"
          border
          stripe
          style="width: 100%"
          :header-cell-style="{ background: '#f5f7fa', color: '#303133', fontWeight: '600' }">
          <el-table-column type="index" label="排名" width="80" align="center" :index="getRankIndex"></el-table-column>
          <el-table-column prop="HealthCoachName" label="健康师姓名" min-width="150" align="center"></el-table-column>
          <el-table-column prop="BillingPerformance" label="开单业绩" min-width="120" align="center">
            <template slot-scope="scope">
              <span>¥{{ formatMoney(scope.row.BillingPerformance) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="ConsumePerformance" label="消耗业绩" min-width="120" align="center">
            <template slot-scope="scope">
              <span>¥{{ formatMoney(scope.row.ConsumePerformance) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="RefundPerformance" label="退款业绩" min-width="120" align="center">
            <template slot-scope="scope">
              <span>¥{{ formatMoney(scope.row.RefundPerformance) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="BillingProjectCount" label="开单项目数" min-width="120" align="center"></el-table-column>
          <el-table-column prop="ConsumeProjectCount" label="消耗项目数" min-width="120" align="center"></el-table-column>
          <el-table-column prop="RefundProjectCount" label="退款项目数" min-width="120" align="center"></el-table-column>
        </el-table>
      </div>
      <div v-else style="text-align: center; padding: 40px; color: #909399;">
        暂无数据
      </div>
    </el-card>

    <!-- 第八个报表：门店剩余权益统计 -->
    <el-card class="report-card" shadow="never" v-loading="loading8">
      <div slot="header" class="card-header">
        <i class="el-icon-wallet"></i>
        <span>门店剩余权益统计</span>
      </div>
      <div v-if="storeRemainingRightsData && storeRemainingRightsData.length > 0">
        <el-table
          :data="storeRemainingRightsData"
          border
          stripe
          style="width: 100%"
          :header-cell-style="{ background: '#f5f7fa', color: '#303133', fontWeight: '600' }">
          <el-table-column prop="StoreName" label="门店名称" min-width="200" align="center"></el-table-column>
          <el-table-column prop="RemainingRightsAmount" label="剩余权益累计金额" min-width="180" align="center">
            <template slot-scope="scope">
              <span>¥{{ formatMoney(scope.row.RemainingRightsAmount) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="RemainingRightsPersonCount" label="剩余权益累计人数" min-width="180" align="center"></el-table-column>
        </el-table>
      </div>
      <div v-else style="text-align: center; padding: 40px; color: #909399;">
        暂无数据
      </div>
    </el-card>
  </div>
</template>

<script>
import request from '@/utils/request'
import * as echarts from 'echarts'

export default {
  name: 'BusinessReport',
  data() {
    return {
      query: {
        startTime: undefined,
        endTime: undefined,
        storeIds: []
      },
      storeOptions: [],
      businessData: null,
      customerData: null,
      performanceData: [],
      itemStatisticsData: [],
      storeItemStatisticsData: [],
      customerVisitFrequencyData: [],
      healthCoachBillingRankingData: [],
      storeRemainingRightsData: [],
      tkStatisticsData: null,
      loading1: false,
      loading2: false,
      loading3: false,
      loading4: false,
      loading5: false,
      loading6: false,
      loading7: false,
      loading8: false,
      loading9: false,
      gaugeItems: [],
      // 门店项目统计字段配置
      showFieldConfigDialog: false,
      availableFields: [
        { prop: 'StoreName', label: '门店名称' },
        { prop: 'BillingAmount', label: '开单金额' },
        { prop: 'ConsumePersonCount', label: '消耗人次' },
        { prop: 'ConsumeProjectCount', label: '消耗项目数' },
        { prop: 'AvgProjectPerConsume', label: '客单项目数' },
        { prop: 'ConsumeAmount', label: '消耗金额' },
        { prop: 'AvgAmountPerConsume', label: '消耗客单价' },
        { prop: 'ConsumeRate', label: '消耗率' }
      ],
      selectedFields: ['StoreName', 'BillingAmount', 'ConsumePersonCount', 'ConsumeProjectCount', 'AvgProjectPerConsume', 'ConsumeAmount', 'AvgAmountPerConsume', 'ConsumeRate'],
      sortParams: {
        prop: null,
        order: null
      },
      originalStoreItemStatisticsData: [] // 保存原始数据，用于取消排序时恢复
    }
  },
  computed: {
    sortedItemData() {
      if (!this.itemStatisticsData || this.itemStatisticsData.length === 0) return []
      return [...this.itemStatisticsData]
        .sort((a, b) => (b.BillingAmount || 0) - (a.BillingAmount || 0))
        .slice(0, 10)
    },
    maxValue() {
      if (!this.itemStatisticsData || this.itemStatisticsData.length === 0) return 1
      const maxBilling = Math.max(...this.itemStatisticsData.map(item => item.BillingAmount || 0))
      const maxConsume = Math.max(...this.itemStatisticsData.map(item => item.ConsumeAmount || 0))
      return Math.max(maxBilling, maxConsume)
    }
  },
  created() {
    this.setDefaultTimeRange()
    this.initStoreOptions()
    this.$nextTick(() => {
      this.search()
    })
  },
  methods: {
    // 设置默认时间范围（本月1号到现在）
    setDefaultTimeRange() {
      const now = new Date()
      const firstDayOfMonth = new Date(now.getFullYear(), now.getMonth(), 1)
      
      this.query.startTime = this.formatDateTime(firstDayOfMonth.getTime())
      this.query.endTime = this.formatDateTime(now.getTime())
    },

    // 初始化门店选项
    initStoreOptions() {
      return request({
        url: '/api/Extend/LqMdxx',
        method: 'GET',
        data: {
          currentPage: 1,
          pageSize: 1000
        }
      }).then(res => {
        this.storeOptions = res.data.list || []
        return this.storeOptions
      }).catch(err => {
        console.error('获取门店列表失败:', err)
        this.storeOptions = []
        return []
      })
    },

    // 查询所有数据
    async search() {
      await this.loadHealthCoachBillingRanking()
      await this.loadBusinessStatistics()
      await this.loadCustomerTypeStatistics()
      await this.loadStorePerformanceComparison()
      await this.loadStoreItemStatistics()
      await this.loadCustomerVisitFrequency()
      await this.loadTkStatistics()
      //await this.loadStoreRemainingRights()
    },

    // 获取业务统计数据
    loadBusinessStatistics() {
      this.loading1 = true
      const params = {
        startTime: this.query.startTime,
        endTime: this.query.endTime,
        storeIds: this.query.storeIds || []
      }
      
      request({
        url: '/api/Extend/lqreport/get-business-statistics',
        method: 'POST',
        data: params
      }).then(res => {
        this.businessData = res.data || null
        if (this.businessData) {
          this.initGaugeItems()
          this.$nextTick(() => {
            this.initGaugeCharts()
          })
        }
        this.loading1 = false
      }).catch(err => {
        console.error('获取业务统计数据失败:', err)
        this.$message.error('获取业务统计数据失败')
        this.loading1 = false
      })
    },

    // 初始化仪表盘数据
    initGaugeItems() {
      const billingValue = this.businessData.TotalBillingAmount - this.businessData.TotalRefundAmount || 0
      const countValue = this.businessData.BillingCount || 0
      const consumeValue = this.businessData.TotalConsumeAmount || 0
      const targetValue = this.businessData.TargetConsumeAmount || 0
      const completionRate = this.businessData.BillingCompletionRate || 0

      this.gaugeItems = [
        {
          title: '现金业绩',
          icon: 'el-icon-wallet',
          displayValue: `¥${this.formatMoney(billingValue)}`,
          value: billingValue,
          max: billingValue > 0 ? Math.floor(billingValue * 0.87) : 100000,
          isAmount: true
        },
        {
          title: '人头',
          icon: 'el-icon-s-custom',
          displayValue: countValue || 0,
          value: countValue,
          max: countValue > 0 ? Math.floor(countValue * 0.84) : 100,
          isAmount: false
        },
        {
          title: '消耗业绩',
          icon: 'el-icon-coin',
          displayValue: `¥${this.formatMoney(consumeValue)}`,
          value: consumeValue,
          max: consumeValue > 0 ? Math.floor(consumeValue * 0.85) : 50000,
          isAmount: true
        },
        {
          title: '目标值',
          icon: 'el-icon-coin',
          displayValue: `¥${this.formatMoney(targetValue)}`,
          value: targetValue,
          max: targetValue > 0 ? Math.floor(targetValue * 0.85) : 50000,
          isAmount: true
        },
        {
          title: '完成率',
          icon: 'el-icon-coin',
          displayValue: `${this.formatMoney(completionRate)}%`,
          value: completionRate,
          max: completionRate > 0 ? Math.floor(completionRate * 0.85) : 50000,
          isAmount: true
        }
      ]
    },

    // 初始化仪表盘图表
    initGaugeCharts() {
      if (!this.businessData || this.gaugeItems.length === 0) return
      
      this.gaugeItems.forEach((item, index) => {
        this.initGaugeChart(`gaugeChart${index + 1}`, item, `range${index + 1}`)
      })
    },

    // 初始化单个仪表盘
    initGaugeChart(chartId, item, rangeId) {
      const chartDom = document.getElementById(chartId)
      if (!chartDom) return
      
      const myChart = echarts.init(chartDom)
      
      const percentage = item.max > 0 ? (item.value / item.max) : 1
      const displayPercentage = percentage > 1 ? 1 : percentage
      
      const option = {
        series: [
          {
            name: item.title,
            type: 'gauge',
            startAngle: 180,
            endAngle: 0,
            radius: '88%',
            min: 0,
            max: item.max || 1,
            splitNumber: 0,
            center: ['50%', '60%'],
            axisLine: {
              lineStyle: {
                width: 22,
                color: [[displayPercentage, '#409EFF'], [1, '#f0f2f5']]
              }
            },
            pointer: {
              show: false
            },
            axisLabel: {
              show: false
            },
            splitLine: {
              show: false
            },
            axisTick: {
              show: false
            },
            title: {
              show: false
            },
            detail: {
              show: false
            }
          }
        ]
      }
      
      myChart.setOption(option)
      
      // 设置范围显示
      const rangeElement = document.getElementById(rangeId)
      if (rangeElement) {
        const displayMax = item.isAmount ? `¥${this.formatMoney(item.max)}` : item.max
        rangeElement.textContent = displayMax
      }
      
      window.addEventListener('resize', () => {
        myChart.resize()
      })
    },

    // 获取客户类型统计数据
    loadCustomerTypeStatistics() {
      this.loading2 = true
      const params = {
        startTime: this.query.startTime,
        endTime: this.query.endTime,
        storeIds: this.query.storeIds || []
      }
      
      request({
        url: '/api/Extend/lqreport/get-customer-type-statistics',
        method: 'POST',
        data: params
      }).then(res => {
        this.customerData = res.data || null
        this.loading2 = false
      }).catch(err => {
        console.error('获取客户类型统计数据失败:', err)
        this.$message.error('获取客户类型统计数据失败')
        this.loading2 = false
      })
    },

    // 获取门店业绩对比数据
    loadStorePerformanceComparison() {
      this.loading3 = true
      this.loading4 = true
      const params = {
        startTime: this.query.startTime,
        endTime: this.query.endTime,
        storeIds: this.query.storeIds || []
      }
      
      // 获取门店业绩对比数据
      request({
        url: '/api/Extend/lqreport/get-store-performance-comparison',
        method: 'POST',
        data: params
      }).then(res => {
        // 只取前10条数据
        this.performanceData = (res.data || []).slice(0, 10)
        this.$nextTick(() => {
          this.initStorePerformanceChart()
        })
        this.loading3 = false
      }).catch(err => {
        console.error('获取门店业绩对比数据失败:', err)
        this.$message.error('获取门店业绩对比数据失败')
        this.loading3 = false
      })
      
      // 获取品项统计数据
      request({
        url: '/api/Extend/lqreport/get-item-statistics',
        method: 'POST',
        data: params
      }).then(res => {
        this.itemStatisticsData = res.data || []
        this.loading4 = false
      }).catch(err => {
        console.error('获取品项统计数据失败:', err)
        this.$message.error('获取品项统计数据失败')
        this.loading4 = false
      })
    },

    // 获取门店项目统计数据
    loadStoreItemStatistics() {
      this.loading5 = true
      const params = {
        startTime: this.query.startTime,
        endTime: this.query.endTime,
        storeIds: this.query.storeIds || []
      }
      
      request({
        url: '/api/Extend/lqreport/get-store-item-statistics',
        method: 'POST',
        data: params
      }).then(res => {
        const data = res.data || []
        // 保存原始数据
        this.originalStoreItemStatisticsData = JSON.parse(JSON.stringify(data))
        this.storeItemStatisticsData = data
        // 如果有排序参数，重新应用排序
        if (this.sortParams.prop && this.sortParams.order) {
          this.sortTableData()
        }
        this.loading5 = false
      }).catch(err => {
        console.error('获取门店项目统计数据失败:', err)
        this.$message.error('获取门店项目统计数据失败')
        this.loading5 = false
      })
    },

    // 获取客户到店次数分布数据
    loadCustomerVisitFrequency() {
      this.loading6 = true
      const params = {
        startTime: this.query.startTime,
        endTime: this.query.endTime,
        storeIds: this.query.storeIds || []
      }
      
      request({
        url: '/api/Extend/lqreport/get-customer-visit-frequency',
        method: 'POST',
        data: params
      }).then(res => {
        this.customerVisitFrequencyData = res.data || []
        this.$nextTick(() => {
          this.initCustomerVisitFrequencyChart()
        })
        this.loading6 = false
      }).catch(err => {
        console.error('获取客户到店次数分布数据失败:', err)
        this.$message.error('获取客户到店次数分布数据失败')
        this.loading6 = false
      })
    },

    // 获取健康师开单排名数据
    loadHealthCoachBillingRanking() {
      this.loading7 = true
      const params = {
        startTime: this.query.startTime,
        endTime: this.query.endTime,
        storeIds: this.query.storeIds || []
      }
      
      request({
        url: '/api/Extend/lqreport/get-health-coach-billing-ranking',
        method: 'POST',
        data: params
      }).then(res => {
        // 按开单业绩降序排序
        const data = res.data || []
        this.healthCoachBillingRankingData = data.sort((a, b) => (b.BillingPerformance || 0) - (a.BillingPerformance || 0))
        this.loading7 = false
      }).catch(err => {
        console.error('获取健康师开单排名数据失败:', err)
        this.$message.error('获取健康师开单排名数据失败')
        this.loading7 = false
      })
    },

    // 获取门店剩余权益统计数据（按门店循环查询）
    loadStoreRemainingRights() {
      this.loading8 = true
      this.storeRemainingRightsData = []
      
      // 如果门店列表为空，先获取门店列表
      const getStoresToQuery = () => {
        if (this.query.storeIds && this.query.storeIds.length > 0) {
          // 如果选择了门店，只查询选中的门店
          return this.storeOptions.filter(store => this.query.storeIds.includes(store.id))
        } else {
          // 如果没有选择门店，查询所有门店
          return this.storeOptions || []
        }
      }
      
      // 获取要查询的门店列表
      let storesToQuery = getStoresToQuery()
      
      // 如果门店列表为空，先加载门店列表
      if (storesToQuery.length === 0 && (!this.storeOptions || this.storeOptions.length === 0)) {
        this.initStoreOptions().then(() => {
          storesToQuery = getStoresToQuery()
          if (storesToQuery.length === 0) {
            this.loading8 = false
            return
          }
          this.queryStoresRemainingRights(storesToQuery)
        }).catch(() => {
          this.loading8 = false
        })
        return
      }
      
      if (storesToQuery.length === 0) {
        this.loading8 = false
        return
      }
      
      this.queryStoresRemainingRights(storesToQuery)
    },

    // 查询门店剩余权益数据
    queryStoresRemainingRights(storesToQuery) {
      // 使用 Promise.all 并发查询所有门店
      const requests = storesToQuery.map(store => {
        const params = {
          startTime: this.query.startTime,
          endTime: this.query.endTime,
          storeIds: [store.id]
        }
        
        return request({
          url: '/api/Extend/lqreport/get-store-remaining-rights',
          method: 'POST',
          data: params
        }).then(res => {
          const data = res.data || []
          return data
        }).catch(err => {
          console.error(`获取门店 ${store.dm || store.id} 剩余权益统计数据失败:`, err)
          return []
        })
      })
      
      Promise.all(requests).then(results => {
        // 合并所有门店的查询结果
        const allData = []
        results.forEach(data => {
          if (data && data.length > 0) {
            allData.push(...data)
          }
        })
        this.storeRemainingRightsData = allData
        this.loading8 = false
      }).catch(err => {
        console.error('获取门店剩余权益统计数据失败:', err)
        this.$message.error('获取门店剩余权益统计数据失败')
        this.loading8 = false
      })
    },

    // 获取拓客统计数据
    loadTkStatistics() {
      this.loading9 = true
      const params = {
        startTime: this.query.startTime,
        endTime: this.query.endTime,
        storeIds: this.query.storeIds || []
      }
      
      return request({
        url: '/api/Extend/lqtkjlb/get-tk-statistics',
        method: 'POST',
        data: params
      }).then(res => {
        this.tkStatisticsData = res.data || null
        if (this.tkStatisticsData) {
          this.$nextTick(() => {
            this.initTkFunnelChart()
          })
        }
        this.loading9 = false
      }).catch(err => {
        console.error('获取拓客统计数据失败:', err)
        this.$message.error('获取拓客统计数据失败')
        this.loading9 = false
      })
    },

    // 初始化拓客转化漏斗图
    initTkFunnelChart() {
      if (!this.tkStatisticsData) return
      
      const chartDom = document.getElementById('tkFunnelChart')
      if (!chartDom) return
      
      const myChart = echarts.init(chartDom)
      
      const tkCount = this.tkStatisticsData.TkCount || 0
      const yaoyCount = this.tkStatisticsData.YaoyCount || 0
      const yyCount = this.tkStatisticsData.YyCount || 0
      const ddCount = this.tkStatisticsData.DdCount || 0
      const kdCount = this.tkStatisticsData.KdCount || 0
      const xfCount = this.tkStatisticsData.XfCount || 0
      
      // 计算百分比（以拓客人数为基准100%）
      const maxValue = tkCount || 1
      const getPercent = (value) => {
        return tkCount > 0 ? ((value / tkCount) * 100).toFixed(1) : '0.0'
      }
      
      const funnelData = [
        { value: tkCount, name: '拓客人数', percent: '100.0%' },
        { value: yaoyCount, name: '沟通人头', percent: getPercent(yaoyCount) + '%' },
        { value: yyCount, name: '预约人头', percent: getPercent(yyCount) + '%' },
        { value: ddCount, name: '到店人头', percent: getPercent(ddCount) + '%' },
        { value: kdCount, name: '开单人头', percent: getPercent(kdCount) + '%' },
        { value: xfCount, name: '消费人头', percent: getPercent(xfCount) + '%' }
      ]
      
      const option = {
        tooltip: {
          trigger: 'item',
          formatter: '{b} : {c}人 ({d}%)'
        },
        legend: {
          bottom: '5%',
          left: 'center',
          icon: 'circle',
          itemWidth: 10,
          itemHeight: 10
        },
        series: [
          {
            name: '拓客转化漏斗',
            type: 'funnel',
            left: '10%',
            top: '10%',
            bottom: '20%',
            width: '80%',
            min: 0,
            max: maxValue,
            minSize: '0%',
            maxSize: '100%',
            sort: 'descending',
            gap: 2,
            label: {
              show: true,
              position: 'inside',
              formatter: '{c}人',
              fontSize: 12,
              color: '#fff'
            },
            itemStyle: {
              borderColor: '#fff',
              borderWidth: 1
            },
            data: funnelData,
            color: ['#409EFF', '#64B5FF', '#8CC5FF', '#B3D8FF', '#D9ECFF', '#EBF5FF']
          }
        ]
      }
      
      myChart.setOption(option)
      
      window.addEventListener('resize', () => {
        myChart.resize()
      })
    },

    // 计算拓客沟通率
    getTkInviteRate() {
      if (!this.tkStatisticsData || !this.tkStatisticsData.TkCount || this.tkStatisticsData.TkCount === 0) return 0
      const rate = (this.tkStatisticsData.YaoyCount || 0) / this.tkStatisticsData.TkCount * 100
      return rate
    },

    // 计算沟通到店率
    getInviteStoreRate() {
      if (!this.tkStatisticsData || !this.tkStatisticsData.YaoyCount || this.tkStatisticsData.YaoyCount === 0) return 0
      const rate = (this.tkStatisticsData.DdCount || 0) / this.tkStatisticsData.YaoyCount * 100
      return rate
    },

    // 计算到店转化率
    getStoreConversionRate() {
      if (!this.tkStatisticsData || !this.tkStatisticsData.YyCount || this.tkStatisticsData.YyCount === 0) return 0
      const rate = (this.tkStatisticsData.XfCount || 0) / this.tkStatisticsData.YyCount * 100
      return rate
    },

    // 初始化门店业绩对比柱状图
    initStorePerformanceChart() {
      if (!this.performanceData || this.performanceData.length === 0) return
      
      const chartDom = document.getElementById('storePerformanceChart')
      if (!chartDom) return
      
      const myChart = echarts.init(chartDom)
      console.error(this.performanceData)
      const storeNames = this.performanceData.map(item => item.StoreName)
      const targetPerformance = this.performanceData.map(item => item.ActualPerformance || 0)
      const actualPerformance = this.performanceData.map(item => item.ActualConsumePerformance || 0)
      console.error(actualPerformance)
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter: function(params) {
            let result = params[0].name + '<br/>'
            params.forEach(item => {
              result += item.seriesName + ': ¥' + item.value + '<br/>'
            })
            return result
          }
        },
        legend: {
          data: ['现金业绩', '消耗业绩'],
          bottom: 10,
          textStyle: {
            fontSize: 14
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '15%',
          top: '5%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: storeNames,
          axisLabel: {
            rotate: 45,
            interval: 0,
            fontSize: 12
          }
        },
        yAxis: {
          type: 'value',
          axisLabel: {
            formatter: function(value) {
              return '¥' + value
            }
          }
        },
        series: [
          {
            name: '现金业绩',
            type: 'bar',
            data: targetPerformance,
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#409EFF' },
                { offset: 1, color: '#79bbff' }
              ])
            },
            barWidth: '25%',
            label: {
              show: false,
              position: 'inside',
              formatter: (params) => {
                // 将数字转换为纵向显示
                const value = params.value;
                return String(value).split('').join('\n');
              },
              fontSize: 10,
              color: '#efefef',
              fontWeight: 'bold'
            }
          },
          {
            name: '消耗业绩',
            type: 'bar',
            data: actualPerformance,
            itemStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: '#67C23A' },
                { offset: 1, color: '#95d475' }
              ])
            },
            barWidth: '25%',
            label: {
              show: false,
              position: 'inside',
              formatter: (params) => {
                // 将数字转换为纵向显示
                const value = params.value;
                return String(value).split('').join('\n');
              },
              fontSize: 10,
              color: '#efefef',
              fontWeight: 'bold'
            }
          }
        ]
      }
      
      myChart.setOption(option)
      
      window.addEventListener('resize', () => {
        myChart.resize()
      })
    },

    // 初始化客户到店次数分布柱状图
    initCustomerVisitFrequencyChart() {
      if (!this.customerVisitFrequencyData || this.customerVisitFrequencyData.length === 0) return
      
      const chartDom = document.getElementById('customerVisitFrequencyChart')
      if (!chartDom) return
      
      // 按 VisitCount 降序排序（从高到低）
      const sortedData = [...this.customerVisitFrequencyData].sort((a, b) => (b.VisitCount || 0) - (a.VisitCount || 0))
      
      const visitCounts = sortedData.map(item => `${item.VisitCount || 0}次`)
      const customerCounts = sortedData.map(item => item.CustomerCount || 0)
      
      const myChart = echarts.init(chartDom)
      
      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter: function(params) {
            const param = params[0]
            return `${param.name}<br/>人数: ${param.value}`
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '10%',
          top: '7%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: visitCounts,
          axisLabel: {
            fontSize: 12,
            color: '#606266'
          },
          axisLine: {
            lineStyle: {
              color: '#DCDFE6'
            }
          }
        },
        yAxis: {
          type: 'value',
          name: '人数',
          nameTextStyle: {
            color: '#606266',
            fontSize: 12
          },
          axisLabel: {
            fontSize: 12,
            color: '#606266'
          },
          axisLine: {
            lineStyle: {
              color: '#DCDFE6'
            }
          },
          splitLine: {
            lineStyle: {
              color: '#EBEEF5',
              type: 'dashed'
            }
          }
        },
        series: [
          {
            name: '人数',
            type: 'bar',
            data: customerCounts,
            itemStyle: {
              color: '#409EFF'
            },
            barWidth: '50%',
            label: {
              show: true,
              position: 'top',
              fontSize: 12,
              color: '#303133',
              fontWeight: '500'
            }
          }
        ]
      }
      
      myChart.setOption(option)
      
      window.addEventListener('resize', () => {
        myChart.resize()
      })
    },

    // 获取环形图样式
    getDonutStyle(rate) {
      // rate 是小数形式（如 0.75 表示 75%），需要转换为百分比
      const percentage = (rate || 0) * 100
      return {
        background: `conic-gradient(#EC4899 0% ${percentage}%, #E5E7EB ${percentage}% 100%)`
      }
    },

    // 计算进度条宽度
    getProgressWidth(value) {
      if (!value && value !== 0) return '0%'
      // 假设最大值为500
      const maxValue = 500
      const percentage = (value / maxValue) * 100
      return Math.min(percentage, 100) + '%'
    },

    // 计算柱状图宽度（用于蝴蝶图）
    getButterflyBarWidth(value, maxValue) {
      if (!value && value !== 0 || !maxValue || maxValue === 0) return 0
      const percentage = (value / maxValue) * 100
      return Math.min(percentage, 100)
    },

    // 重置查询条件
    reset() {
      this.query = {
        startTime: undefined,
        endTime: undefined,
        storeIds: []
      }
      this.setDefaultTimeRange()
      this.businessData = null
      this.customerData = null
      this.performanceData = []
      this.itemStatisticsData = []
      this.storeItemStatisticsData = []
      this.customerVisitFrequencyData = []
      this.healthCoachBillingRankingData = []
      this.storeRemainingRightsData = []
      this.tkStatisticsData = null
      this.gaugeItems = []
    },

    // 获取排名索引（从1开始）
    getRankIndex(index) {
      return index + 1
    },

    // 格式化金额
    formatMoney(amount) {
      if (!amount && amount !== 0) return '0.00'
      return Number(amount).toFixed(2)
    },

    // 格式化百分比
    formatPercent(ratio) {
      if (!ratio && ratio !== 0) return '0.00'
      return Number(ratio).toFixed(2)
    },

    // 格式化日期时间（用于API传参）
    formatDateTime(timestamp) {
      if (!timestamp) return ''
      const date = new Date(timestamp)
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hours = String(date.getHours()).padStart(2, '0')
      const minutes = String(date.getMinutes()).padStart(2, '0')
      const seconds = String(date.getSeconds()).padStart(2, '0')
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    },

    // 字段配置相关方法
    // 判断字段是否可见
    isFieldVisible(fieldProp) {
      return this.selectedFields.includes(fieldProp)
    },

    // 全选字段
    selectAllFields() {
      this.selectedFields = this.availableFields.map(field => field.prop)
    },

    // 全不选字段
    unselectAllFields() {
      this.selectedFields = []
    },

    // 确认字段配置
    confirmFieldConfig() {
      if (this.selectedFields.length === 0) {
        this.$message.warning('至少需要选择一个字段')
        return
      }
      this.showFieldConfigDialog = false
    },

    // 处理排序变化
    handleSortChange({ column, prop, order }) {
      if (!order) {
        // 取消排序，恢复到原始数据顺序
        this.sortParams = { prop: null, order: null }
        this.storeItemStatisticsData = JSON.parse(JSON.stringify(this.originalStoreItemStatisticsData))
        return
      }
      this.sortParams = { prop, order }
      this.sortTableData()
    },

    // 对表格数据进行排序
    sortTableData() {
      if (!this.sortParams.prop || !this.sortParams.order) {
        return
      }

      const { prop, order } = this.sortParams
      const data = [...this.storeItemStatisticsData]

      data.sort((a, b) => {
        let valA = a[prop]
        let valB = b[prop]

        // 处理空值
        if (valA == null) valA = 0
        if (valB == null) valB = 0

        // 确保是数字类型
        valA = Number(valA) || 0
        valB = Number(valB) || 0

        if (order === 'ascending') {
          return valA - valB
        } else {
          return valB - valA
        }
      })

      this.storeItemStatisticsData = data
    }
  }
}
</script>

<style lang="scss" scoped>
.business-report-page {
  padding: 16px;
  background-color: #f0f2f5;
  min-height: 100vh;
  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
}

.search-box-container {
  margin-bottom: 24px;
}

.search-form {
  display: flex;
  align-items: center;
}

.report-card {
  margin-bottom: 24px;
  border-radius: 4px;
  border: none;
  box-shadow: none !important;
  
  &::v-deep .el-card__header {
    background-color: #fff;
    border-bottom: 1px solid #ebeef5;
    padding: 14px 20px;
  }

  .card-header {
    display: flex;
    align-items: center;
    font-size: 15px;
    font-weight: 600;
    color: #303133;
    
    i {
      margin-right: 8px;
      font-size: 16px;
      color: #409EFF;
    }
  }
}

/* 业务统计仪表盘 */
.gauge-dashboard {
  padding: 16px 0;
}

.gauge-item-wrapper {
  position: relative;
  height: 100%;
}

.gauge-item {
  background: linear-gradient(135deg, #fff 0%, #f9fafb 100%);
  border-radius: 8px;
  padding: 0 10px;
  text-align: center;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  
  &:hover {
    transform: translateY(-5px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  }
}

.gauge-chart-container {
  position: relative;
  margin: 16px 0;
  min-height: 200px;
}

.gauge-chart {
  height: 200px;
}

.gauge-value-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  padding-top: 30px;
  
  .gauge-icon-wrapper {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: linear-gradient(135deg, #409EFF, #67C23A);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 12px;
    box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
    
    i {
      font-size: 24px;
      color: #fff;
    }
  }
  
  .gauge-value-large {
    font-size: 20px;
    font-weight: bold;
    color: #303133;
    margin-bottom: 2px;
    letter-spacing: 0;
    text-align: center;
    line-height: 1.2;
    max-width: 100%;
    word-wrap: break-word;
    overflow-wrap: break-word;
  }
  
  .gauge-label-text {
    font-size: 13px;
    color: #606266;
    font-weight: 400;
  }
}

.gauge-range-info {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 10px;
  
  .range-label,
  .range-value {
    font-size: 12px;
    color: #909399;
  }
  
  .range-divider {
    flex: 1;
    height: 1px;
    background: #DCDFE6;
    margin: 0 10px;
  }
}

/* 客户类型统计 */
.customer-stats-container {
  padding: 16px 0;
}

.stats-grid {
  /* Removed grid layout in favor of el-row/el-col */
}

.stat-card {
  background: linear-gradient(135deg, #fff 0%, #f9fafb 100%);
  border-radius: 8px;
  padding: 16px;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  min-height: 90px;
  height: 100%;
  
  &:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  }
  
  &.stat-card-purple {
    .stat-icon {
      background: rgba(138, 43, 226, 0.1);
      i { color: #8A2BE2; }
    }
  }
  
  &.stat-card-blue {
    .stat-icon {
      background: rgba(64, 158, 255, 0.1);
      i { color: #409EFF; }
    }
  }
  
  &.stat-card-green {
    .stat-icon {
      background: rgba(103, 194, 58, 0.1);
      i { color: #67C23A; }
    }
  }
  
  &.stat-card-cyan {
    .stat-icon {
      background: rgba(0, 206, 209, 0.1);
      i { color: #00CED1; }
    }
  }
}

.stat-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 16px;
  flex-shrink: 0;
  
  i {
    font-size: 24px;
  }
}

.stat-content {
  flex: 1;
  min-width: 0; /* Fix flex overflow */
}

.stat-label {
  font-size: 13px;
  color: #909399;
  margin-bottom: 4px;
  white-space: nowrap;
}

.stat-value {
  font-size: 20px;
  font-weight: bold;
  color: #303133;
  line-height: 1.2;
}

.stat-progress {
  height: 6px;
  background: #E5E7EB;
  border-radius: 3px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  border-radius: 3px;
  transition: width 0.8s ease;
}

.conversion-rate-card {
  background: linear-gradient(135deg, #fff 0%, #f9fafb 100%);
  border-radius: 8px;
  padding: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  min-height: 90px;
  height: 100%;
  
  &:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 24px rgba(236, 72, 153, 0.2);
  }
}

.donut-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.donut-chart {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  background: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  
  .donut-center {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    background: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 6px;
    
    .conversion-title {
      font-size: 12px;
      color: #909399;
      margin-bottom: 4px;
      font-weight: 500;
      text-align: center;
      white-space: nowrap;
    }
    
    .percentage {
      font-size: 16px;
      font-weight: bold;
      color: #EC4899;
      line-height: 1;
      text-align: center;
    }
  }
}

/* 图表行容器 */
.charts-row {
  /* display: grid; Removed */
  /* grid-template-columns: 1fr 1fr; Removed */
  /* gap: 20px; Removed */
  margin-bottom: 24px;
}

.half-width {
  margin-bottom: 0;
}

/* 图表容器 */
.chart-container {
  width: 100%;
  height: 500px;
  margin-top: 16px;
}

.chart-container-half {
  width: 100%;
  height: 400px;
  margin-top: 16px;
}

/* 蝴蝶图样式 */
.butterfly-chart-container {
  padding: 16px 0;
}

.chart-legend {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-bottom: 24px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.legend-color {
  width: 40px;
  height: 16px;
  border-radius: 4px;
}

.legend-purple {
  background: #409EFF;
}

.legend-orange {
  background: #67C23A;
}

.legend-text {
  font-size: 14px;
  color: #303133;
  font-weight: 500;
}

.chart-axis {
  padding: 0 50px;
  margin-bottom: 10px;
}

.axis-labels {
  display: grid;
  grid-template-columns: repeat(14, 1fr);
  gap: 0;
}

.axis-label {
  font-size: 11px;
  color: #909399;
  text-align: center;
}

.butterfly-chart-content {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 8px;
  align-items: center;
  padding: 0 10px;
}

.chart-left,
.chart-right {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}

.chart-row {
  height: 32px;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
}

.chart-left .chart-row {
  justify-content: flex-end;
}

.chart-right .chart-row {
  justify-content: flex-start;
}

.bar-left,
.bar-right {
  height: 24px;
  display: flex;
  align-items: center;
  border-radius: 4px;
  min-width: 40px;
}

.bar-left {
  background: #409EFF;
  justify-content: flex-end;
  padding-right: 8px;
  transition: width 0.3s ease;
}

.bar-right {
  background: #67C23A;
  justify-content: flex-start;
  padding-left: 8px;
  transition: width 0.3s ease;
}

.bar-value {
  font-size: 11px;
  font-weight: 500;
  color: #fff;
}

.chart-center {
  min-width: 80px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
  padding: 0 8px;
}

.category-name {
  height: 32px;
  font-size: 12px;
  color: #303133;
  display: flex;
  align-items: center;
  margin-bottom: 6px;
  text-align: center;
  line-height: 1.4;
}

/* 字段配置对话框样式 */
.field-config-content {
  max-height: 400px;
  overflow-y: auto;
}

.field-config-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid #EBEEF5;
}

.field-config-item {
  padding: 10px 0;
  border-bottom: 1px solid #F5F7FA;

  &:last-child {
    border-bottom: none;
  }

  ::v-deep .el-checkbox {
    width: 100%;

    .el-checkbox__label {
      font-size: 14px;
      color: #303133;
    }
  }
}

/* 拓客转化漏斗图样式 */
.funnel-container {
  padding: 16px 0;
}

.funnel-chart-container {
  width: 100%;
  height: 500px;
  margin-bottom: 24px;
}

.funnel-chart-container-half {
  width: 100%;
  height: 300px;
  margin-bottom: 16px;
}

.conversion-rate-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-top: 10px;
}

.conversion-card {
  background: linear-gradient(135deg, #fff 0%, #f9fafb 100%);
  border-radius: 8px;
  padding: 12px;
  text-align: center;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  }
}

.conversion-label {
  font-size: 12px;
  color: #909399;
  margin-bottom: 6px;
  font-weight: 500;
}

.conversion-value {
  font-size: 20px;
  font-weight: bold;
  color: #409EFF;
  margin-bottom: 4px;
  line-height: 1.2;
}

.conversion-detail {
  font-size: 12px;
  color: #909399;
}
</style>