gaoluyang
6 天以前 4650de835add34d2193d52c620523d43ec4f50a9
汇星与博达-策略管控前端页面
已添加2个文件
1549 ■■■■■ 文件已修改
src/api/salesManagement/strategyControl.js 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/strategyControl/index.vue 1347 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/strategyControl.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,202 @@
// ç­–略管控页面接口
import request from "@/utils/request";
// ========== ä»·æ ¼ç­–略配置 ==========
// åˆ†é¡µæŸ¥è¯¢ä»·æ ¼ç­–略列表
export function getPriceStrategyList(query) {
  return request({
    url: "/sales/priceStrategy/list",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢ä»·æ ¼ç­–略详情
export function getPriceStrategyDetail(id) {
  return request({
    url: "/sales/priceStrategy/detail",
    method: "get",
    params: { id },
  });
}
// æ–°å¢žä»·æ ¼ç­–ç•¥
export function addPriceStrategy(data) {
  return request({
    url: "/sales/priceStrategy/add",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹ä»·æ ¼ç­–ç•¥
export function updatePriceStrategy(data) {
  return request({
    url: "/sales/priceStrategy/update",
    method: "post",
    data: data,
  });
}
// åˆ é™¤ä»·æ ¼ç­–ç•¥
export function deletePriceStrategy(id) {
  return request({
    url: "/sales/priceStrategy/delete",
    method: "delete",
    params: { id },
  });
}
// å¯ç”¨/禁用价格策略
export function togglePriceStrategy(data) {
  return request({
    url: "/sales/priceStrategy/toggle",
    method: "post",
    data: data,
  });
}
// ========== åˆåŒæ‰§è¡Œç›‘控 ==========
// èŽ·å–åˆåŒæ‰§è¡Œç»Ÿè®¡æ•°æ®
export function getContractStats(query) {
  return request({
    url: "/sales/contract/stats",
    method: "get",
    params: query,
  });
}
// åˆ†é¡µæŸ¥è¯¢åˆåŒæ‰§è¡Œåˆ—表
export function getContractExecutionList(query) {
  return request({
    url: "/sales/contract/executionList",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢åˆåŒæ‰§è¡Œè¯¦æƒ…
export function getContractExecutionDetail(contractNo) {
  return request({
    url: "/sales/contract/executionDetail",
    method: "get",
    params: { contractNo },
  });
}
// æ›´æ–°åˆåŒæ‰§è¡Œè¿›åº¦
export function updateContractProgress(data) {
  return request({
    url: "/sales/contract/updateProgress",
    method: "post",
    data: data,
  });
}
// ========== åŽ†å²æ¯”ä»·åˆ†æž ==========
// æŸ¥è¯¢åŽ†å²ä»·æ ¼å¯¹æ¯”æ•°æ®
export function getPriceComparisonList(query) {
  return request({
    url: "/sales/priceComparison/list",
    method: "get",
    params: query,
  });
}
// èŽ·å–ä»·æ ¼è¶‹åŠ¿å›¾è¡¨æ•°æ®
export function getPriceTrendChart(query) {
  return request({
    url: "/sales/priceComparison/trendChart",
    method: "get",
    params: query,
  });
}
// å¯¼å‡ºåŽ†å²æ¯”ä»·æ•°æ®
export function exportPriceComparison(query) {
  return request({
    url: "/sales/priceComparison/export",
    method: "get",
    params: query,
    responseType: "blob",
  });
}
// ========== åˆ©æ¶¦åˆ†æž ==========
// èŽ·å–åˆ©æ¶¦ç»Ÿè®¡æ•°æ®
export function getProfitStats(query) {
  return request({
    url: "/sales/profit/stats",
    method: "get",
    params: query,
  });
}
// åˆ†é¡µæŸ¥è¯¢åˆ©æ¶¦åˆ†æžåˆ—表
export function getProfitAnalysisList(query) {
  return request({
    url: "/sales/profit/analysisList",
    method: "get",
    params: query,
  });
}
// èŽ·å–åˆ©æ¶¦è¶‹åŠ¿å›¾è¡¨æ•°æ®
export function getProfitTrendChart(query) {
  return request({
    url: "/sales/profit/trendChart",
    method: "get",
    params: query,
  });
}
// è®¡ç®—毛利率
export function calculateGrossProfit(data) {
  return request({
    url: "/sales/profit/calculate",
    method: "post",
    data: data,
  });
}
// å¯¼å‡ºåˆ©æ¶¦åˆ†æžæŠ¥è¡¨
export function exportProfitAnalysis(query) {
  return request({
    url: "/sales/profit/export",
    method: "get",
    params: query,
    responseType: "blob",
  });
}
// ========== å…¬å…±æŽ¥å£ ==========
// æŸ¥è¯¢å®¢æˆ·åˆ—表(用于下拉选择)
export function getCustomerOptions() {
  return request({
    url: "/basic/customer/options",
    method: "get",
  });
}
// æŸ¥è¯¢äº§å“åˆ—表(用于下拉选择)
export function getProductOptions(query) {
  return request({
    url: "/basic/product/options",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢é”€å”®åŒºåŸŸåˆ—表
export function getRegionOptions() {
  return request({
    url: "/basic/region/options",
    method: "get",
  });
}
src/views/salesManagement/strategyControl/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1347 @@
<template>
  <div class="app-container strategy-control">
    <el-tabs v-model="activeTab" type="border-card" class="main-tabs" @tab-change="handleTabChange">
      <!-- ä»·æ ¼ç­–略配置 -->
      <el-tab-pane label="价格策略配置" name="priceStrategy">
        <el-card class="box-card">
          <el-row :gutter="20" class="search-row">
            <el-col :span="6">
              <el-select v-model="priceSearchForm.customerName" placeholder="请选择客户" clearable>
                <el-option label="全部客户" value=""></el-option>
                <el-option label="华东建材集团" value="华东建材集团"></el-option>
                <el-option label="长江混凝土公司" value="长江混凝土公司"></el-option>
                <el-option label="浦江水泥制品厂" value="浦江水泥制品厂"></el-option>
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-select v-model="priceSearchForm.productType" placeholder="请选择水泥类型" clearable>
                <el-option label="全部类型" value=""></el-option>
                <el-option label="普通硅酸盐水泥" value="普通硅酸盐水泥"></el-option>
                <el-option label="矿渣硅酸盐水泥" value="矿渣硅酸盐水泥"></el-option>
                <el-option label="复合硅酸盐水泥" value="复合硅酸盐水泥"></el-option>
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-select v-model="priceSearchForm.strategyType" placeholder="策略类型" clearable>
                <el-option label="全部策略" value=""></el-option>
                <el-option label="专属价格" value="专属价格"></el-option>
                <el-option label="阶梯报价" value="阶梯报价"></el-option>
                <el-option label="促销折扣" value="促销折扣"></el-option>
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-button type="primary" @click="searchPriceStrategy">查询</el-button>
              <el-button @click="resetPriceSearch">重置</el-button>
              <el-button type="primary" @click="handleAddPriceStrategy">新增策略</el-button>
            </el-col>
          </el-row>
          <el-table :data="priceStrategyList" border stripe v-loading="priceLoading" height="calc(100vh - 26em)">
            <el-table-column prop="id" label="ID" width="60" align="center"/>
            <el-table-column prop="strategyNo" label="策略编号" width="150"/>
            <el-table-column prop="strategyType" label="策略类型" width="100">
              <template #default="scope">
                <el-tag :type="getStrategyTypeColor(scope.row.strategyType)">
                  {{ scope.row.strategyType }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="customerName" label="客户名称" width="180"/>
            <el-table-column prop="productName" label="产品名称" width="200"/>
            <el-table-column prop="specification" label="规格型号" width="120"/>
            <el-table-column prop="basePrice" label="基础价格" width="100">
              <template #default="scope">
                Â¥{{ scope.row.basePrice }}/吨
              </template>
            </el-table-column>
            <el-table-column prop="strategyPrice" label="策略价格" width="120">
              <template #default="scope">
                <span style="color: #f56c6c; font-weight: bold;">
                  {{ scope.row.strategyPrice }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="validPeriod" label="有效期" width="200">
              <template #default="scope">
                {{ scope.row.startDate }} è‡³ {{ scope.row.endDate }}
              </template>
            </el-table-column>
            <el-table-column prop="status" label="状态" width="80">
              <template #default="scope">
                <el-tag :type="scope.row.status === '生效中' ? 'success' : 'info'">
                  {{ scope.row.status }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="200" fixed="right" align="center">
              <template #default="scope">
                <el-button link type="primary" @click="handleViewPriceStrategy(scope.row)">查看</el-button>
                <el-button link type="primary" @click="handleEditPriceStrategy(scope.row)">编辑</el-button>
                <el-button link type="danger" @click="handleDeletePriceStrategy(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
          <pagination
            :total="pricePagination.total"
            :page="pricePagination.currentPage"
            :limit="pricePagination.pageSize"
            @pagination="handlePricePageChange"
          />
        </el-card>
      </el-tab-pane>
      <!-- åˆåŒæ‰§è¡Œç›‘控 -->
      <el-tab-pane label="合同执行监控" name="contractMonitor">
        <el-card class="box-card">
          <!-- ç»Ÿè®¡æ¦‚览 -->
          <el-row :gutter="20" class="stats-row">
            <el-col :span="6">
              <div class="stat-card">
                <div class="stat-icon" style="background: #ecf5ff;">
                  <el-icon :size="30" color="#409eff"><Document /></el-icon>
                </div>
                <div class="stat-content">
                  <div class="stat-value">{{ contractStats.totalContracts }}</div>
                  <div class="stat-label">合同总数</div>
                </div>
              </div>
            </el-col>
            <el-col :span="6">
              <div class="stat-card">
                <div class="stat-icon" style="background: #f0f9ff;">
                  <el-icon :size="30" color="#67c23a"><Van /></el-icon>
                </div>
                <div class="stat-content">
                  <div class="stat-value">{{ contractStats.deliveryRate }}%</div>
                  <div class="stat-label">交付完成率</div>
                </div>
              </div>
            </el-col>
            <el-col :span="6">
              <div class="stat-card">
                <div class="stat-icon" style="background: #fef0f0;">
                  <el-icon :size="30" color="#e6a23c"><Tickets /></el-icon>
                </div>
                <div class="stat-content">
                  <div class="stat-value">{{ contractStats.invoiceRate }}%</div>
                  <div class="stat-label">发票开具率</div>
                </div>
              </div>
            </el-col>
            <el-col :span="6">
              <div class="stat-card">
                <div class="stat-icon" style="background: #f4f4f5;">
                  <el-icon :size="30" color="#f56c6c"><Wallet /></el-icon>
                </div>
                <div class="stat-content">
                  <div class="stat-value">{{ contractStats.paymentRate }}%</div>
                  <div class="stat-label">回款完成率</div>
                </div>
              </div>
            </el-col>
          </el-row>
          <!-- æœç´¢åŒºåŸŸ -->
          <el-row :gutter="20" class="search-row">
            <el-col :span="6">
              <el-input v-model="contractSearchForm.contractNo" placeholder="请输入合同编号" clearable>
                <template #prefix>
                  <el-icon><Search /></el-icon>
                </template>
              </el-input>
            </el-col>
            <el-col :span="6">
              <el-select v-model="contractSearchForm.customerName" placeholder="请选择客户" clearable>
                <el-option label="华东建材集团" value="华东建材集团"></el-option>
                <el-option label="长江混凝土公司" value="长江混凝土公司"></el-option>
                <el-option label="浦江水泥制品厂" value="浦江水泥制品厂"></el-option>
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-select v-model="contractSearchForm.executionStatus" placeholder="执行状态" clearable>
                <el-option label="待执行" value="待执行"></el-option>
                <el-option label="执行中" value="执行中"></el-option>
                <el-option label="已完成" value="已完成"></el-option>
                <el-option label="异常" value="异常"></el-option>
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-button type="primary" @click="searchContract">查询</el-button>
              <el-button @click="resetContractSearch">重置</el-button>
            </el-col>
          </el-row>
          <!-- åˆåŒåˆ—表 -->
          <el-table :data="contractList" border stripe v-loading="contractLoading" height="calc(100vh - 36em)">
            <el-table-column type="expand">
              <template #default="scope">
                <div class="contract-detail-expand">
                  <el-steps :active="getContractStep(scope.row)" align-center>
                    <el-step title="订单确认" :description="scope.row.orderDate">
                      <template #icon>
                        <el-icon :color="scope.row.orderStatus === '已完成' ? '#67c23a' : '#909399'">
                          <Check v-if="scope.row.orderStatus === '已完成'" />
                          <Clock v-else />
                        </el-icon>
                      </template>
                    </el-step>
                    <el-step title="货物交付" :description="`${scope.row.deliveryProgress}%`">
                      <template #icon>
                        <el-icon :color="scope.row.deliveryProgress === 100 ? '#67c23a' : '#409eff'">
                          <Check v-if="scope.row.deliveryProgress === 100" />
                          <Van v-else />
                        </el-icon>
                      </template>
                    </el-step>
                    <el-step title="发票开具" :description="`${scope.row.invoiceProgress}%`">
                      <template #icon>
                        <el-icon :color="scope.row.invoiceProgress === 100 ? '#67c23a' : '#e6a23c'">
                          <Check v-if="scope.row.invoiceProgress === 100" />
                          <Tickets v-else />
                        </el-icon>
                      </template>
                    </el-step>
                    <el-step title="款项收回" :description="`${scope.row.paymentProgress}%`">
                      <template #icon>
                        <el-icon :color="scope.row.paymentProgress === 100 ? '#67c23a' : '#f56c6c'">
                          <Check v-if="scope.row.paymentProgress === 100" />
                          <Wallet v-else />
                        </el-icon>
                      </template>
                    </el-step>
                  </el-steps>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="contractNo" label="合同编号" width="150"/>
            <el-table-column prop="customerName" label="客户名称" width="180"/>
            <el-table-column prop="contractAmount" label="合同金额" width="120">
              <template #default="scope">
                Â¥{{ scope.row.contractAmount.toLocaleString() }}
              </template>
            </el-table-column>
            <el-table-column prop="signDate" label="签订日期" width="120"/>
            <el-table-column label="执行进度" width="150">
              <template #default="scope">
                <el-progress
                  :percentage="scope.row.executionProgress"
                  :color="getProgressColor(scope.row.executionProgress)"
                />
              </template>
            </el-table-column>
            <el-table-column prop="deliveryProgress" label="交付进度" width="100">
              <template #default="scope">
                {{ scope.row.deliveryProgress }}%
              </template>
            </el-table-column>
            <el-table-column prop="invoiceProgress" label="开票进度" width="100">
              <template #default="scope">
                {{ scope.row.invoiceProgress }}%
              </template>
            </el-table-column>
            <el-table-column prop="paymentProgress" label="回款进度" width="100">
              <template #default="scope">
                {{ scope.row.paymentProgress }}%
              </template>
            </el-table-column>
            <el-table-column prop="executionStatus" label="执行状态" width="100">
              <template #default="scope">
                <el-tag :type="getExecutionStatusType(scope.row.executionStatus)">
                  {{ scope.row.executionStatus }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="120" fixed="right" align="center">
              <template #default="scope">
                <el-button link type="primary" @click="handleViewContract(scope.row)">查看详情</el-button>
              </template>
            </el-table-column>
          </el-table>
          <pagination
            :total="contractPagination.total"
            :page="contractPagination.currentPage"
            :limit="contractPagination.pageSize"
            @pagination="handleContractPageChange"
          />
        </el-card>
      </el-tab-pane>
      <!-- åŽ†å²æ¯”ä»·åˆ†æž -->
      <el-tab-pane label="历史比价分析" name="priceComparison">
        <el-card class="box-card">
          <el-row :gutter="20" class="search-row">
            <el-col :span="6">
              <el-select v-model="compareSearchForm.productName" placeholder="请选择产品" clearable>
                <el-option label="P.O 42.5普通硅酸盐水泥" value="P.O 42.5普通硅酸盐水泥"></el-option>
                <el-option label="P.S 32.5矿渣硅酸盐水泥" value="P.S 32.5矿渣硅酸盐水泥"></el-option>
                <el-option label="P.C 32.5复合硅酸盐水泥" value="P.C 32.5复合硅酸盐水泥"></el-option>
              </el-select>
            </el-col>
            <el-col :span="8">
              <el-date-picker
                v-model="compareSearchForm.dateRange"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="YYYY-MM-DD"
                style="width: 100%"
              />
            </el-col>
            <el-col :span="6">
              <el-select v-model="compareSearchForm.region" placeholder="销售区域" clearable>
                <el-option label="华东地区" value="华东地区"></el-option>
                <el-option label="华南地区" value="华南地区"></el-option>
                <el-option label="华北地区" value="华北地区"></el-option>
              </el-select>
            </el-col>
            <el-col :span="4">
              <el-button type="primary" @click="searchPriceComparison">查询</el-button>
              <el-button @click="resetCompareSearch">重置</el-button>
            </el-col>
          </el-row>
          <!-- ä»·æ ¼è¶‹åŠ¿å›¾ -->
          <div class="chart-container">
            <div ref="priceChartRef" style="width: 100%; height: 350px;"></div>
          </div>
          <!-- åŽ†å²ä»·æ ¼åˆ—è¡¨ -->
          <el-table :data="priceComparisonList" border stripe v-loading="compareLoading" style="margin-top: 20px;">
            <el-table-column prop="date" label="日期" width="120"/>
            <el-table-column prop="productName" label="产品名称" width="200"/>
            <el-table-column prop="specification" label="规格" width="120"/>
            <el-table-column prop="customerName" label="客户" width="180"/>
            <el-table-column prop="region" label="区域" width="100"/>
            <el-table-column prop="quantity" label="数量(吨)" width="100" align="right">
              <template #default="scope">
                {{ scope.row.quantity.toLocaleString() }}
              </template>
            </el-table-column>
            <el-table-column prop="price" label="成交单价" width="100">
              <template #default="scope">
                Â¥{{ scope.row.price }}/吨
              </template>
            </el-table-column>
            <el-table-column prop="totalAmount" label="成交金额" width="120">
              <template #default="scope">
                Â¥{{ scope.row.totalAmount.toLocaleString() }}
              </template>
            </el-table-column>
            <el-table-column prop="priceChange" label="价格变动" width="100">
              <template #default="scope">
                <span :style="{ color: scope.row.priceChange > 0 ? '#f56c6c' : scope.row.priceChange < 0 ? '#67c23a' : '#909399' }">
                  {{ scope.row.priceChange > 0 ? '+' : '' }}{{ scope.row.priceChange }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="remark" label="备注" show-overflow-tooltip/>
          </el-table>
        </el-card>
      </el-tab-pane>
      <!-- åˆ©æ¶¦åˆ†æž -->
      <el-tab-pane label="利润分析" name="profitAnalysis">
        <el-card class="box-card">
          <!-- åˆ©æ¶¦ç»Ÿè®¡å¡ç‰‡ -->
          <el-row :gutter="20" class="profit-stats-row">
            <el-col :span="8">
              <div class="profit-card">
                <div class="profit-header">总销售额</div>
                <div class="profit-value">Â¥{{ profitStats.totalSales.toLocaleString() }}</div>
                <div class="profit-footer">
                  <span>较上月</span>
                  <span :class="profitStats.salesGrowth > 0 ? 'growth-up' : 'growth-down'">
                    {{ profitStats.salesGrowth > 0 ? '+' : '' }}{{ profitStats.salesGrowth }}%
                  </span>
                </div>
              </div>
            </el-col>
            <el-col :span="8">
              <div class="profit-card">
                <div class="profit-header">总成本</div>
                <div class="profit-value">Â¥{{ profitStats.totalCost.toLocaleString() }}</div>
                <div class="profit-footer">
                  <span>成本率</span>
                  <span class="cost-rate">{{ profitStats.costRate }}%</span>
                </div>
              </div>
            </el-col>
            <el-col :span="8">
              <div class="profit-card">
                <div class="profit-header">毛利润</div>
                <div class="profit-value profit-highlight">Â¥{{ profitStats.grossProfit.toLocaleString() }}</div>
                <div class="profit-footer">
                  <span>毛利率</span>
                  <span class="gross-profit-rate">{{ profitStats.grossProfitRate }}%</span>
                </div>
              </div>
            </el-col>
          </el-row>
          <!-- æœç´¢åŒºåŸŸ -->
          <el-row :gutter="20" class="search-row">
            <el-col :span="6">
              <el-select v-model="profitSearchForm.productType" placeholder="产品类型" clearable>
                <el-option label="普通硅酸盐水泥" value="普通硅酸盐水泥"></el-option>
                <el-option label="矿渣硅酸盐水泥" value="矿渣硅酸盐水泥"></el-option>
                <el-option label="复合硅酸盐水泥" value="复合硅酸盐水泥"></el-option>
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-select v-model="profitSearchForm.customerName" placeholder="客户名称" clearable>
                <el-option label="华东建材集团" value="华东建材集团"></el-option>
                <el-option label="长江混凝土公司" value="长江混凝土公司"></el-option>
                <el-option label="浦江水泥制品厂" value="浦江水泥制品厂"></el-option>
              </el-select>
            </el-col>
            <el-col :span="8">
              <el-date-picker
                v-model="profitSearchForm.dateRange"
                type="monthrange"
                range-separator="至"
                start-placeholder="开始月份"
                end-placeholder="结束月份"
                value-format="YYYY-MM"
                style="width: 100%"
              />
            </el-col>
            <el-col :span="4">
              <el-button type="primary" @click="searchProfit">查询</el-button>
              <el-button @click="resetProfitSearch">重置</el-button>
            </el-col>
          </el-row>
          <!-- åˆ©æ¶¦åˆ†æžå›¾è¡¨ -->
          <div class="chart-container">
            <div ref="profitChartRef" style="width: 100%; height: 350px;"></div>
          </div>
          <!-- åˆ©æ¶¦æ˜Žç»†è¡¨ -->
          <el-table :data="profitAnalysisList" border stripe v-loading="profitLoading" style="margin-top: 20px;" show-summary :summary-method="getProfitSummary">
            <el-table-column prop="orderNo" label="订单编号" width="150"/>
            <el-table-column prop="customerName" label="客户名称" width="180"/>
            <el-table-column prop="productName" label="产品名称" width="200"/>
            <el-table-column prop="quantity" label="数量(吨)" width="100" align="right">
              <template #default="scope">
                {{ scope.row.quantity.toLocaleString() }}
              </template>
            </el-table-column>
            <el-table-column prop="salesPrice" label="销售单价" width="100">
              <template #default="scope">
                Â¥{{ scope.row.salesPrice }}
              </template>
            </el-table-column>
            <el-table-column prop="costPrice" label="成本单价" width="100">
              <template #default="scope">
                Â¥{{ scope.row.costPrice }}
              </template>
            </el-table-column>
            <el-table-column prop="salesAmount" label="销售金额" width="120" align="right">
              <template #default="scope">
                Â¥{{ scope.row.salesAmount.toLocaleString() }}
              </template>
            </el-table-column>
            <el-table-column prop="costAmount" label="成本金额" width="120" align="right">
              <template #default="scope">
                Â¥{{ scope.row.costAmount.toLocaleString() }}
              </template>
            </el-table-column>
            <el-table-column prop="grossProfit" label="毛利润" width="120" align="right">
              <template #default="scope">
                <span :style="{ color: scope.row.grossProfit > 0 ? '#67c23a' : '#f56c6c', fontWeight: 'bold' }">
                  Â¥{{ scope.row.grossProfit.toLocaleString() }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="grossProfitRate" label="毛利率" width="100">
              <template #default="scope">
                <el-tag :type="getProfitRateType(scope.row.grossProfitRate)">
                  {{ scope.row.grossProfitRate }}%
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="orderDate" label="订单日期" width="120"/>
          </el-table>
          <pagination
            :total="profitPagination.total"
            :page="profitPagination.currentPage"
            :limit="profitPagination.pageSize"
            @pagination="handleProfitPageChange"
          />
        </el-card>
      </el-tab-pane>
    </el-tabs>
    <!-- ä»·æ ¼ç­–略对话框 -->
    <el-dialog v-model="priceStrategyDialogVisible" :title="priceStrategyDialogTitle" width="900px" :close-on-click-modal="false">
      <el-form :model="priceStrategyForm" :rules="priceStrategyRules" ref="priceStrategyFormRef" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="策略类型" prop="strategyType">
              <el-select v-model="priceStrategyForm.strategyType" placeholder="请选择策略类型" style="width: 100%;">
                <el-option label="专属价格" value="专属价格"></el-option>
                <el-option label="阶梯报价" value="阶梯报价"></el-option>
                <el-option label="促销折扣" value="促销折扣"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="客户名称" prop="customerName">
              <el-select v-model="priceStrategyForm.customerName" placeholder="请选择客户" style="width: 100%;">
                <el-option label="华东建材集团" value="华东建材集团"></el-option>
                <el-option label="长江混凝土公司" value="长江混凝土公司"></el-option>
                <el-option label="浦江水泥制品厂" value="浦江水泥制品厂"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="产品名称" prop="productName">
              <el-select v-model="priceStrategyForm.productName" placeholder="请选择产品" style="width: 100%;">
                <el-option label="P.O 42.5普通硅酸盐水泥" value="P.O 42.5普通硅酸盐水泥"></el-option>
                <el-option label="P.S 32.5矿渣硅酸盐水泥" value="P.S 32.5矿渣硅酸盐水泥"></el-option>
                <el-option label="P.C 32.5复合硅酸盐水泥" value="P.C 32.5复合硅酸盐水泥"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号" prop="specification">
              <el-input v-model="priceStrategyForm.specification" placeholder="请输入规格型号" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="基础价格(元/吨)" prop="basePrice">
              <el-input-number v-model="priceStrategyForm.basePrice" :min="0" :precision="2" style="width: 100%;" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="策略价格" prop="strategyPrice">
              <el-input v-model="priceStrategyForm.strategyPrice" placeholder="如: Â¥350/吨 æˆ– 9折" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="生效日期" prop="startDate">
              <el-date-picker
                v-model="priceStrategyForm.startDate"
                type="date"
                placeholder="选择生效日期"
                style="width: 100%"
                value-format="YYYY-MM-DD"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="失效日期" prop="endDate">
              <el-date-picker
                v-model="priceStrategyForm.endDate"
                type="date"
                placeholder="选择失效日期"
                style="width: 100%"
                value-format="YYYY-MM-DD"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="策略说明" prop="description">
          <el-input type="textarea" v-model="priceStrategyForm.description" :rows="3" placeholder="请输入策略说明" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="priceStrategyDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSavePriceStrategy">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, reactive, onMounted, nextTick, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Document, Van, Tickets, Wallet, Check, Clock, Search } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import Pagination from '@/components/PIMTable/Pagination.vue'
// æ´»åŠ¨æ ‡ç­¾é¡µ
const activeTab = ref('priceStrategy')
// ========== ä»·æ ¼ç­–略配置 ==========
const priceLoading = ref(false)
const priceSearchForm = reactive({
  customerName: '',
  productType: '',
  strategyType: ''
})
const priceStrategyList = ref([
  {
    id: 1,
    strategyNo: 'PS202501001',
    strategyType: '专属价格',
    customerName: '华东建材集团',
    productName: 'P.O 42.5普通硅酸盐水泥',
    specification: '50kg/袋',
    basePrice: 380,
    strategyPrice: 'Â¥350/吨',
    startDate: '2025-01-01',
    endDate: '2025-12-31',
    status: '生效中',
    description: '战略合作客户专属优惠价格'
  },
  {
    id: 2,
    strategyNo: 'PS202501002',
    strategyType: '阶梯报价',
    customerName: '长江混凝土公司',
    productName: 'P.S 32.5矿渣硅酸盐水泥',
    specification: '50kg/袋',
    basePrice: 320,
    strategyPrice: '500吨以上9折',
    startDate: '2025-01-01',
    endDate: '2025-06-30',
    status: '生效中',
    description: '大批量采购阶梯优惠'
  },
  {
    id: 3,
    strategyNo: 'PS202501003',
    strategyType: '促销折扣',
    customerName: '浦江水泥制品厂',
    productName: 'P.C 32.5复合硅酸盐水泥',
    specification: '50kg/袋',
    basePrice: 300,
    strategyPrice: '8.5折',
    startDate: '2025-01-15',
    endDate: '2025-02-28',
    status: '生效中',
    description: '春节促销活动'
  },
  {
    id: 4,
    strategyNo: 'PS202412015',
    strategyType: '专属价格',
    customerName: '华东建材集团',
    productName: 'P.C 32.5复合硅酸盐水泥',
    specification: '50kg/袋',
    basePrice: 300,
    strategyPrice: 'Â¥285/吨',
    startDate: '2024-10-01',
    endDate: '2024-12-31',
    status: '已过期',
    description: '第四季度专属价格'
  }
])
const pricePagination = reactive({
  total: 4,
  currentPage: 1,
  pageSize: 10
})
const priceStrategyDialogVisible = ref(false)
const priceStrategyDialogTitle = ref('新增价格策略')
const priceStrategyForm = reactive({
  strategyType: '',
  customerName: '',
  productName: '',
  specification: '',
  basePrice: 0,
  strategyPrice: '',
  startDate: '',
  endDate: '',
  description: ''
})
const priceStrategyRules = {
  strategyType: [{ required: true, message: '请选择策略类型', trigger: 'change' }],
  customerName: [{ required: true, message: '请选择客户', trigger: 'change' }],
  productName: [{ required: true, message: '请选择产品', trigger: 'change' }],
  basePrice: [{ required: true, message: '请输入基础价格', trigger: 'blur' }],
  strategyPrice: [{ required: true, message: '请输入策略价格', trigger: 'blur' }],
  startDate: [{ required: true, message: '请选择生效日期', trigger: 'change' }],
  endDate: [{ required: true, message: '请选择失效日期', trigger: 'change' }]
}
const priceStrategyFormRef = ref()
// ========== åˆåŒæ‰§è¡Œç›‘控 ==========
const contractLoading = ref(false)
const contractStats = reactive({
  totalContracts: 48,
  deliveryRate: 87.5,
  invoiceRate: 82.3,
  paymentRate: 75.6
})
const contractSearchForm = reactive({
  contractNo: '',
  customerName: '',
  executionStatus: ''
})
const contractList = ref([
  {
    id: 1,
    contractNo: 'CT202501001',
    customerName: '华东建材集团',
    contractAmount: 2850000,
    signDate: '2025-01-05',
    executionProgress: 85,
    deliveryProgress: 90,
    invoiceProgress: 85,
    paymentProgress: 75,
    executionStatus: '执行中',
    orderStatus: '已完成',
    orderDate: '2025-01-05'
  },
  {
    id: 2,
    contractNo: 'CT202501002',
    customerName: '长江混凝土公司',
    contractAmount: 1650000,
    signDate: '2025-01-08',
    executionProgress: 95,
    deliveryProgress: 100,
    invoiceProgress: 100,
    paymentProgress: 85,
    executionStatus: '执行中',
    orderStatus: '已完成',
    orderDate: '2025-01-08'
  },
  {
    id: 3,
    contractNo: 'CT202501003',
    customerName: '浦江水泥制品厂',
    contractAmount: 980000,
    signDate: '2025-01-12',
    executionProgress: 60,
    deliveryProgress: 65,
    invoiceProgress: 60,
    paymentProgress: 50,
    executionStatus: '执行中',
    orderStatus: '已完成',
    orderDate: '2025-01-12'
  },
  {
    id: 4,
    contractNo: 'CT202412028',
    customerName: '华东建材集团',
    contractAmount: 3200000,
    signDate: '2024-12-15',
    executionProgress: 100,
    deliveryProgress: 100,
    invoiceProgress: 100,
    paymentProgress: 100,
    executionStatus: '已完成',
    orderStatus: '已完成',
    orderDate: '2024-12-15'
  },
  {
    id: 5,
    contractNo: 'CT202501004',
    customerName: '长江混凝土公司',
    contractAmount: 750000,
    signDate: '2025-01-20',
    executionProgress: 25,
    deliveryProgress: 30,
    invoiceProgress: 20,
    paymentProgress: 0,
    executionStatus: '异常',
    orderStatus: '已完成',
    orderDate: '2025-01-20'
  }
])
const contractPagination = reactive({
  total: 5,
  currentPage: 1,
  pageSize: 10
})
// ========== åŽ†å²æ¯”ä»·åˆ†æž ==========
const compareLoading = ref(false)
const compareSearchForm = reactive({
  productName: '',
  dateRange: [],
  region: ''
})
const priceComparisonList = ref([
  { date: '2025-01-20', productName: 'P.O 42.5普通硅酸盐水泥', specification: '50kg/袋', customerName: '华东建材集团', region: '华东地区', quantity: 5000, price: 350, totalAmount: 1750000, priceChange: 0, remark: '长期合作客户' },
  { date: '2025-01-15', productName: 'P.O 42.5普通硅酸盐水泥', specification: '50kg/袋', customerName: '浦东新区建筑公司', region: '华东地区', quantity: 3000, price: 365, totalAmount: 1095000, priceChange: +15, remark: '现款现货' },
  { date: '2025-01-10', productName: 'P.O 42.5普通硅酸盐水泥', specification: '50kg/袋', customerName: '长江混凝土公司', region: '华东地区', quantity: 8000, price: 345, totalAmount: 2760000, priceChange: -5, remark: '大批量优惠' },
  { date: '2025-01-05', productName: 'P.O 42.5普通硅酸盐水泥', specification: '50kg/袋', customerName: '江苏工程集团', region: '华东地区', quantity: 4500, price: 360, totalAmount: 1620000, priceChange: +10, remark: '工程项目专用' },
  { date: '2024-12-28', productName: 'P.O 42.5普通硅酸盐水泥', specification: '50kg/袋', customerName: '华东建材集团', region: '华东地区', quantity: 6000, price: 355, totalAmount: 2130000, priceChange: +5, remark: '年底备货' },
  { date: '2024-12-20', productName: 'P.O 42.5普通硅酸盐水泥', specification: '50kg/袋', customerName: '上海市政工程', region: '华东地区', quantity: 10000, price: 340, totalAmount: 3400000, priceChange: -10, remark: '政府项目' }
])
const priceChartRef = ref(null)
let priceChart = null
// ========== åˆ©æ¶¦åˆ†æž ==========
const profitLoading = ref(false)
const profitStats = reactive({
  totalSales: 15680000,
  totalCost: 11256000,
  grossProfit: 4424000,
  grossProfitRate: 28.2,
  salesGrowth: 12.5,
  costRate: 71.8
})
const profitSearchForm = reactive({
  productType: '',
  customerName: '',
  dateRange: []
})
const profitAnalysisList = ref([
  { orderNo: 'SO202501015', customerName: '华东建材集团', productName: 'P.O 42.5普通硅酸盐水泥', quantity: 5000, salesPrice: 350, costPrice: 245, salesAmount: 1750000, costAmount: 1225000, grossProfit: 525000, grossProfitRate: 30.0, orderDate: '2025-01-20' },
  { orderNo: 'SO202501012', customerName: '长江混凝土公司', productName: 'P.S 32.5矿渣硅酸盐水泥', quantity: 3500, salesPrice: 288, costPrice: 210, salesAmount: 1008000, costAmount: 735000, grossProfit: 273000, grossProfitRate: 27.1, orderDate: '2025-01-18' },
  { orderNo: 'SO202501008', customerName: '浦江水泥制品厂', productName: 'P.C 32.5复合硅酸盐水泥', quantity: 2800, salesPrice: 255, costPrice: 185, salesAmount: 714000, costAmount: 518000, grossProfit: 196000, grossProfitRate: 27.5, orderDate: '2025-01-15' },
  { orderNo: 'SO202501005', customerName: '华东建材集团', productName: 'P.O 42.5普通硅酸盐水泥', quantity: 6000, salesPrice: 350, costPrice: 248, salesAmount: 2100000, costAmount: 1488000, grossProfit: 612000, grossProfitRate: 29.1, orderDate: '2025-01-10' },
  { orderNo: 'SO202501003', customerName: '江苏工程集团', productName: 'P.O 42.5普通硅酸盐水泥', quantity: 4500, salesPrice: 360, costPrice: 250, salesAmount: 1620000, costAmount: 1125000, grossProfit: 495000, grossProfitRate: 30.6, orderDate: '2025-01-08' },
  { orderNo: 'SO202412025', customerName: '长江混凝土公司', productName: 'P.S 32.5矿渣硅酸盐水泥', quantity: 8000, salesPrice: 290, costPrice: 215, salesAmount: 2320000, costAmount: 1720000, grossProfit: 600000, grossProfitRate: 25.9, orderDate: '2024-12-28' }
])
const profitPagination = reactive({
  total: 6,
  currentPage: 1,
  pageSize: 10
})
const profitChartRef = ref(null)
let profitChart = null
// ========== æ–¹æ³• ==========
// ä»·æ ¼ç­–略相关方法
const getStrategyTypeColor = (type) => {
  const colorMap = {
    '专属价格': 'success',
    '阶梯报价': 'primary',
    '促销折扣': 'warning'
  }
  return colorMap[type] || 'info'
}
const searchPriceStrategy = () => {
  priceLoading.value = true
  setTimeout(() => {
    priceLoading.value = false
  }, 500)
}
const resetPriceSearch = () => {
  priceSearchForm.customerName = ''
  priceSearchForm.productType = ''
  priceSearchForm.strategyType = ''
}
const handleAddPriceStrategy = () => {
  priceStrategyDialogTitle.value = '新增价格策略'
  resetPriceStrategyForm()
  priceStrategyDialogVisible.value = true
}
const handleViewPriceStrategy = (row) => {
  ElMessage.info('查看策略详情: ' + row.strategyNo)
}
const handleEditPriceStrategy = (row) => {
  priceStrategyDialogTitle.value = '编辑价格策略'
  Object.assign(priceStrategyForm, row)
  priceStrategyDialogVisible.value = true
}
const handleDeletePriceStrategy = (row) => {
  ElMessageBox.confirm('确认删除该价格策略吗?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    ElMessage.success('删除成功')
  })
}
const resetPriceStrategyForm = () => {
  Object.keys(priceStrategyForm).forEach(key => {
    if (key === 'basePrice') {
      priceStrategyForm[key] = 0
    } else {
      priceStrategyForm[key] = ''
    }
  })
}
const handleSavePriceStrategy = () => {
  priceStrategyFormRef.value.validate((valid) => {
    if (valid) {
      ElMessage.success('保存成功')
      priceStrategyDialogVisible.value = false
    }
  })
}
const handlePricePageChange = (val) => {
  pricePagination.currentPage = val.page
  pricePagination.pageSize = val.limit
}
// åˆåŒæ‰§è¡Œç›‘控相关方法
const getExecutionStatusType = (status) => {
  const statusMap = {
    '待执行': 'info',
    '执行中': 'primary',
    '已完成': 'success',
    '异常': 'danger'
  }
  return statusMap[status] || 'info'
}
const getProgressColor = (percentage) => {
  if (percentage < 30) return '#f56c6c'
  if (percentage < 70) return '#e6a23c'
  return '#67c23a'
}
const getContractStep = (row) => {
  if (row.paymentProgress === 100) return 4
  if (row.invoiceProgress === 100) return 3
  if (row.deliveryProgress === 100) return 2
  if (row.orderStatus === '已完成') return 1
  return 0
}
const searchContract = () => {
  contractLoading.value = true
  setTimeout(() => {
    contractLoading.value = false
  }, 500)
}
const resetContractSearch = () => {
  contractSearchForm.contractNo = ''
  contractSearchForm.customerName = ''
  contractSearchForm.executionStatus = ''
}
const handleViewContract = (row) => {
  ElMessage.info('查看合同详情: ' + row.contractNo)
}
const handleContractPageChange = (val) => {
  contractPagination.currentPage = val.page
  contractPagination.pageSize = val.limit
}
// åŽ†å²æ¯”ä»·åˆ†æžç›¸å…³æ–¹æ³•
const searchPriceComparison = () => {
  compareLoading.value = true
  setTimeout(() => {
    compareLoading.value = false
    initPriceChart()
  }, 500)
}
const resetCompareSearch = () => {
  compareSearchForm.productName = ''
  compareSearchForm.dateRange = []
  compareSearchForm.region = ''
}
const initPriceChart = () => {
  if (!priceChartRef.value) return
  if (priceChart) {
    priceChart.dispose()
  }
  priceChart = echarts.init(priceChartRef.value)
  const option = {
    title: {
      text: '水泥价格趋势分析',
      left: 'center'
    },
    tooltip: {
      trigger: 'axis',
      formatter: '{b}<br/>{a}: Â¥{c}/吨'
    },
    legend: {
      data: ['P.O 42.5普通硅酸盐水泥'],
      top: 30
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: ['2024-12-20', '2024-12-28', '2025-01-05', '2025-01-10', '2025-01-15', '2025-01-20']
    },
    yAxis: {
      type: 'value',
      name: 'ä»·æ ¼(元/吨)',
      min: 330,
      max: 370
    },
    series: [
      {
        name: 'P.O 42.5普通硅酸盐水泥',
        type: 'line',
        data: [340, 355, 360, 345, 365, 350],
        smooth: true,
        itemStyle: {
          color: '#409eff'
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(64, 158, 255, 0.3)' },
            { offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
          ])
        }
      }
    ]
  }
  priceChart.setOption(option)
}
// åˆ©æ¶¦åˆ†æžç›¸å…³æ–¹æ³•
const searchProfit = () => {
  profitLoading.value = true
  setTimeout(() => {
    profitLoading.value = false
    initProfitChart()
  }, 500)
}
const resetProfitSearch = () => {
  profitSearchForm.productType = ''
  profitSearchForm.customerName = ''
  profitSearchForm.dateRange = []
}
const getProfitRateType = (rate) => {
  if (rate >= 30) return 'success'
  if (rate >= 25) return 'warning'
  return 'danger'
}
const getProfitSummary = (param) => {
  const { columns, data } = param
  const sums = []
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = '合计'
      return
    }
    if (['quantity', 'salesAmount', 'costAmount', 'grossProfit'].includes(column.property)) {
      const values = data.map(item => Number(item[column.property]))
      if (!values.every(value => isNaN(value))) {
        const total = values.reduce((prev, curr) => {
          const value = Number(curr)
          if (!isNaN(value)) {
            return prev + curr
          } else {
            return prev
          }
        }, 0)
        sums[index] = column.property === 'quantity' ? total.toLocaleString() : 'Â¥' + total.toLocaleString()
      }
    } else if (column.property === 'grossProfitRate') {
      // è®¡ç®—平均毛利率
      const totalSales = data.reduce((sum, item) => sum + item.salesAmount, 0)
      const totalProfit = data.reduce((sum, item) => sum + item.grossProfit, 0)
      sums[index] = ((totalProfit / totalSales) * 100).toFixed(1) + '%'
    }
  })
  return sums
}
const initProfitChart = () => {
  if (!profitChartRef.value) return
  if (profitChart) {
    profitChart.dispose()
  }
  profitChart = echarts.init(profitChartRef.value)
  const option = {
    title: {
      text: '销售与利润趋势分析',
      left: 'center'
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        crossStyle: {
          color: '#999'
        }
      }
    },
    legend: {
      data: ['销售金额', '成本金额', '毛利润', '毛利率'],
      top: 30
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'category',
        data: ['2024-12', '2025-01'],
        axisPointer: {
          type: 'shadow'
        }
      }
    ],
    yAxis: [
      {
        type: 'value',
        name: '金额(万元)',
        axisLabel: {
          formatter: '{value}'
        }
      },
      {
        type: 'value',
        name: '毛利率(%)',
        min: 0,
        max: 40,
        axisLabel: {
          formatter: '{value}%'
        }
      }
    ],
    series: [
      {
        name: '销售金额',
        type: 'bar',
        data: [820, 950],
        itemStyle: {
          color: '#409eff'
        }
      },
      {
        name: '成本金额',
        type: 'bar',
        data: [605, 670],
        itemStyle: {
          color: '#e6a23c'
        }
      },
      {
        name: '毛利润',
        type: 'bar',
        data: [215, 280],
        itemStyle: {
          color: '#67c23a'
        }
      },
      {
        name: '毛利率',
        type: 'line',
        yAxisIndex: 1,
        data: [26.2, 29.5],
        itemStyle: {
          color: '#f56c6c'
        }
      }
    ]
  }
  profitChart.setOption(option)
}
const handleProfitPageChange = (val) => {
  profitPagination.currentPage = val.page
  profitPagination.pageSize = val.limit
}
// ç”Ÿå‘½å‘¨æœŸ
onMounted(() => {
  // ç»„件挂载后不立即初始化图表,等待用户切换到对应标签页
})
// ç›‘听标签页切换
watch(activeTab, (newVal) => {
  nextTick(() => {
    if (newVal === 'priceComparison') {
      initPriceChart()
    } else if (newVal === 'profitAnalysis') {
      initProfitChart()
    }
  })
})
const handleTabChange = () => {
  // æ ‡ç­¾é¡µåˆ‡æ¢å¤„理
}
</script>
<style scoped>
.strategy-control {
  padding: 0;
}
.main-tabs {
  border: none;
  box-shadow: none;
}
.main-tabs :deep(.el-tabs__content) {
  padding: 0;
}
.box-card {
  border: none;
  box-shadow: none;
}
.search-row {
  margin-bottom: 20px;
}
/* ç»Ÿè®¡å¡ç‰‡æ ·å¼ */
.stats-row {
  margin-bottom: 24px;
}
.stat-card {
  display: flex;
  align-items: center;
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.stat-icon {
  width: 60px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  margin-right: 16px;
}
.stat-content {
  flex: 1;
}
.stat-value {
  font-size: 28px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 4px;
}
.stat-label {
  font-size: 14px;
  color: #909399;
}
/* åˆåŒè¯¦æƒ…展开样式 */
.contract-detail-expand {
  padding: 30px 60px;
  background: #f5f7fa;
}
.contract-detail-expand :deep(.el-step__title) {
  font-size: 14px;
}
.contract-detail-expand :deep(.el-step__description) {
  font-size: 12px;
  margin-top: 4px;
}
/* åˆ©æ¶¦ç»Ÿè®¡å¡ç‰‡ */
.profit-stats-row {
  margin-bottom: 24px;
}
.profit-card {
  padding: 24px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  color: #fff;
  box-shadow: 0 4px 20px rgba(102, 126, 234, 0.4);
}
.profit-card:nth-child(2) .profit-card {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}
.profit-card:nth-child(3) .profit-card {
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
.profit-header {
  font-size: 14px;
  opacity: 0.9;
  margin-bottom: 12px;
}
.profit-value {
  font-size: 32px;
  font-weight: bold;
  margin-bottom: 12px;
}
.profit-highlight {
  color: #fff;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.profit-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 13px;
  opacity: 0.9;
}
.growth-up {
  color: #fff;
  font-weight: bold;
}
.growth-down {
  color: #ffd04b;
  font-weight: bold;
}
.cost-rate, .gross-profit-rate {
  font-weight: bold;
}
/* å›¾è¡¨å®¹å™¨ */
.chart-container {
  margin: 20px 0;
  padding: 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
</style>