瀏覽代碼

取消直接退款按钮

yuhongqi 1 周之前
父節點
當前提交
e50ef37945
共有 3 個文件被更改,包括 352 次插入5 次删除
  1. 28 0
      src/api/live/liveData.js
  2. 1 1
      src/views/live/liveAfteraSales/index.vue
  3. 323 4
      src/views/live/liveData/index.vue

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

@@ -20,3 +20,31 @@ export function listLiveData(data) {
     data:data,
   })
 }
+
+export function getLiveDataDetailBySql(liveId) {
+  return request({
+    url: '/liveData/liveData/getLiveDataDetailBySql?liveId=' + liveId,
+    method: 'get'
+  })
+}
+
+export function getLiveUserDetailListBySql(liveId) {
+  return request({
+    url: '/liveData/liveData/getLiveUserDetailListBySql?liveId=' + liveId,
+    method: 'get'
+  })
+}
+
+export function getLiveDataDetailByServer(liveId) {
+  return request({
+    url: '/liveData/liveData/getLiveDataDetailByServer?liveId=' + liveId,
+    method: 'get'
+  })
+}
+
+export function getLiveUserDetailListByServer(liveId) {
+  return request({
+    url: '/liveData/liveData/getLiveUserDetailListByServer?liveId=' + liveId,
+    method: 'get'
+  })
+}

+ 1 - 1
src/views/live/liveAfteraSales/index.vue

@@ -183,7 +183,7 @@
             size="mini"
             type="text"
             @click="handleShow(scope.row)"
-            v-hasPermi="['live:liveAfterSales:query']"
+            v-hasPermi="['live:liveAfteraSales:query']"
           >查看</el-button>
 
         </template>

+ 323 - 4
src/views/live/liveData/index.vue

@@ -309,11 +309,256 @@
         <el-button type="primary" @click="confirmAutoRemark">确 定</el-button>
       </div>
     </el-dialog>
