Prechádzať zdrojové kódy

修改直播数据展示

yuhongqi 1 deň pred
rodič
commit
cf53587556
2 zmenil súbory, kde vykonal 633 pridanie a 1411 odobranie
  1. 7 0
      src/api/live/liveData.js
  2. 626 1411
      src/views/live/liveData/index.vue

+ 7 - 0
src/api/live/liveData.js

@@ -51,4 +51,11 @@ export function dashboardData(liveId) {
     method: 'get'
   })
 }
+export function listLiveData(data) {
+  return request({
+    url: '/liveData/liveData/listLiveData',
+    method: 'post',
+    data:data,
+  })
+}
 

+ 626 - 1411
src/views/live/liveData/index.vue

@@ -1,1444 +1,659 @@
 <template>
-  <div class="app-container">
-    <div class="title">近期直播</div>
-    <div class="live-container">
-      <div class="live-card" v-for="live in displayLives" :key="live.liveId">
-        <!-- 直播状态 -->
-        <div class="status" :class="getStatusClass(live.status)">
-          {{ getStatusText(live.status) }}
-        </div>
-        <!-- 直播信息 -->
-        <div class="content">
-          <img :src="live.liveImgUrl" alt="直播封面" class="cover-image" />
-          <div class="info">
-            <h3 class="live-title">{{ live.liveName }}</h3>
-            <p class="time">开播时间: {{ live.startTime }}</p>
+  <div class="el-container-md">
+    <!-- 数据统计指标展示区域 -->
+    <el-card class="statistics-card" shadow="never">
+      <el-row :gutter="20">
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">累计观看人数</div>
+            <div class="statistics-value">{{ statisticsData.totalViewers || 0 }}</div>
           </div>
-        </div>
-
-        <!-- 直播数据 -->
-        <div class="stats">
-          <div class="stat-item">
-            <p class="label">直播间浏览量</p>
-            <p class="value">{{ live.pageViews }}</p>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">
+              累计完课人数
+              <el-popover placement="top" width="200" trigger="click">
+                <div>
+                  <el-input-number v-model="completeWatchTime" :min="0" :precision="0" placeholder="看课时长(分钟)" style="width: 100%;"></el-input-number>
+                  <el-button type="primary" size="mini" style="width: 100%; margin-top: 10px;" @click="updateCompleteWatchTime('total')">确定</el-button>
+                </div>
+                <el-button slot="reference" size="mini" type="text" icon="el-icon-setting" style="margin-left: 5px;">设置</el-button>
+              </el-popover>
+            </div>
+            <div class="statistics-value">{{ statisticsData.totalCompletedCourses || 0 }}</div>
           </div>
-          <div class="stat-item">
-            <p class="label">直播间访客数</p>
-            <p class="value">{{ live.uniqueVisitors }}</p>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">直播观看人数</div>
+            <div class="statistics-value">{{ statisticsData.liveViewers || 0 }}</div>
           </div>
-        </div>
-      </div>
-    </div>
-    <!-- 直播趋势统计 -->
-    <div class="trend-section">
-      <div class="trend-header">
-        <h3>直播趋势</h3>
-        <div class="filter-container">
-        <!-- 时间范围选择(下拉框) -->
-          <span class="filter-label">时间筛选:</span>
-          <el-select v-model="selectedTimeRange" placeholder="选择时间范围" @change="changeTimeRange" style="width: 180px">
-            <el-option label="自然天" value="day"></el-option>
-            <el-option label="自然周" value="week"></el-option>
-            <el-option label="自然月" value="month"></el-option>
-          </el-select>
-
-          <!-- 日期选择器 -->
-          <!-- 选择日期 -->
-          <el-date-picker
-            ref="datePickerRef"
-            v-model="selectedDate"
-            :type="datePickerType"
-            :format="selectedTimeRange === 'week' ? weekRange : dateFormat"
-            :value-format="valueFormat"
-            placeholder="选择日期"
-            style="width: 280px"
-            @change="changeDate"
-            @blur="setDefaultDate"
-          />
-        </div>
-      </div>
-
-      <div class="trend-cards">
-        <div class="trend-card"
-             :class="{ 'active': selectedMetric === 'page_views' }"
-             @click="changeMetric('page_views')">
-          <p class="trend-title">
-            浏览量
-            <el-tooltip class="item" effect="dark" content="观看页面的总浏览量" placement="top">
-              <i class="el-icon-info"></i>
-            </el-tooltip>
-          </p>
-          <p class="trend-value">{{ trendData.views || 0 }}</p>
-          <p class="trend-tip">{{ changeLabel }}: {{ trendData.viewsChange }}%</p>
-
-        </div>
-
-        <div class="trend-card"
-             :class="{ 'active': selectedMetric === 'unique_visitors' }"
-             @click="changeMetric('unique_visitors')">
-          <p class="trend-title">
-            访客数
-            <el-tooltip class="item" effect="dark" content="进入直播间的访客数" placement="top">
-              <i class="el-icon-info"></i>
-            </el-tooltip>
-          </p>
-          <p class="trend-value">{{ trendData.visitors|| 0 }}</p>
-          <p class="trend-tip">{{ changeLabel }}: {{ trendData.visitorsChange }}%</p>
-
-        </div>
-
-        <div class="trend-card"
-             :class="{ 'active': selectedMetric === 'streams' }"
-             @click="changeMetric('streams')">
-          <p class="trend-title">
-            创建直播数
-            <el-tooltip class="item" effect="dark" content="创建的直播间数量" placement="top">
-              <i class="el-icon-info"></i>
-            </el-tooltip>
-          </p>
-          <p class="trend-value">{{ trendData.streams|| 0 }}</p>
-          <p class="trend-tip">{{ changeLabel }}: {{ trendData.streamsChange }}%</p>
-
-        </div>
-
-        <div class="trend-card"
-             :class="{ 'active': selectedMetric === 'total_views' }"
-             @click="changeMetric('total_views')">
-          <p class="trend-title">
-            累计观看人次
-            <el-tooltip class="item" effect="dark" content="直播间被观看的总人次" placement="top">
-              <i class="el-icon-info"></i>
-            </el-tooltip>
-          </p>
-          <p class="trend-value">{{ trendData.pv|| 0 }}</p>
-          <p class="trend-tip">{{ changeLabel }}: {{ trendData.pvChange }}%</p>
-
-        </div>
-
-        <div class="trend-card"
-             :class="{ 'active': selectedMetric === 'unique_viewers' }"
-             @click="changeMetric('unique_viewers')">
-          <p class="trend-title">
-            累计观看人数
-            <el-tooltip class="item" effect="dark" content="去重后的观看人数" placement="top">
-              <i class="el-icon-info"></i>
-            </el-tooltip>
-          </p>
-          <p class="trend-value">{{ trendData.uv|| 0 }}</p>
-          <p class="trend-tip">{{ changeLabel }}: {{ trendData.uvChange }}%</p>
-
-        </div>
-      </div>
-
-
-      <!-- 直播趋势折线图 -->
-      <div id="liveChart" class="chart"></div>
-    </div>
-    <!-- 直播TOP10排行榜 -->
-    <div class="top10-section">
-      <h3>直播TOP10排行榜</h3>
-      <div class="ranking-container">
-          <!-- 红榜 -->
-          <div class="ranking-section red-rank">
-            <span class="rank-title">红榜</span>
-            <div class="rank-filters">
-              <button
-                v-for="item in redRankTypes"
-                :key="item.value"
-                :class="{ active: selectedRank === item.value }"
-                @click="selectRank(item.value)"
-              >
-                {{ item.label }}
-              </button>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">
+              直播完课人数
+              <el-popover placement="top" width="200" trigger="click">
+                <div>
+                  <el-input-number v-model="liveCompleteWatchTime" :min="0" :precision="0" placeholder="看课时长(分钟)" style="width: 100%;"></el-input-number>
+                  <el-button type="primary" size="mini" style="width: 100%; margin-top: 10px;" @click="updateCompleteWatchTime('live')">确定</el-button>
+                </div>
+                <el-button slot="reference" size="mini" type="text" icon="el-icon-setting" style="margin-left: 5px;">设置</el-button>
+              </el-popover>
             </div>
+            <div class="statistics-value">{{ statisticsData.liveCompletedCourses || 0 }}</div>
           </div>
-
-          <!-- 黑榜 -->
-          <div class="ranking-section black-rank">
-            <div class="rank-filters">
-              <button
-                v-for="item in blackRankTypes"
-                :key="item.value"
-                :class="{ active: selectedRank === item.value }"
-                @click="selectRank(item.value)"
-              >
-                {{ item.label }}
-              </button>
-            </div>
-            <span class="rank-title">黑榜</span>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">回放观看人数</div>
+            <div class="statistics-value">{{ statisticsData.playbackViewers || 0 }}</div>
           </div>
-      </div>
-      <el-table :data="top10List" border style="width: 100%">
-        <el-table-column prop="rank" label="排名" width="80"></el-table-column>
-        <el-table-column prop="liveName" label="直播名称">
-          <template #default="scope">
-            <div class="live-name">
-              <img :src="scope.row.liveImgUrl" class="live-cover" alt="封面">
-              <span class="live-title">{{ scope.row.liveName }}</span>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">
+              回放完课人数
+              <el-popover placement="top" width="200" trigger="click">
+                <div>
+                  <el-input-number v-model="replayCompleteWatchTime" :min="0" :precision="0" placeholder="看课时长(分钟)" style="width: 100%;"></el-input-number>
+                  <el-button type="primary" size="mini" style="width: 100%; margin-top: 10px;" @click="updateCompleteWatchTime('replay')">确定</el-button>
+                </div>
+                <el-button slot="reference" size="mini" type="text" icon="el-icon-setting" style="margin-left: 5px;">设置</el-button>
+              </el-popover>
             </div>
-          </template>
-        </el-table-column>
-        <el-table-column prop="pageViews" label="直播间浏览量(PV)"></el-table-column>
-        <el-table-column prop="uniqueVisitors" label="直播间访客数(UV)"></el-table-column>
-        <el-table-column prop="totalViews" label="累计观看人次(PV)"></el-table-column>
-        <el-table-column prop="uniqueViewers" label="累计观看人数(UV)"></el-table-column>
-        <!--<el-table-column prop="avgTime" label="人均观看时长"></el-table-column>-->
-        <el-table-column prop="peakConcurrentViewers" label="最高在线人数"></el-table-column>
-      </el-table>
-
+            <div class="statistics-value">{{ statisticsData.playbackCompletedCourses || 0 }}</div>
+          </div>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20" style="margin-top: 20px;">
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">直播峰值</div>
+            <div class="statistics-value">{{ statisticsData.livePeak || 0 }}</div>
+          </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">直播平均时长</div>
+            <div class="statistics-value">{{ formatDuration(statisticsData.liveAvgDuration) }}</div>
+          </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">回放平均时长</div>
+            <div class="statistics-value">{{ formatDuration(statisticsData.playbackAvgDuration) }}</div>
+          </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">GMV</div>
+            <div class="statistics-value">¥{{ statisticsData.gmv || 0 }}</div>
+          </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">付费人数</div>
+            <div class="statistics-value">{{ statisticsData.paidUsers || 0 }}</div>
+          </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">付费单数</div>
+            <div class="statistics-value">{{ statisticsData.paidOrders || 0 }}</div>
+          </div>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20" style="margin-top: 20px;">
+        <el-col :span="4">
+          <div class="statistics-item">
+            <div class="statistics-title">销量统计</div>
+            <div class="statistics-value">{{ statisticsData.salesCount || 0 }}</div>
+          </div>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 筛选条件区域 -->
+    <el-form :model="queryParams" class="live-data-css" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px">
+      <el-form-item label="直播名称" prop="liveName">
+        <el-input
+          v-model="queryParams.liveName"
+          placeholder="请输入直播名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="观看类型" prop="watchType">
+        <el-select v-model="queryParams.watchType" placeholder="请选择观看类型" clearable size="small">
+          <el-option label="直播" value="live"></el-option>
+          <el-option label="回放" value="replay"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="完课状态" prop="completeStatus">
+        <el-select v-model="queryParams.completeStatus" placeholder="请选择完课状态" clearable size="small">
+          <el-option label="已完课" value="1"></el-option>
+          <el-option label="未完课" value="0"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="付费状态" prop="payStatus">
+        <el-select v-model="queryParams.payStatus" placeholder="请选择付费状态" clearable size="small">
+          <el-option label="已付费" value="1"></el-option>
+          <el-option label="未付费" value="0"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="观看时长" prop="watchDuration">
+        <el-input-number
+          v-model="queryParams.watchDuration"
+          :min="0"
+          :precision="0"
+          placeholder="观看时长(分钟)"
+          size="small"
+        ></el-input-number>
+      </el-form-item>
+      <el-form-item label="时间范围" prop="dateRange">
+        <el-date-picker
+          v-model="dateRange"
+          type="datetimerange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          size="small"
+          value-format="yyyy-MM-dd HH:mm:ss"
+        ></el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作工具栏 -->
+    <div class="selection-toolbar">
+      <el-checkbox :indeterminate="isIndeterminate" v-model="allChecked" @change="toggleSelectAll">
+        {{ multipleSelection.length > 0 ? `已选 ${multipleSelection.length} 条` : '选中本页' }}
+      </el-checkbox>
+<!--      <el-button plain size="mini" @click="handleAutoTag">自动打标签</el-button>-->
+<!--      <el-button plain size="mini" @click="handleAutoRemark">自动备注</el-button>-->
+      <el-button plain type="primary" size="mini" icon="el-icon-download" :loading="exportLoading" @click="handleExport">导出</el-button>
     </div>
-<!--    <div class="student-section">-->
-<!--      <h3>直播间学员</h3>-->
-<!--        <el-form :inline="true" v-show="showAdvancedSearch" label-width="100px">-->
-<!--          &lt;!&ndash; 直播列表弹框 &ndash;&gt;-->
-<!--          <el-dialog title="选择直播" :visible.sync="dialogVisible" width="70%">-->
-<!--            <el-row :gutter="20">-->
-<!--              <el-col :span="8" :sm="12" :md="8">-->
-<!--                <el-form-item label="直播名称:">-->
-<!--                  <el-input v-model="liveFiltersParam.liveName" placeholder="请输入直播名称"></el-input>-->
-<!--                </el-form-item>-->
-<!--              </el-col>-->
-<!--              <el-col :span="8" :sm="12" :md="8">-->
-<!--                <el-form-item label="直播状态:">-->
-<!--                  <el-select v-model="liveFiltersParam.status" placeholder="请选择直播状态" clearable>-->
-<!--                    <el-option label="全部" value=""></el-option>-->
-<!--                    <el-option label="已结束" value="3"></el-option>-->
-<!--                    <el-option label="进行中" value="2"></el-option>-->
-<!--                    <el-option label="未开始" value="1"></el-option>-->
-<!--                  </el-select>-->
-<!--                </el-form-item>-->
-<!--              </el-col>-->
-<!--              <el-col :span="8" :sm="12" :md="8">-->
-<!--                <el-form-item label="直播时间:">-->
-<!--                  <el-date-picker-->
-<!--                    v-model="liveDateRange"-->
-<!--                    type="daterange"-->
-<!--                    value-format="yyyy-MM-dd"-->
-<!--                    range-separator="至"-->
-<!--                    start-placeholder="开始日期"-->
-<!--                    end-placeholder="结束日期"-->
-<!--                    clearable-->
-<!--                    style="width: 250px"-->
-<!--                    @change="handleLiveDateChange"-->
-<!--                  ></el-date-picker>-->
-<!--                </el-form-item>-->
-<!--              </el-col>-->
-<!--              &lt;!&ndash; 查询 & 重置 按钮 &ndash;&gt;-->
-<!--              <el-col :span="4" class="button-group">-->
-<!--                <el-button type="primary" @click="getLive">查询</el-button>-->
-<!--                <el-button @click="resetLiveFilters">重置</el-button>-->
-<!--              </el-col>-->
-<!--            </el-row>-->
 