+
+    <!-- 详情侧边栏 -->
+    <el-drawer
+      title="直播间详情"
+      :visible.sync="detailDrawerVisible"
+      direction="rtl"
+      size="60%"
+      :before-close="closeDetailDrawer"
+    >
+      <div v-if="!showUserDetail" class="detail-content">
+        <el-card shadow="never" style="margin-bottom: 20px;">
+          <div slot="header">
+            <span>总体数据</span>
+            <el-button style="float: right; padding: 3px 0" type="text" @click="handleViewUserDetail">查看用户详情</el-button>
+          </div>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">视频时长:</span>
+                <span class="detail-value">{{ formatDuration(detailData.videoDuration || 0) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">累计观看人数:</span>
+                <span class="detail-value">{{ detailData.totalViewers || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">累计完课人数:</span>
+                <span class="detail-value">{{ detailData.totalCompletedCourses || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">到课完课率:</span>
+                <span class="detail-value">{{ formatPercent(detailData.totalCompletionRate) }}</span>
+              </div>
+            </el-col>
+          </el-row>
+        </el-card>
+
+        <el-card shadow="never" style="margin-bottom: 20px;">
+          <div slot="header">直播数据</div>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">直播观看人数:</span>
+                <span class="detail-value">{{ detailData.liveViewers || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">>20分钟人数(直播):</span>
+                <span class="detail-value">{{ detailData.liveOver20Minutes || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">>30分钟人数(直播):</span>
+                <span class="detail-value">{{ detailData.liveOver30Minutes || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">到课完课率直播(>20分钟):</span>
+                <span class="detail-value">{{ formatPercent(detailData.liveCompletionRate20) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">到课完课率直播(>30分钟):</span>
+                <span class="detail-value">{{ formatPercent(detailData.liveCompletionRate30) }}</span>
+              </div>
+            </el-col>
+          </el-row>
+        </el-card>
+
+        <el-card shadow="never" style="margin-bottom: 20px;">
+          <div slot="header">回放数据</div>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">回放观看人数:</span>
+                <span class="detail-value">{{ detailData.playbackViewers || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">>20分钟人数(回放):</span>
+                <span class="detail-value">{{ detailData.playbackOver20Minutes || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">>30分钟人数(回放):</span>
+                <span class="detail-value">{{ detailData.playbackOver30Minutes || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">到课完课率回放(>20分钟):</span>
+                <span class="detail-value">{{ formatPercent(detailData.playbackCompletionRate20) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">到课完课率回放(>30分钟):</span>
+                <span class="detail-value">{{ formatPercent(detailData.playbackCompletionRate30) }}</span>
+              </div>
+            </el-col>
+          </el-row>
+        </el-card>
+
+        <el-card shadow="never" style="margin-bottom: 20px;">
+          <div slot="header">时长统计</div>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">直播峰值:</span>
+                <span class="detail-value">{{ detailData.livePeak || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">直播平均时长:</span>
+                <span class="detail-value">{{ formatDuration(detailData.liveAvgDuration || 0) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">回放平均时长:</span>
+                <span class="detail-value">{{ formatDuration(detailData.playbackAvgDuration || 0) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">回放完播率:</span>
+                <span class="detail-value">{{ formatPercent(detailData.playbackFinishRate) }}</span>
+              </div>
+            </el-col>
+          </el-row>
+        </el-card>
+
+        <el-card shadow="never" style="margin-bottom: 20px;">
+          <div slot="header">订单数据</div>
+          <el-row :gutter="20">
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">GMV:</span>
+                <span class="detail-value">{{ formatMoney(detailData.gmv) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">付费人数:</span>
+                <span class="detail-value">{{ detailData.paidUsers || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">付费单数:</span>
+                <span class="detail-value">{{ detailData.paidOrders || 0 }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">峰值转化率:</span>
+                <span class="detail-value">{{ formatPercent(detailData.peakConversionRate) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">总到课转化率:</span>
+                <span class="detail-value">{{ formatPercent(detailData.totalViewerConversionRate) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">30min完课转化率:</span>
+                <span class="detail-value">{{ formatPercent(detailData.completion30MinConversionRate) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">峰值R值:</span>
+                <span class="detail-value">{{ formatMoney(detailData.peakRValue) }}</span>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div class="detail-item">
+                <span class="detail-label">完课R值:</span>
+                <span class="detail-value">{{ formatMoney(detailData.completionRValue) }}</span>
+              </div>
+            </el-col>
+          </el-row>
+        </el-card>
+
+        <el-card shadow="never" v-if="detailData.productSalesList && detailData.productSalesList.length > 0">
+          <div slot="header">单品销量统计</div>
+          <el-table :data="detailData.productSalesList" border>
+            <el-table-column prop="productName" label="商品名称" min-width="200"></el-table-column>
+            <el-table-column prop="salesCount" label="销量" width="100" align="center"></el-table-column>
+            <el-table-column prop="salesAmount" label="销售额" width="150" align="center">
+              <template slot-scope="scope">
+                {{ formatMoney(scope.row.salesAmount) }}
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </div>
+
+      <!-- 用户详情列表 -->
+      <div v-else class="user-detail-content">
+        <el-button type="text" icon="el-icon-arrow-left" @click="showUserDetail = false" style="margin-bottom: 20px;">返回</el-button>
+        <el-table
+          :data="userDetailList"
+          v-loading="userDetailLoading"
+          border
+          style="width: 100%"
+        >
+          <el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
+          <el-table-column prop="userName" label="用户名称" min-width="120"></el-table-column>
+          <el-table-column prop="liveWatchDuration" label="直播观看时长" width="140" align="center">
+            <template slot-scope="scope">
+              {{ formatDuration(scope.row.liveWatchDuration || 0) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="playbackWatchDuration" label="回放观看时长" width="140" align="center">
+            <template slot-scope="scope">
+              {{ formatDuration(scope.row.playbackWatchDuration || 0) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="orderCount" label="订单数" width="100" align="center"></el-table-column>
+          <el-table-column prop="orderAmount" label="订单金额" width="120" align="center">
+            <template slot-scope="scope">
+              {{ formatMoney(scope.row.orderAmount) }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="companyName" label="分公司" min-width="150"></el-table-column>
+          <el-table-column prop="salesName" label="销售" min-width="120"></el-table-column>
+        </el-table>
+      </div>
+    </el-drawer>
   </div>
 </template>
 
 <script>
-import { listLiveData, exportLiveData, autoTagAndRemark, dashboardData } from "@/api/live/liveData";
+import { listLiveData, exportLiveData, autoTagAndRemark, dashboardData, getLiveDataDetailBySql, getLiveUserDetailListBySql } from "@/api/live/liveData";
 import { batchUpdateExternalContactNotes } from "@/api/qw/externalContact";
 import { addTag } from "@/api/qw/externalContact";
 
@@ -377,7 +622,14 @@ export default {
         rules: [],
         remarkFormat: 'time',
         position: 1
-      }
+      },
+      // 详情侧边栏
+      detailDrawerVisible: false,
+      currentLiveId: null,
+      detailData: {},
+      userDetailList: [],
+      userDetailLoading: false,
+      showUserDetail: false
     };
   },
   created() {
@@ -582,8 +834,9 @@ export default {
     },
     /** 查看详情 */
     handleViewDetail(row) {
-      // 可以跳转到详情页面或打开详情弹窗
-      this.$message.info('查看详情功能待实现');
+      this.currentLiveId = row.liveId;
+      this.detailDrawerVisible = true;
+      this.loadDetailData();
     },
     /** 格式化时长 */
     formatDuration(seconds) {
@@ -609,6 +862,48 @@ export default {
       // this.getStatistics();
       this.getList();
       this.$message.success('设置成功');
+    },
+    /** 加载详情数据 */
+    loadDetailData() {
+      if (!this.currentLiveId) return;
+      // 使用SQL方式获取详情数据
+      getLiveDataDetailBySql(this.currentLiveId).then(response => {
+        if (response.code === 200) {
+          this.detailData = response.data || {};
+        }
+      });
+    },
+    /** 查看用户详情 */
+    handleViewUserDetail() {
+      if (!this.currentLiveId) return;
+      this.showUserDetail = true;
+      this.userDetailLoading = true;
+      getLiveUserDetailListBySql(this.currentLiveId).then(response => {
+        if (response.code === 200) {
+          this.userDetailList = response.data || [];
+        }
+        this.userDetailLoading = false;
+      }).catch(() => {
+        this.userDetailLoading = false;
+      });
+    },
+    /** 关闭详情侧边栏 */
+    closeDetailDrawer() {
+      this.detailDrawerVisible = false;
+      this.showUserDetail = false;
+      this.detailData = {};
+      this.userDetailList = [];
+      this.currentLiveId = null;
+    },
+    /** 格式化百分比 */
+    formatPercent(value) {
+      if (value == null || value === undefined) return '0%';
+      return (typeof value === 'number' ? value : parseFloat(value)).toFixed(2) + '%';
+    },
+    /** 格式化金额 */
+    formatMoney(value) {
+      if (value == null || value === undefined) return '¥0.00';
+      return '¥' + (typeof value === 'number' ? value : parseFloat(value)).toFixed(2);
     }
   }
 };
@@ -656,4 +951,28 @@ export default {
   padding-left: 10px;
   padding-top: 30px;
 }
+
+.detail-content {
+  padding: 20px;
+}
+
+.detail-item {
+  margin-bottom: 15px;
+  line-height: 32px;
+}
+
+.detail-label {
+  color: #606266;
+  font-size: 14px;
+}
+
+.detail-value {
+  color: #303133;
+  font-size: 14px;
+  font-weight: bold;
+}
+
+.user-detail-content {
+  padding: 20px;
+}
 </style>