-<!--            &lt;!&ndash; 直播列表 &ndash;&gt;-->
-<!--            <el-table :data="liveList" border @selection-change="handleSelectionChange">-->
-<!--              <el-table-column type="selection" width="50" align="center" />-->
-<!--              &lt;!&ndash; 直播信息列 &ndash;&gt;-->
-<!--              <el-table-column label="直播名称" min-width="250">-->
-<!--                <template slot-scope="{ row }">-->
-<!--                  <div class="live-info">-->
-<!--                    &lt;!&ndash; 直播封面图 &ndash;&gt;-->
-<!--                    <img :src="row.liveImgUrl" class="live-cover" />-->
-<!--                    &lt;!&ndash; 直播名称 + 时间 &ndash;&gt;-->
-<!--                    <div class="live-text">-->
-<!--                      <div type="text"class="live-name">{{ row.liveName }}</div>-->
-<!--                      <div class="live-time">{{ row.startTime }}-{{row.finishTime}}</div>-->
-<!--                    </div>-->
-<!--                  </div>-->
-<!--                </template>-->
-<!--              </el-table-column>-->
-
-<!--              &lt;!&ndash; 直播状态 &ndash;&gt;-->
-<!--              <el-table-column label="直播状态" min-width="120">-->
-<!--                <template slot-scope="{ row }">-->
-<!--                  <div class="status-container">-->
-<!--                    <span :class="['status-dot', getStatusClass(row.status)]"></span>-->
-<!--                    <span>{{ getStatusText(row.status) }}</span>-->
-<!--                  </div>-->
-<!--                </template>-->
-<!--              </el-table-column>-->
-
-<!--              &lt;!&ndash; 讲师 &ndash;&gt;-->
-<!--              <el-table-column label="讲师" prop="teacher" min-width="120"></el-table-column>-->
-<!--            </el-table>-->
-<!--            <pagination-->
-<!--              v-show="liveTotal>0"-->
-<!--              :total="liveTotal"-->
-<!--              :page.sync="liveFiltersParam.pageNum"-->
-<!--              :limit.sync="liveFiltersParam.pageSize"-->
-<!--              @pagination="getLive"-->
-<!--            />-->
-<!--            &lt;!&ndash; 确认按钮 &ndash;&gt;-->
-<!--            <span slot="footer" class="dialog-footer">-->
-<!--              <el-button @click="dialogVisible = false">取消</el-button>-->
-<!--              <el-button type="primary" @click="confirmSelection">确认</el-button>-->
-<!--            </span>-->
-<!--          </el-dialog>-->
-<!--          &lt;!&ndash; 基础筛选项:始终显示 &ndash;&gt;-->
-<!--          <el-row :gutter="20">-->
-<!--            <el-col :span="8" :sm="12" :md="8">-->
-<!--              <el-form-item label="直播名称:" class="el-form-item-ellipsis">-->
-<!--                <el-input-->
-<!--                  v-model="filters.liveName"-->
-<!--                  placeholder="请选择直播"-->
-<!--                  @focus="openDialog"-->
-<!--                  type="text"-->
-<!--                  readonly-->
-<!--                >-->
-<!--                  <template slot="prepend">-->
-<!--                    <div v-if="filters.liveNames.length > 0" class="selected-lives">-->
-<!--                      <el-tag-->
-<!--                        v-for="(name, index) in filters.liveNames"-->
-<!--                        :key="index"-->
-<!--                        closable-->
-<!--                        @close="removeLive(index)"-->
-<!--                        class="live-name-tag"-->
-<!--                      >-->
-<!--                        {{ name }}-->
-<!--                      </el-tag>-->
-<!--                    </div>-->
-<!--                  </template>-->
-<!--                </el-input>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--            <el-col :span="8" :sm="12" :md="8">-->
-<!--              <el-form-item label="用户名:" class="el-form-item-ellipsis">-->
-<!--                <el-input v-model="filters.userName" placeholder="请输入用户名"></el-input>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--            <el-col :span="8" :sm="12" :md="8">-->
-<!--              <el-form-item label="手机号:" class="el-form-item-ellipsis">-->
-<!--                <el-input v-model="filters.userPhone" placeholder="请输入手机号"></el-input>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-<!--          &lt;!&ndash; 高级筛选项 &ndash;&gt;-->
-<!--          <el-row :gutter="24" v-show="showAllFilters">-->
-<!--            <el-col :span="8" :sm="12" :md="8" >-->
-<!--              <el-form-item label="用户创建时间:">-->
-<!--                <el-date-picker-->
-<!--                  v-model="dateRange"-->
-<!--                  type="daterange"-->
-<!--                  range-separator="至"-->
-<!--                  start-placeholder="开始日期"-->
-<!--                  end-placeholder="结束日期"-->
-<!--                  value-format="yyyy-MM-dd"-->
-<!--                  @change="handleDateChange"-->
-<!--                  class="full-width-picker"-->
-<!--                />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--            <el-col :span="8" :sm="12" :md="8">-->
-<!--              <el-form-item label="分享次数:" class="el-form-item-ellipsis">-->
-<!--                <el-input v-model="filters.shareCount" placeholder="请输入分享次数"></el-input>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--            <el-col :span="8" :sm="12" :md="8">-->
-<!--              <el-form-item label="所属部门:" prop="deptId">-->
-<!--                <treeselect style="width:220px" v-model="filters.deptId" :options="deptOptions" :show-count="true" placeholder="请选择所属部门" />-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-<!--          <el-row :gutter="20" v-show="showAllFilters">-->
-<!--            <el-col :span="8" :sm="12" :md="8"> &lt;!&ndash; 每列 span 总和控制在 24 内 &ndash;&gt;-->
-<!--              <el-form-item label="跟进人:" class="el-form-item-ellipsis">-->
-<!--                <el-input v-model="filters.companyUserName" placeholder="请输入跟进人"></el-input>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--            <el-col :span="8" :sm="12" :md="8">-->
-<!--              <el-form-item label="购买商品数:" class="el-form-item-ellipsis">-->
-<!--                <el-input v-model="filters.goodsCount" placeholder="请输入购买商品数"></el-input>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--            <el-col :span="8" :sm="12" :md="8">-->
-<!--              <el-form-item label="提问数:" class="flex-container">-->
-<!--                <el-row>-->
-<!--                  <el-col :span="8" :sm="12" :md="8">-->
-<!--                    <el-input-number v-model="filters.minQuestionCount" placeholder="最小提问数" :min="0" style="width: 100%"></el-input-number>-->
-<!--                  </el-col>-->
-<!--                  <el-col :span="2" class="text-center">至</el-col>-->
-<!--                  <el-col :span="8" :sm="12" :md="8">-->
-<!--                    <el-input-number v-model="filters.maxQuestionCount" placeholder="最大提问数" :min="0" style="width: 100%"></el-input-number>-->
-<!--                  </el-col>-->
-<!--                </el-row>-->
-<!--              </el-form-item>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-
-<!--          &lt;!&ndash; 按钮组:始终显示 &ndash;&gt;-->
-<!--          <el-row>-->
-<!--            <el-col :span="24" class="button-group">-->
-<!--              <el-button type="primary" @click="getStudentData" class="custom-button">查询</el-button>-->
-<!--              <el-button @click="resetFilters" class="custom-button">重置</el-button>-->
-<!--              <el-button type="text" @click="toggleAllFilters" class="custom-button toggle-button">-->
-<!--                {{ showAllFilters ? '收起' : '展开' }}-->
-<!--                <i :class="showAllFilters ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>-->
-<!--              </el-button>-->
-<!--            </el-col>-->
-<!--          </el-row>-->
-<!--        </el-form>-->
-<!--      &lt;!&ndash;<div class="column-button-container">-->
-<!--        <el-button-->
-<!--          type="primary"-->
-<!--          @click="showColumnSettings = true"-->
-<!--          class="custom-column-button"-->
-<!--        >-->
-<!--          自定义列-->
-<!--        </el-button>-->
-<!--      </div>&ndash;&gt;-->
-<!--      &lt;!&ndash; 自定义列弹窗 &ndash;&gt;-->
-<!--      <el-drawer-->
-<!--        title="自定义列设置"-->
-<!--        :visible.sync="showColumnSettings"-->
-<!--        :before-close="handleClose"-->
-<!--        size="25%"-->
-<!--      >-->
-<!--        &lt;!&ndash; 抽屉内容区域 &ndash;&gt;-->
-<!--        &lt;!&ndash;<div style="display: flex; flex-direction: column; height: 100%;">-->
-<!--          &lt;!&ndash; 可拖拽的列设置区域 &ndash;&gt;-->
-<!--          <draggable-->
-<!--            v-model="columnOrder"-->
-<!--            group="columns"-->
-<!--            style="flex: 1; overflow-y: auto;"-->
-<!--          >-->
-<!--            <div v-for="col in columnOrder" :key="col.dataIndex" class="column-item">-->
-<!--              <el-checkbox v-model="col.status" true-label="ENABLE" false-label="DISABLE">-->
-<!--                {{ col.title }}-->
-<!--              </el-checkbox>-->
-<!--              <i class="el-icon-rank drag-handle"></i>-->
-<!--            </div>-->
-<!--          </draggable>-->
-
-<!--          &lt;!&ndash; 底部按钮区域 &ndash;&gt;-->
-<!--          <div style="padding: 12px; text-align: right; border-top: 2px solid;">-->
-<!--            <el-button @click="showColumnSettings = false" style="color: black;">取消</el-button>-->
-<!--            <el-button-->
-<!--              type="primary"-->
-<!--              @click="saveColumnsConfig"-->
-<!--              style="color: black; background-color: #409EFF; border-color: #409EFF;"-->
-<!--            >-->
-<!--              确定-->
-<!--            </el-button>-->
-<!--          </div>-->
-<!--        </div>&ndash;&gt;-->
-<!--      </el-drawer>-->
-
-
-<!--      <div style="overflow-x: auto; white-space: nowrap;">-->
-<!--        <el-table :data="liveStudentList" border style="min-width: 1200px;">-->
-<!--          &lt;!&ndash; 固定列,内容不换行 &ndash;&gt;-->
-<!--          <el-table-column prop="userName" label="客户名" fixed :style="{whiteSpace: 'nowrap',textOverflow: 'ellipsis',overflow: 'hidden',textAlign: 'center'}"></el-table-column>-->
-<!--          <el-table-column prop="liveName" label="直播间" fixed :show-overflow-tooltip="true" width=151px :min-width="'直播间'.length * 12 + 30":style="{whiteSpace: 'nowrap',textOverflow: 'ellipsis',overflow: 'hidden',textAlign: 'center'}"></el-table-column>-->
-<!--          <el-table-column prop="companyUserName" label="跟进人" fixed class="no-wrap-column"></el-table-column>-->
-<!--          <el-table-column prop="deptName" label="归属部门" width="150" show-overflow-tooltip/>-->
-<!--          <el-table-column prop="userCreateTime" label="客户创建时间" width="150" show-overflow-tooltip/>-->
-<!--          <el-table-column prop="userPhone" label="联系方式" width="150" show-overflow-tooltip/>-->
-<!--          <el-table-column prop="goodsCount" label="去下单实物商品" width="150" show-overflow-tooltip/>-->
-<!--          <el-table-column prop="shareCount" label="分享直播间次数" width="150" show-overflow-tooltip/>-->
-<!--          <el-table-column prop="questionCount" label="答题次数" width="150" show-overflow-tooltip/>-->
-
-<!--          &lt;!&ndash; 动态列 &ndash;&gt;-->
-<!--          &lt;!&ndash;<el-table-column-->
-<!--            v-for="col in filteredColumns"-->
-<!--            :key="col.dataIndex"-->
-<!--            :prop="col.dataIndex"-->
-<!--            :label="col.title"-->
-<!--            :width="col.width"-->
-<!--            :min-width="col.title.length * 12 + 30"-->
-<!--            :show-overflow-tooltip="true">-->
-<!--          </el-table-column>&ndash;&gt;-->
-
-<!--        </el-table>-->
-<!--        <pagination-->
-<!--          v-show="liveStudentTotal>0"-->
-<!--          :total="liveStudentTotal"-->
-<!--          :page.sync="filters.pageNum"-->
-<!--          :limit.sync="filters.pageSize"-->
-<!--          @pagination="getStudentData"-->
-<!--        />-->
-<!--      </div>-->
-<!--    </div>-->
+    <!-- 数据表格 -->
+    <el-table
+      ref="dataTable"
+      :data="dataList"
+      style="width: 100%"
+      v-loading="loading"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column type="index" label="序号" width="55" align="center"></el-table-column>
+      <el-table-column prop="liveName" label="直播间名称" min-width="160" show-overflow-tooltip></el-table-column>
+      <el-table-column prop="liveType" label="直播类型" width="100" align="center">
+        <template slot-scope="scope">
+          <el-tag type="danger" v-if="scope.row.liveType == 1">直播</el-tag>
+          <el-tag type="success" v-else-if="scope.row.liveType == 2">录播</el-tag>
+          <el-tag v-else-if="scope.row.liveType == 3">直播回放</el-tag>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="status" label="状态" width="100" align="center">
+        <template slot-scope="scope">
+          <el-tag type="info" v-if="scope.row.status == 1">未开始</el-tag>
+          <el-tag type="warning" v-else-if="scope.row.status == 2">进行中</el-tag>
+          <el-tag type="success" v-else-if="scope.row.status == 3">已结束</el-tag>
+          <span v-else>-</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="startTime" label="开始时间" width="180" align="center"></el-table-column>
+      <el-table-column prop="finishTime" label="结束时间" width="180" align="center"></el-table-column>
+      <el-table-column prop="totalViewers" label="累计观看" width="110" align="center"></el-table-column>
+      <el-table-column prop="liveViewers" label="直播观看" width="110" align="center"></el-table-column>
+      <el-table-column prop="playbackViewers" label="回放观看" width="110" align="center"></el-table-column>
+      <el-table-column prop="liveAvgDuration" label="直播平均时长" width="140" align="center">
+        <template slot-scope="scope">{{ formatDuration(scope.row.liveAvgDuration) }}</template>
+      </el-table-column>
+      <el-table-column prop="playbackAvgDuration" label="回放平均时长" width="140" align="center">
+        <template slot-scope="scope">{{ formatDuration(scope.row.playbackAvgDuration) }}</template>
+      </el-table-column>
+      <el-table-column prop="totalCompletedCourses" label="累计完课" width="110" align="center"></el-table-column>
+      <el-table-column prop="liveCompletedCourses" label="直播完课" width="110" align="center"></el-table-column>
+      <el-table-column prop="playbackCompletedCourses" label="回放完课" width="110" align="center"></el-table-column>
+      <el-table-column prop="gmv" label="GMV" width="120" align="center">
+        <template slot-scope="scope">¥{{ scope.row.gmv || 0 }}</template>
+      </el-table-column>
+      <el-table-column prop="paidUsers" label="付费人数" width="100" align="center"></el-table-column>
+      <el-table-column prop="paidOrders" label="付费单数" width="100" align="center"></el-table-column>
+      <el-table-column prop="salesCount" label="销量统计" width="100" align="center"></el-table-column>
+      <el-table-column label="操作" width="120" fixed="right">
+        <template slot-scope="scope">
+          <el-button type="text" size="small" @click="handleViewDetail(scope.row)">查看详情</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页组件 -->
+    <pagination
+      v-show="total > 0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+      style="margin-top: 20px;"
+    />
+
+    <!-- 自动打标签弹窗 -->
+    <el-dialog
+      title="自动打标签"
+      :visible.sync="tagDialogVisible"
+      width="600px"
+      :close-on-click-modal="false"
+    >
+      <el-form :model="tagForm" label-width="120px">
+        <el-form-item label="打标签规则">
+          <el-checkbox-group v-model="tagForm.rules">
+            <el-checkbox label="liveComplete">直播完课</el-checkbox>
+            <el-checkbox label="replayComplete">回放完课</el-checkbox>
+            <el-checkbox label="pay">付费行为</el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+        <el-form-item label="标签名称">
+          <el-input v-model="tagForm.tagName" placeholder="请输入标签名称"></el-input>
+        </el-form-item>
+        <el-form-item label="备注格式">
+          <el-radio-group v-model="tagForm.remarkFormat">
+            <el-radio label="time">时间—行为(如:2024-01-01—直播完课)</el-radio>
+            <el-radio label="simple">仅行为(如:直播完课)</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="tagDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="confirmAutoTag">确 定</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 自动备注弹窗 -->
+    <el-dialog
+      title="自动备注"
+      :visible.sync="remarkDialogVisible"
+      width="600px"
+      :close-on-click-modal="false"
+    >
+      <el-form :model="remarkForm" label-width="120px">
+        <el-form-item label="备注规则">
+          <el-checkbox-group v-model="remarkForm.rules">
+            <el-checkbox label="liveComplete">直播完课</el-checkbox>
+            <el-checkbox label="replayComplete">回放完课</el-checkbox>
+            <el-checkbox label="pay">付费行为</el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+        <el-form-item label="备注格式">
+          <el-radio-group v-model="remarkForm.remarkFormat">
+            <el-radio label="time">时间—行为(如:2024-01-01—直播完课)</el-radio>
+            <el-radio label="simple">仅行为(如:直播完课)</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="备注位置">
+          <el-radio-group v-model="remarkForm.position">
+            <el-radio :label="1">添加在最前面</el-radio>
+            <el-radio :label="2">添加在最后面</el-radio>
+            <el-radio :label="3">替换所有备注</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="remarkDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="confirmAutoRemark">确 定</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
-
 <script>
-  import * as echarts from "echarts";
-  import Editor from '@/components/Editor/wang';
-  import {recentLive,liveTop,getTrendData,columns,updateColumns,queryStudentData} from "@/api/live/liveData";
-  import {selectLiveToStudent} from "@/api/live/live";
-  import { treeselect } from "@/api/company/companyDept";
-  import Treeselect from "@riophae/vue-treeselect";
-  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
-  import draggable from "vuedraggable";
-  export default {
-
-    name: "LiveData",
-    components: { Editor,draggable,Treeselect },
-    data() {
-      return {
-        // 部门树选项
-        deptOptions: [],
-        liveDateRange:"",
-        liveFiltersParam:{
-          liveName:"",
-          status:"",
-          startTime:"",
-          finishTime:"",
-          pageNum: 1,
-          pageSize: 10,
-        },
-        liveList: [],
-        dialogVisible: false,
-        span:8,
-        showAllFilters: true, // 默认收起
-        showAdvancedSearch: true, // 控制表单的显示
-        // 直播间总条数
-        liveTotal: 0,
-        //学员数据总条数
-        liveStudentTotal:0,
-        dateRange: [],//存选择的日期范围
-        filters: {
-          minQuestionCount: 0,  // 大于提问数
-          maxQuestionCount: 0,  // 小于提问数
-          liveNames: [],  // 存放已选的直播名称
-          liveIds: [],
-          liveName: '',
-          userName: '',
-          userPhone: '',
-          userCreateTime: '',
-          startTime: '', // 开始时间
-          finishTime: '',
-          shareCount: '',
-          deptName: '',
-          deptId:null,
-          companyUserName: '',
-          goodsCount: '',
-          questionCount: '',
-          pageNum: 1,
-          pageSize: 2
-        },
-        selectedLives: [], // 临时存储选中的直播数据
-        showColumnSettings: false, // 控制自定义列弹窗
-        columnOrder: [],
-        tempOrderedColumns : [],  // 用于渲染表格的列顺序
-        selectedColumns: [],  // 用于控制哪些列被选中
-        liveStudentList:[],
-        top10List: [],
-        selectedRank: 'highFlow',
-        redRankTypes: [
-          { label: '高流量', value: 'highFlow' },
-          { label: '高观看', value: 'highView' },
-          /*{ label: '高时长', value: 'highTime' },*/
-        ],
-        blackRankTypes: [
-          { label: '低观看', value: 'lowView' },
-          { label: '低流量', value: 'lowFlow' },
-        ],
-        selectedTimeRange: 'day',  // 默认选择自然天
-        selectedDate: null,  // 用户选择的日期
-        datePickerType: 'date',  // 默认日期选择类型
-        weekRange: 'yyyy-ww',  // 周选择的日期格式
-        queryParams: {
-          type: 'day',  // 用来存储时间筛选方式(如 day, week, month)
-          date: new Date().toISOString().split("T")[0],  // 用来存储用户选择的日期默认今天
-          category:"page_views"
-        },
-        chart: null,
-        trendData: {}, // 直播趋势数据
-        selectedMetric: "page_views", // 默认选中浏览量
-        lives: [],
-      };
+import { listLiveData, exportLiveData, autoTagAndRemark, dashboardData } from "@/api/live/liveData";
+import { batchUpdateExternalContactNotes } from "@/api/qw/externalContact";
+import { addTag } from "@/api/qw/externalContact";
+
+export default {
+  name: "LiveData",
+  data() {
+    return {
+      liveId: '',
+      loading: true,
+      exportLoading: false,
+      showSearch: true,
+      dataList: [],
+      total: 0,
+      multipleSelection: [],
+      allChecked: false,
+      isIndeterminate: false,
+      dateRange: [],
+      // 统计数据
+      statisticsData: {
+        gmv: 0,
+        liveAvgDuration: 0,
+        liveCompletedCourses: 0,
+        livePeak: 0,
+        liveViewers: 0,
+        paidOrders: 0,
+        paidUsers: 0,
+        playbackAvgDuration: 0,
+        playbackCompletedCourses: 0,
+        playbackViewers: 0,
+        salesCount: 0,
+        totalCompletedCourses: 0,
+        totalViewers: 1
+      },
+      // 完课时长设置
+      completeWatchTime: 0,
+      liveCompleteWatchTime: 0,
+      replayCompleteWatchTime: 0,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        liveId: null,
+        liveName: null,
+        watchType: null,
+        completeStatus: null,
+        payStatus: null,
+        watchDuration: null,
+        startTime: null,
+        endTime: null
+      },
+      // 打标签弹窗
+      tagDialogVisible: false,
+      tagForm: {
+        rules: [],
+        tagName: '',
+        remarkFormat: 'time'
+      },
+      // 备注弹窗
+      remarkDialogVisible: false,
+      remarkForm: {
+        rules: [],
+        remarkFormat: 'time',
+        position: 1
+      }
+    };
+  },
+  created() {
+    this.liveId = this.$route.query.liveId;
+    this.queryParams.liveId = this.liveId;
+
+    this.getList();
+  },
+  methods: {
+    /** 获取统计数据 */
+    getStatistics() {
+      if (!this.liveId) return;
+      dashboardData(this.liveId).then(response => {
+        if (response.code === 200) {
+          this.statisticsData = response.data || {};
+        }
+      });
     },
-    computed: {
-
-      filteredColumns() {
-        return this.columnOrder.filter(col => col.status === "ENABLE");
-      },
-      changeLabel() {
-        switch (this.selectedTimeRange) {
-          case 'day': return '比前一天';
-          case 'week': return '比上周';
-          case 'month': return '比上月';
-          default: return '变化';
+    /** 获取列表数据 */
+    getList() {
+      this.loading = true;
+      // 处理时间范围
+      if (this.dateRange && this.dateRange.length === 2) {
+        this.queryParams.startTime = this.dateRange[0];
+        this.queryParams.endTime = this.dateRange[1];
+      } else {
+        this.queryParams.startTime = null;
+        this.queryParams.endTime = null;
+      }
+      listLiveData(this.queryParams).then(response => {
+        if (response.code === 200) {
+          this.statisticsData = response.data || {};
+          this.dataList = response.list || [];
+          this.total = response.total || 0;
         }
-      },
-      displayLives() {
-        return this.lives.slice(0, 4); // 最多只显示前 4 条数据
-      },
-
-      dateFormat() {
-        return this.selectedTimeRange === "day"
-          ? "yyyy-MM-dd"
-          : this.selectedTimeRange === "week"
-            ? "yyyy-MM-dd 至 yyyy-MM-dd"
-            : "yyyy-MM-dd";
-      },
-      valueFormat() {
-        return this.selectedTimeRange === "day"
-          ? "yyyy-MM-dd"
-          : this.selectedTimeRange === "week"
-            ? "yyyy-MM-dd"
-            : "yyyy-MM-dd";
-      },
+        this.loading = false;
+      }).catch(() => {
+        this.loading = false;
+      });
     },
-    created() {
-      this.getRecentLive();
-      this.getLiveTop();
-      this.getTrendData();
-      //this.getColumns();
-      this.getTreeselect();
-
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
     },
-    mounted() {
-      this.selectedColumns = this.columnOrder.map((col) => col.prop); // 默认全选
-      this.selectedMetric = this.trendData[0]; // 默认选中第一个
-      this.initChart(); // 初始化折线图
-      if (!this.selectedMetric) {
-        this.selectedMetric = "page_views";
-      };
-      this.updateChart();
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.dateRange = [];
+      this.$refs.queryForm.resetFields();
+      this.handleQuery();
     },
-    watch: {
-      // 如果 columnOrder 更新,确保 orderedColumns 跟随更新
-      columnOrder(newOrder) {
-        this.tempOrderedColumns = [...newOrder];
-      },
+    /** 全选或取消全选 */
+    toggleSelectAll(val) {
+      if (val) {
+        this.toggleSelection(this.dataList);
+      } else {
+        this.toggleSelection();
+      }
     },
-
-    methods: {
-      handleLiveDateChange(value) {
-        if (value) {
-          this.liveFiltersParam.startTime = value[0];
-          this.liveFiltersParam.finishTime = value[1];
-        } else {
-          this.liveFiltersParam.startTime = null;
-          this.liveFiltersParam.finishTime = null;
-        }
-        console.log("直播时间范围:", this.liveFiltersParam.startTime, this.liveFiltersParam.finishTime);
-      },
-      handleDateChange(value) {
-        if (value) {
-          this.filters.startTime = value[0];
-          this.filters.finishTime = value[1];
-        } else {
-          this.filters.startTime = '';
-          this.filters.finishTime = '';
-        }
-        console.log("用户创建时间范围:", this.filters.startTime, this.filters.finishTime);
-      },
-      getTreeselect() {
-        treeselect().then((response) => {
-          this.deptOptions = response.data;
-          console.log(this.deptOptions)
+    toggleSelection(rows) {
+      if (rows) {
+        rows.forEach(row => {
+          this.$refs.dataTable.toggleRowSelection(row);
         });
-      },
-      getLive(){
-        selectLiveToStudent(this.liveFiltersParam).then(response => {
-          this.liveList = response.rows;
-          this.liveTotal = response.total;
-        });
-      },
-      resetLiveFilters(){
-        this.liveDateRange="",
-        this.liveFiltersParam = {
-          liveName:"",
-          status:"",
-          startTime:"",
-          finishTime:""
-        }
-      },
-      // 确认选择
-      confirmSelection() {
-        this.filters.liveNames = this.selectedLives.map(item => item.liveName);
-        this.filters.liveIds = this.selectedLives.map(item => item.liveId);
-        console.log(this.filters.liveIds)
-        this.dialogVisible = false; // 关闭弹框
-      },
-      // 移除已选直播
-      removeLive(index) {
-        this.filters.liveNames.splice(index, 1);
-        this.filters.liveIds.splice(index, 1);
-      },
-      // 处理表格选中
-      handleSelectionChange(selectedRows) {
-        this.selectedLives = selectedRows; // 存储选中的直播数据
-      },
-
-      openDialog() {
-        this.getLive();
-        this.dialogVisible = true;
-      },
-      toggleAllFilters() {
-        this.showAllFilters = !this.showAllFilters;
-      },
-      getStudentData() {
-        console.log("查询条件:", this.filters);
-        queryStudentData(this.filters).then(response => {
-          console.log(response)
-          this.liveStudentList = response.rows;
-          this.liveStudentTotal = response.total;
-          console.log(response.total)
-        });
-      },
-      resetFilters() {
-        this.filters = {
-          liveName: "",
-          liveNames:[],
-          liveIds:[],
-          phoneNumber: "",
-          wechatNickname: "",
-          customerId: "",
-          visitTime: [],
-          isWinner: "",
-          department: "",
-          customerTag: "",
-        };
-      },
-      handleClose(done) {
-        this.$confirm('确认关闭?')
-          .then(_ => {
-            done();
-          })
-          .catch(_ => {});
-      },
-      saveColumnsConfig() {
-        this.tempOrderedColumns = [...this.columnOrder];  // 更新 orderedColumns
-        console.log(this.tempOrderedColumns)
-        updateColumns(this.tempOrderedColumns).then(response=>{
-          //this.getColumns()
-          location.reload()
-          this.showColumnSettings = false;
-        })
-      },
-      /*getColumns(){
-        this.loading = true;
-        columns().then(response => {
-          this.columnOrder = response.data;
-          this.selectedColumns = response.data.map((col) => col.prop);
-          console.log(this.columnOrder)
-          this.loading = false;
-        });
-      },*/
-      getTrendData(){
-        getTrendData(this.queryParams).then(response=>{
-          this.trendData = response.data
-          this.updateChart()
-        })
-      },
-      // 更新折线图
-      getMetricTitle(metricKey) {
-        const titles = {
-          page_views: "浏览量",
-          unique_visitors: "访客数",
-          streams: "创建直播数",
-          total_views: "累计观看人次",
-          unique_viewers: "累计观看人数"
-        };
-        return titles [metricKey] || "未知指标";
-      },
-
-      // 点击卡片切换指标
-      changeMetric(metric) {
-        this.selectedMetric = metric;
-        // 更新 queryParams 中的 category
-        this.queryParams.category = metric;  // 默认值为 prevViews
-        this.updateChart();  // 更新图表
-        this.getTrendData();  // 重新请求数据
-      },
-      getLiveTop() {
-
-        liveTop({ rankType: this.selectedRank })
-          .then(response => {
-
-            if (response.data) {
-              // 遍历数据并添加排名字段
-              this.top10List = response.data.map((item, index) => ({
-                ...item,
-                rank: index + 1 // 排名从 1 开始
-              }));
-            } else {
-              this.top10List = [];
-            }
-          })
-          .catch(error => {
-          });
-      },
-      getStatusText(status) {
-        if (status === 1) return "待直播";
-        if (status === 2) return "直播中";
-        return "已结束";
-      },
-      getStatusClass(status) {
-        if (status === 1) return "status-upcoming";
-        if (status === 2) return "status-live";
-        return "status-ended";
-      },
-      getRecentLive(){
-        this.loading = true;
-        recentLive().then(response => {
-          this.lives = response.data;
-          this.loading = false;
-        });
-      },
-
-      getWeekRange(selectedWeek) {
-        let date = new Date(selectedWeek);
-
-        if (isNaN(date.getTime())) {
-          return "日期错误";
+      } else {
+        this.$refs.dataTable.clearSelection();
+      }
+    },
+    /** 多选框选中数据 */
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+      this.allChecked = val.length === this.dataList.length;
+      this.isIndeterminate = val.length > 0 && val.length < this.dataList.length;
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      if (this.dateRange && this.dateRange.length === 2) {
+        this.queryParams.startTime = this.dateRange[0];
+        this.queryParams.endTime = this.dateRange[1];
+      } else {
+        this.queryParams.startTime = null;
+        this.queryParams.endTime = null;
+      }
+      this.$confirm('是否确认导出所有直播数据?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.exportLoading = true;
+        return exportLiveData(this.queryParams);
+      }).then(response => {
+        if (response.code === 200) {
+          this.download(response.msg);
         }
-
-        let dayOfWeek = date.getDay(); // 0(星期天)- 6(星期六)
-
-        // 计算周一
-        let startDate = new Date(date); // 创建一个新的 Date 实例
-        startDate.setDate(date.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1));
-
-        // 计算周日(确保 `endDate` 是新实例)
-        let endDate = new Date(startDate.getTime()); // 复制 `startDate`
-        endDate.setDate(startDate.getDate() + 6);
-
-
-        return `${this.formatDate(startDate)} 至 ${this.formatDate(endDate)}`;
-      },
-      changeDate(value) {
-        if (this.selectedTimeRange === 'week' && value) {
-          this.weekRange = this.getWeekRange(value);
-          console.log("周"+this.weekRange)
-        } else {
-          this.weekRange = '';  // 非周选择时清空周范围
+        this.exportLoading = false;
+      }).catch(() => {
+        this.exportLoading = false;
+      });
+    },
+    /** 自动打标签 */
+    // handleAutoTag() {
+    //   if (this.multipleSelection.length === 0) {
+    //     this.$message.warning('请选择要打标签的数据');
+    //     return;
+    //   }
+    //   this.tagDialogVisible = true;
+    // },
+    /** 确认自动打标签 */
+    confirmAutoTag() {
+      if (this.tagForm.rules.length === 0) {
+        this.$message.warning('请选择打标签规则');
+        return;
+      }
+      const userIds = this.multipleSelection.map(item => item.userId).filter(id => id);
+      if (userIds.length === 0) {
+        this.$message.warning('所选数据中没有有效的用户ID');
+        return;
+      }
+      const data = {
+        userIds: userIds,
+        rules: this.tagForm.rules,
+        tagName: this.tagForm.tagName,
+        remarkFormat: this.tagForm.remarkFormat,
+        liveId: this.liveId
+      };
+      autoTagAndRemark(data).then(response => {
+        if (response.code === 200) {
+          this.$message.success('打标签成功');
+          this.tagDialogVisible = false;
+          this.tagForm = {
+            rules: [],
+            tagName: '',
+            remarkFormat: 'time'
+          };
+          this.getList();
         }
-
-        // 更新 queryParams.date
-        if (value) {
-          this.queryParams.date = this.formatDate(value);
+      });
+    },
+    /** 自动备注 */
+    // handleAutoRemark() {
+    //   if (this.multipleSelection.length === 0) {
+    //     this.$message.warning('请选择要备注的数据');
+    //     return;
+    //   }
+    //   this.remarkDialogVisible = true;
+    // },
+    /** 确认自动备注 */
+    confirmAutoRemark() {
+      if (this.remarkForm.rules.length === 0) {
+        this.$message.warning('请选择备注规则');
+        return;
+      }
+      const userIds = this.multipleSelection.map(item => item.userId).filter(id => id);
+      if (userIds.length === 0) {
+        this.$message.warning('所选数据中没有有效的用户ID');
+        return;
+      }
+      // 生成备注内容
+      let notes = '';
+      const now = new Date();
+      const dateStr = now.getFullYear() + '-' +
+        String(now.getMonth() + 1).padStart(2, '0') + '-' +
+        String(now.getDate()).padStart(2, '0');
+
+      this.remarkForm.rules.forEach((rule, index) => {
+        let ruleText = '';
+        if (rule === 'liveComplete') {
+          ruleText = '直播完课';
+        } else if (rule === 'replayComplete') {
+          ruleText = '回放完课';
+        } else if (rule === 'pay') {
+          ruleText = '付费行为';
         }
-        this.getTrendData();
-      },
-      formatDate(date) {
-        let date_ = new Date(date);
-        console.log(date_)
-        const year = date_.getFullYear();
-        const month = String(date_.getMonth() + 1).padStart(2, '0');
-        const day = String(date_.getDate()).padStart(2, '0');
-        return `${year}-${month}-${day}`;
-      },
 
-      // 获取一周的起始日期(周一)
-      getStartOfWeek(date) {
-        let parsedDate = new Date(date);
-        if (isNaN(parsedDate.getTime())) {
-          console.error("无效的日期:", date);
-          return null;
+        if (this.remarkForm.remarkFormat === 'time') {
+          notes += (index > 0 ? ';' : '') + dateStr + '—' + ruleText;
+        } else {
+          notes += (index > 0 ? ';' : '') + ruleText;
         }
+      });
+
+      const data = {
+        userIds: userIds,
+        notes: notes,
+        type: this.remarkForm.position,
+        nameType: 3, // 不添加客户名称
+        filter: false
+      };
 
-        const day = parsedDate.getDay();
-        const diff = parsedDate.getDate() - day + (day === 0 ? -6 : 1); // 调整到周一
-        return new Date(parsedDate.setDate(diff));
-      },
-
-      getEndOfWeek(date) {
-        const startOfWeek = this.getStartOfWeek(date);
-        if (!startOfWeek) return null;
-
-        let endOfWeek = new Date(startOfWeek);
-        endOfWeek.setDate(startOfWeek.getDate() + 6); // 调整到周日
-        return endOfWeek;
-      },
-      computedChange(item) {
-        switch (this.selectedTimeRange) {
-          case 'day': return item.dailyChange;
-          case 'week': return item.weeklyChange;
-          case 'month': return item.monthlyChange;
-          default: return 0;
-        }
-      },
-      selectRank(type) {
-        this.selectedRank = type; // 只允许一个按钮被选中
-        this.getLiveTop();  // 重新获取排行榜数据
-      },
-      // 切换时间范围
-      changeTimeRange() {
-        // 根据选中的时间范围修改 datePicker 类型
-        if (this.selectedTimeRange === 'day') {
-          this.datePickerType = 'date';  // 自然天
-          this.weekRange = '';  // 清空周范围
-        } else if (this.selectedTimeRange === 'month') {
-          this.datePickerType = 'month';  // 自然月
-          this.weekRange = '';  // 清空周范围
-        } else if (this.selectedTimeRange === 'week') {
-          this.datePickerType = 'week';  // 自然周
+      batchUpdateExternalContactNotes(data).then(response => {
+        if (response.code === 200) {
+          this.$message.success('备注成功');
+          this.remarkDialogVisible = false;
+          this.remarkForm = {
+            rules: [],
+            remarkFormat: 'time',
+            position: 1
+          };
+          this.getList();
         }
-        // 立即弹出日期选择器
-        this.$nextTick(() => {
-          this.$refs.datePickerRef.focus();
-        });
-        // 重置已选日期
-        this.queryParams.type = this.selectedTimeRange;
-        this.selectedDate = null;
-        this.queryParams.date = '';  // 清空 queryParams 中的日期
-      },
-      setDefaultDate() {
-        // 如果用户没有选择日期,则使用当前日期
-        if (!this.selectedDate) {
-          this.selectedDate = this.formatDate(new Date());
-          this.queryParams.date = this.selectedDate;
-        }
-      },
-      // 切换日期时更新数据
-      updateTrendData() {
-        // 这里可以加接口请求,获取新的数据
-        this.getTrendData()
-        this.updateChart();
-      },
-      initChart() {
-        let chartDom = document.getElementById("liveChart");
-        if (!chartDom) return;
-        this.chart = echarts.init(chartDom);
-        this.updateChart();
-      },
-      // 更新折线图
-      updateChart() {
-        if (!this.chart) return;
-
-        // 获取当前选中的指标对应的数据
-        let metricKey = this.selectedMetric;
-        let metricTitle = this.getMetricTitle(metricKey); // 获取指标标题
-        let chartData = this.trendData.data || [];
-        let dates = this.trendData.dates || []; // 确保 dates 不是 null
-        let options = {
-          tooltip: {
-            trigger: "axis",
-            backgroundColor: "rgba(0, 0, 0, 0.7)",
-            textStyle: { color: "#fff" },
-            formatter: function (params) {
-              let date = params[0].name; // x 轴的日期
-              let value = params[0].value; // 对应的数值
-              return `${date}<br/>${params[0].seriesName}: ${value}`;
-            }
-          },
-          grid: {
-            left: "5%", right: "5%", bottom: "10%", top: "10%", containLabel: true
-          },
-          xAxis: {
-            type: "category",
-            data: this.trendData.dates || [],
-            axisLine: {lineStyle: {color: "#ddd"}}
-          },
-          yAxis: {
-            type: "value",
-            splitLine: {lineStyle: {type: "dashed", color: "#ddd"}}
-          },
-          series: [
-            {
-              name: metricTitle,
-              data: chartData,
-              type: "line",
-              smooth: true,
-              symbol: "circle",
-              symbolSize: 8,
-              itemStyle: {
-                color: "#007BFF",
-                borderColor: "#fff",
-                borderWidth: 2
-              },
-              lineStyle: {
-                width: 3,
-                color: "#007BFF"
-              },
-              areaStyle: {
-                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                  {offset: 0, color: "rgba(0, 123, 255, 0.5)"},
-                  {offset: 1, color: "rgba(0, 123, 255, 0)"}
-                ])
-              },
-              emphasis: {
-                focus: "series",
-                label: {
-                  show: true,
-                  formatter: "{c}",
-                  fontSize: 14,
-                  color: "#333",
-                  backgroundColor: "#fff",
-                  padding: [4, 6]
-                }
-              },
-              animationDuration: 1200,
-              animationEasing: "quadraticOut"
-            }
-          ]
-        };
-
-        this.chart.setOption(options);
-      },
+      });
+    },
+    /** 查看详情 */
+    handleViewDetail(row) {
+      // 可以跳转到详情页面或打开详情弹窗
+      this.$message.info('查看详情功能待实现');
+    },
+    /** 格式化时长 */
+    formatDuration(seconds) {
+      if (!seconds) return '00:00:00';
+      const hours = Math.floor(seconds / 3600);
+      const minutes = Math.floor((seconds % 3600) / 60);
+      const secs = seconds % 60;
+      return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
+    },
+    /** 更新完课时长设置 */
+    updateCompleteWatchTime(type) {
+      // 这里可以调用API保存设置
+      let watchTime = 0;
+      if (type === 'total') {
+        watchTime = this.completeWatchTime;
+      } else if (type === 'live') {
+        watchTime = this.liveCompleteWatchTime;
+      } else if (type === 'replay') {
+        watchTime = this.replayCompleteWatchTime;
+      }
+      // 更新查询参数并重新获取数据
+      this.queryParams.completeWatchTime = watchTime;
+      // this.getStatistics();
+      this.getList();
+      this.$message.success('设置成功');
     }
-  };
+  }
+};
 </script>
 
 <style scoped>
-  .app-container {
-    padding: 20px;
-  }
-
-  .title {
-    font-size: 18px;
-    font-weight: bold;
-    margin-bottom: 10px;
-  }
-  .live-container {
-    display: flex;
-    gap: 15px; /* 控制卡片之间的间距 */
-    overflow-x: auto; /* 允许横向滚动 */
-    padding-bottom: 10px;
-  }
-
-  /* 卡片样式 */
-  .live-card {
-    width: 380px;
-    height: 225px;
-    background: rgb(250,250,250);
-    border-radius: 10px;
-    padding: 15px;
-    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
-    display: flex;
-    flex-direction: column;
-    align-items: flex-start;
-  }
-
-  /* 直播状态 */
-  .status {
-    background: #d3d3d3;
-    color: #333;
-    font-size: 14px;
-    padding: 4px 8px;
-    border-radius: 5px;
-    display: inline-block;
-  }
-
-  /* 不同状态颜色 */
-  .status-upcoming {
-    background: #FFC107; /* 黄色 */
-    color: #333;
-  }
-
-  .status-live {
-    background: #28A745; /* 绿色 */
-    color: white;
-  }
-
-  .status-ended {
-    background: #D3D3D3; /* 灰色 */
-    color: #333;
-  }
-  /* 直播信息部分 */
-  .content {
-    background: rgb(250,250,250);
-    display: flex;
-    gap: 10px;
-    align-items: center;
-    width: 90%;
-    margin-top: 0px;
-  }
-
-  /* 直播封面图片 */
-  .cover-image {
-    width: 70px;
-    height: 70px;
-    border-radius: 10px;
-    object-fit: cover;
-  }
-
-  /* 直播文本信息 */
-  .info {
-    flex: 1;
-  }
-
-  .live-title {
-    font-size: 16px;
-    font-weight: bold;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    max-width: 250px; /* 防止标题过长 */
-  }
-
-  .time {
-    font-size: 14px;
-    color: #666;
-  }
-
-  /* 直播数据部分 */
-  .stats {
-    display: flex;
-    justify-content: space-between;
-    width: 100%;
-    flex-shrink: 0;
-    margin-top: 10px;
-  }
-
-  .stat-item {
-    text-align: center;
-    flex: 1;
-  }
-
-  .label {
-    font-size: 14px;
-    color: #888;
-  }
-
-  .value {
-    font-size: 18px;
-    font-weight: bold;
-    color: #333;
-  }
-  /* 直播趋势 */
-  .trend-section {
-    margin-top: 30px;
-  }
-  .trend-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-  }
-  .trend-cards {
-    display: flex;
-    gap: 15px;
-  }
-  .trend-card {
-    width: 280px;
-    hight: 100px;
-    border: 1px solid #ddd;
-    border-radius: 8px;
-    padding: 16px;
-    transition: all 0.3s;
-    position: relative;
-  }
-
-  .trend-card.active {
-    border-color: #007bff; /* 选中时边框变蓝 */
-    box-shadow: 0px 0px 10px rgba(0, 123, 255, 0.3);
-  }
-
-  .trend-card.active::after {
-    content: "✔";
-    position: absolute;
-    bottom: 8px;
-    right: 8px;
-    color: white;
-    background: #007bff;
-    border-radius: 50%;
-    width: 20px;
-    height: 20px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    font-size: 14px;
-    font-weight: bold;
-  }
-  .trend-value {
-    font-size: 24px;
-    font-weight: bold;
-  }
-
-  /* 折线图 */
-  .chart {
-    width: 100%;
-    height: 300px;
-    margin-top: 20px;
-  }
-  .top10-section {
-    margin-top: 20px;
-    background: #fff;
-    padding: 16px;
-    border-radius: 8px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-  }
-  .live-name {
-    display: flex;
-    align-items: center;
-  }
-
-  .live-cover {
-    width: 80px;  /* 直播封面宽度 */
-    height: 45px; /* 直播封面高度 */
-    border-radius: 4px;
-    margin-right: 10px;
-    object-fit: cover;
-  }
-
-  .live-title {
-    font-size: 14px;
-    color: #333;
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-  }
-  .ranking-tabs {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    padding: 10px 20px;
-  }
-
-  .ranking-container {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    margin: 10px 0;
-    border-radius: 8px;
-    overflow: hidden;
-  }
-
-  .ranking-section {
-    display: flex;
-    align-items: center;
-    width: 50%;
-    padding: 10px 15px;
-  }
-
-  .red-rank {
-    background: linear-gradient(90deg, #ff6b6b, #ff8e8e);
-    justify-content: flex-start;
-  }
-
-  .black-rank {
-    background: linear-gradient(90deg, #4a4a4a, #6b6b6b);
-    justify-content: flex-end;
-  }
-
-  .rank-title {
-    font-size: 18px;
-    font-weight: bold;
-    color: white;
-    margin: 0 15px;
-  }
-
-  .rank-filters {
-    display: flex;
-  }
-
-  button {
-    background: rgba(255, 255, 255, 0.2);
-    border: 1px solid rgba(255, 255, 255, 0.5);
-    color: white;
-    font-size: 14px;
-    padding: 5px 12px;
-    margin: 0 5px;
-    border-radius: 15px;
-    cursor: pointer;
-    transition: all 0.3s ease;
-  }
-
-  button.active {
-    background: white;
-    color: #ff4d4f;
-  }
-  .filter-container {
-    display: flex;
-    align-items: center;
-    gap: 8px; /* 控制两个组件的间距 */
-  }
-
-  .filter-label {
-    font-weight: bold;
-    white-space: nowrap; /* 防止换行 */
-  }
-
-
-  .student-section {
-    margin-top: 20px;
-    background: #fff;
-    padding: 16px;
-    border-radius: 8px;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-  }
-   .column-item {
-     display: flex;
-     align-items: center;
-     justify-content: space-between;
-     padding: 8px;
-     border: 1px solid #ddd;
-     background: #f9f9f9;
-     margin-bottom: 5px;
-     cursor: grab;
-   }
-
-  .drag-handle {
-    cursor: grab;
-  }
-  /* 自定义列按钮的样式 */
-  .column-button-container {
-    text-align: right; /* 使按钮右对齐 */
-    margin-bottom: 10px; /* 为按钮和表格之间增加间距 */
-  }
-
-  .custom-column-button {
-    background-color: #409EFF;
-    color: black;
-    padding: 10px 20px;
-    border-radius: 5px;
-    margin-right: 10px; /* 如果有多个按钮,确保按钮之间有间距 */
-  }
-
-  /* 表格区域的样式 */
-  .student-section {
-    padding: 20px;
-  }
-
-  .el-table {
-    margin-top: 20px; /* 为表格添加顶部间距 */
-  }
-
-  .el-table-column {
-    /* 让列文本超出时显示省略号 */
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-  }
-
-  .el-table-column:hover {
-    cursor: pointer;
-  }
-  .no-wrap-column .cell {
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    text-align: center; /* 使列内容居中 */
-  }
-  .advanced-search {
-    margin-bottom: 10px;
-    padding: 15px;
-  }
-  .button-group {
-    display: flex;
-    justify-content: flex-end;
-    width: 100%;
-  }
-
-  /* 让按钮默认显示 */
-  .el-button {
-    opacity: 1; /* 确保默认状态可见 */
-    color: #606266; /* 默认文字颜色 */
-    border-color: #dcdfe6; /* 默认边框颜色 */
-    background-color: #f5f7fa; /* 默认背景色 */
-    transition: all 0.3s; /* 添加动画过渡 */
-  }
-
-  /* 鼠标悬停时高亮 */
-  .el-button:hover {
-    color: #409eff !important; /* 文字变蓝 */
-    border-color: #409eff !important; /* 边框变蓝 */
-    background-color: #ecf5ff !important; /* 背景变浅蓝 */
-  }
-
-  /* “展开/收起” 按钮特殊处理 */
-  .el-button[type="text"] {
-    background: none;
-    border: none;
-    color: #606266;
-  }
-
-  /* 鼠标悬停时高亮 */
-  .el-button[type="text"]:hover {
-    color: #409eff !important;
-  }
-  .el-form-item-ellipsis .el-input__inner,
-  .el-form-item-ellipsis .el-select .el-input__inner {
-    text-align: center; /* 输入框内容居中对齐 */
-  }
-
-  /* 控制 label 长度过长时显示省略号 */
-  .el-form-item-ellipsis .el-form-item__label {
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    width: 100%; /* 确保标签可以适配宽度 */
-    text-align: right;
-    vertical-align: middle;
-    float: left;
-    font-size: 14px;
-    color: #606266;
-    line-height: 40px;
-    padding: 0 10px 0 0;
-    -webkit-box-sizing: border-box;
-    box-sizing: border-box;
-    cursor: pointer;
-  }
-
-  /* 直播信息整体布局 */
-  .live-info {
-    display: flex;
-    align-items: center;
-  }
-
-  /* 直播封面图 */
-  .live-cover {
-    width: 80px;
-    height: 80px;
-    object-fit: cover;
-    border-radius: 6px;
-    margin-right: 10px;
-  }
-
-  /* 直播名称 + 时间 */
-  .live-text {
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
-  }
-
-
-  /* 直播时间 */
-  .live-time {
-    font-size: 12px;
-    color: #888;
-    margin-top: 4px;
-  }
-
-  /* 直播状态 */
-  .status-container {
-    display: flex;
-    align-items: center;
-  }
-
-  /* 状态圆点 */
-  .status-dot {
-    width: 8px;
-    height: 8px;
-    border-radius: 50%;
-    display: inline-block;
-    margin-right: 6px;
-  }
-  .live-name-input .el-input__inner {
-    white-space: normal;  /* 允许文本换行 */
-    word-wrap: break-word; /* 长文本自动换行 */
-    padding-left: 10px;
-  }
-
-  .live-name-tag {
-    margin-right: 5px;
-    display: inline-block; /* 确保标签显示为块级元素 */
-  }
-  .flex-container {
-    display: flex;
-    align-items: center;
-    gap: 10px; /* 调整 label 与输入框间距 */
-    width: 90%;
-  }
-
-  .ellipsis-label .el-form-item__label {
-    white-space: nowrap;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    max-width: 80px; /* 你可以调整这个值 */
-    display: block;
-    padding: 0 10px 0 0;
-  }
-
-  .full-width-picker {
-    flex: 1; /* 让日期选择器填充剩余空间 */
-  }
-
+.statistics-card {
+  margin-bottom: 20px;
+}
+
+.statistics-item {
+  text-align: center;
+  padding: 15px;
+  background: #f5f7fa;
+  border-radius: 4px;
+}
+
+.statistics-title {
+  font-size: 14px;
+  color: #606266;
+  margin-bottom: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.statistics-value {
+  font-size: 24px;
+  font-weight: bold;
+  color: #303133;
+}
+
+.selection-toolbar {
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px;
+  padding-left: 10px;
+}
+
+.selection-toolbar .el-checkbox {
+  margin-right: 10px;
+}
+
+.live-data-css {
+  padding-left: 10px;
+  padding-top: 30px;
+}
 </style>
-