ソースを参照

卓美优化相关代码

yjwang 1 ヶ月 前
コミット
93a2fbb8b9

+ 75 - 72
src/views/course/userCoursePeriod/courseStatistics.vue

@@ -27,13 +27,6 @@
     >
       <el-table-column label="课程名称" align="center" prop="courseName" width="200" />
       <el-table-column label="小节" align="center" prop="videoName" width="210" />
-<!--      <el-table-column label="小节状态" align="center" prop="videoStatus" width="120">-->
-<!--        <template slot-scope="scope">-->
-<!--          <el-tag :type="scope.row.videoStatus === '已开课' ? 'success' : scope.row.videoStatus === '已结束' ? 'info' : 'warning'">-->
-<!--            {{ scope.row.videoStatus }}-->
-<!--          </el-tag>-->
-<!--        </template>-->
-<!--      </el-table-column>-->
       <el-table-column label="开课状态" align="center" prop="openStatus" width="120">
         <template slot-scope="scope">
           <el-tag :type="scope.row.openStatus === '已开课' ? 'success' : scope.row.openStatus === '已结束' ? 'info' : 'warning'">
@@ -112,78 +105,84 @@
         </el-card>
 
         <!-- 第二块:首次点播数据 -->
+<!--        <el-card class="detail-card" shadow="never">-->
+<!--          <div slot="header" class="card-header">-->
+<!--            <span>首次点播数据</span>-->
+<!--          </div>-->
+<!--          <el-row :gutter="20">-->
+<!--            <el-col :span="6">-->
+<!--              <div class="stat-item">-->
+<!--                <div class="stat-label">观看人数</div>-->
+<!--                <div class="stat-value">{{ detailDialog.data.firstWatchCount || 0 }}</div>-->
+<!--              </div>-->
+<!--            </el-col>-->
+<!--            <el-col :span="6">-->
+<!--              <div class="stat-item">-->
+<!--                <div class="stat-label">>=20分钟人数(首次)</div>-->
+<!--                <div class="stat-value">{{ detailDialog.data.firstWatch20MinCount || 0 }}</div>-->
+<!--              </div>-->
+<!--            </el-col>-->
+<!--            <el-col :span="6">-->
+<!--              <div class="stat-item">-->
+<!--                <div class="stat-label">>=30分钟人数(首次)</div>-->
+<!--                <div class="stat-value">{{ detailDialog.data.firstWatch30MinCount || 0 }}</div>-->
+<!--              </div>-->
+<!--            </el-col>-->
+<!--            <el-col :span="6">-->
+<!--              <div class="stat-item">-->
+<!--                <div class="stat-label">到课完课率首次(>=20分钟)</div>-->
+<!--                <div class="stat-value">{{ detailDialog.data.firstCompleteRate20Min || '0%' }}</div>-->
+<!--              </div>-->
+<!--            </el-col>-->
+<!--            <el-col :span="6">-->
+<!--              <div class="stat-item">-->
+<!--                <div class="stat-label">到课完课率首次(>=30分钟)</div>-->
+<!--                <div class="stat-value">{{ detailDialog.data.firstCompleteRate30Min || '0%' }}</div>-->
+<!--              </div>-->
+<!--            </el-col>-->
+<!--          </el-row>-->
+<!--        </el-card>-->
+
+        <!-- 第三块:实际看课数据(修复后) -->
         <el-card class="detail-card" shadow="never">
           <div slot="header" class="card-header">
-            <span>首次点播数据</span>
+            <span>实际看课数据</span>
           </div>
           <el-row :gutter="20">
             <el-col :span="6">
               <div class="stat-item">
-                <div class="stat-label">观看人数</div>
-                <div class="stat-value">{{ detailDialog.data.firstWatchCount || 0 }}</div>
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="stat-item">
-                <div class="stat-label">>=20分钟人数(首次)</div>
-                <div class="stat-value">{{ detailDialog.data.firstWatch20MinCount || 0 }}</div>
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="stat-item">
-                <div class="stat-label">>=30分钟人数(首次)</div>
-                <div class="stat-value">{{ detailDialog.data.firstWatch30MinCount || 0 }}</div>
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="stat-item">
-                <div class="stat-label">到课完课率首次(>=20分钟)</div>
-                <div class="stat-value">{{ detailDialog.data.firstCompleteRate20Min || '0%' }}</div>
-              </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="stat-item">
-                <div class="stat-label">到课完课率首次(>=30分钟)</div>
-                <div class="stat-value">{{ detailDialog.data.firstCompleteRate30Min || '0%' }}</div>
+                <div class="stat-label">实际到课人数</div>
+                <div class="stat-value">{{ detailDialog.data.totalStudents || 0 }}</div>
               </div>
             </el-col>
-          </el-row>
-        </el-card>
-
-        <!-- 第三块:第2-n次观看数据 -->
-        <el-card class="detail-card" shadow="never">
-          <div slot="header" class="card-header">
-            <span>第2-n次观看数据</span>
-          </div>
-          <el-row :gutter="20">
             <el-col :span="6">
               <div class="stat-item">
-                <div class="stat-label">观看人数</div>
-                <div class="stat-value">{{ detailDialog.data.repeatWatchCount || 0 }}</div>
+                <div class="stat-label">实际完课人数</div>
+                <div class="stat-value">{{ detailDialog.data.completedCount || 0 }}</div>
               </div>
             </el-col>
             <el-col :span="6">
               <div class="stat-item">
-                <div class="stat-label">>=20分钟人数</div>
-                <div class="stat-value">{{ detailDialog.data.repeatWatch20MinCount || 0 }}</div>
+                <div class="stat-label">实际完课率</div>
+                <div class="stat-value">{{ detailDialog.data.actualCompletionRate ? detailDialog.data.actualCompletionRate + '%' : '0%' }}</div>
               </div>
             </el-col>
             <el-col :span="6">
               <div class="stat-item">
-                <div class="stat-label">>=30分钟人数</div>
-                <div class="stat-value">{{ detailDialog.data.repeatWatch30MinCount || 0 }}</div>
+                <div class="stat-label">人均看课时长</div>
+                <div class="stat-value">{{ (detailDialog.data.avgWatchDurationMinutes || 0) + '分' }}</div>
               </div>
             </el-col>
             <el-col :span="6">
               <div class="stat-item">
-                <div class="stat-label">到课完课率2-n次(>=20分钟)</div>
-                <div class="stat-value">{{ detailDialog.data.repeatCompleteRate20Min || '0%' }}</div>
+                <div class="stat-label">人均完课时长</div>
+                <div class="stat-value">{{ (detailDialog.data.avgCompletedDuration || 0) + '分' }}</div>
               </div>
             </el-col>
             <el-col :span="6">
               <div class="stat-item">
-                <div class="stat-label">到课完课率2-n次(>=30分钟)</div>
-                <div class="stat-value">{{ detailDialog.data.repeatCompleteRate30Min || '0%' }}</div>
+                <div class="stat-label">人均完课完播率</div>
+                <div class="stat-value">{{ detailDialog.data.avgCompletionPlaybackRate ? detailDialog.data.avgCompletionPlaybackRate + '%' : '0%' }}</div>
               </div>
             </el-col>
           </el-row>
@@ -249,7 +248,7 @@
         <!-- 第五块:单品销量统计 -->
         <el-card class="detail-card" shadow="never">
           <div slot="header" class="card-header">
-            <span>品销量统计</span>
+            <span>品销量统计</span>
           </div>
           <el-table
             :data="detailDialog.data.productList || []"
@@ -287,12 +286,12 @@
           style="width: 100%"
         >
           <el-table-column label="用户名称" align="center" prop="userName" width="150" />
-          <el-table-column label="观看时长" align="center" prop="watchDuration" width="120">
-            <template slot-scope="scope">
-              {{ formatDuration(scope.row.watchDuration) }}
-            </template>
-          </el-table-column>
-          <el-table-column label="第2-n次观看时长" align="center" prop="repeatWatchDuration" width="150">
+<!--          <el-table-column label="观看时长" align="center" prop="watchDuration" width="120">-->
+<!--            <template slot-scope="scope">-->
+<!--              {{ formatDuration(scope.row.watchDuration) }}-->
+<!--            </template>-->
+<!--          </el-table-column>-->
+          <el-table-column label="观看时长" align="center" prop="repeatWatchDuration" width="150">
             <template slot-scope="scope">
               {{ formatDuration(scope.row.repeatWatchDuration) }}
             </template>
@@ -452,7 +451,6 @@ export default {
       this.detailDialog.visible = true;
       this.detailDialog.loading = true;
 
-      // 调用API获取总体数据
       const videoId = row.videoId || row.id;
       const periodId = this.queryParams.periodId;
 
@@ -465,25 +463,30 @@ export default {
       getCourseStatisticsDetail(videoId, periodId).then(response => {
         if (response.code === 200 && response.data) {
           const data = response.data;
+          // 安全获取实际看课数据对象
+          const actualVO = data.fsActualCompletionVO || {};
+
           // 设置总体数据
           this.detailDialog.data = {
-            videoDuration: data.videoDuration || 0,
-            totalWatchCount: data.totalWatchCount || 0,
-            totalCompleteCount: data.totalCompleteCount || 0,
+            // 总体数据
+            videoDuration: data.videoDuration ?? 0,
+            totalWatchCount: data.totalWatchCount ?? 0,
+            totalCompleteCount: data.totalCompleteCount ?? 0,
             completeRate: data.completeRate != null ? Number(data.completeRate).toFixed(2) + '%' : '0%',
-            // 首次点播数据(接口返回)
+            // 首次点播数据
             firstWatchCount: data.firstWatchCount ?? 0,
             firstWatch20MinCount: data.firstWatch20MinCount ?? 0,
             firstWatch30MinCount: data.firstWatch30MinCount ?? 0,
             firstCompleteRate20Min: data.firstCompleteRate20Min != null ? Number(data.firstCompleteRate20Min).toFixed(2) + '%' : '0%',
             firstCompleteRate30Min: data.firstCompleteRate30Min != null ? Number(data.firstCompleteRate30Min).toFixed(2) + '%' : '0%',
-            // 第2-n次观看数据(接口返回)
-            repeatWatchCount: data.repeatWatchCount ?? 0,
-            repeatWatch20MinCount: data.repeatWatch20MinCount ?? 0,
-            repeatWatch30MinCount: data.repeatWatch30MinCount ?? 0,
-            repeatCompleteRate20Min: data.repeatCompleteRate20Min != null ? Number(data.repeatCompleteRate20Min).toFixed(2) + '%' : '0%',
-            repeatCompleteRate30Min: data.repeatCompleteRate30Min != null ? Number(data.repeatCompleteRate30Min).toFixed(2) + '%' : '0%',
-            // 订单数据(接口返回)
+            // 实际看课数据(修复后,所有字段都有默认值)
+            totalStudents: actualVO.totalStudents ?? 0,
+            completedCount: actualVO.completedCount ?? 0,
+            actualCompletionRate: actualVO.actualCompletionRate != null ? Number(actualVO.actualCompletionRate).toFixed(2) : '0',
+            avgWatchDurationMinutes: actualVO.avgWatchDurationMinutes ?? 0,
+            avgCompletedDuration: actualVO.avgCompletedDuration ?? 0,
+            avgCompletionPlaybackRate: actualVO.avgCompletionPlaybackRate != null ? Number(actualVO.avgCompletionPlaybackRate).toFixed(2) : '0',
+            // 订单数据
             gmv: data.gmv != null ? Number(data.gmv).toFixed(2) : '0.00',
             paidUserCount: data.paidUserCount ?? 0,
             paidOrderCount: data.paidOrderCount ?? 0,

+ 16 - 2
src/views/hisStore/components/productOrder.vue

@@ -323,9 +323,15 @@
               </span>
           </el-descriptions-item>
           <el-descriptions-item label="实付金额"  >
-              <span v-if="order!=null">
+              <span v-if="order!=null && !isBeiJingZhuoMei">
+                ¥{{order.payMoney.toFixed(2)}}
+              </span>
+            <span v-else-if="order!=null && isBeiJingZhuoMei && order.status != -3">
                 ¥{{order.payMoney.toFixed(2)}}
               </span>
+              <span v-else>
+                ¥0
+              </span>
           </el-descriptions-item>
           <el-descriptions-item label="代收金额"  >
               <span v-if="order!=null">
@@ -823,6 +829,7 @@ import singleImg from '@/components/Material/single'
 import {getCompanyList} from "@/api/company/company";
 import {listStore} from '@/api/hisStore/store';
 import {addStoreOrderItem, delStoreOrderItem, updateNumStoreOrderItem} from "../../../api/hisStore/storeOrderItem";
+import{ getSignProjectName } from '@/api/course/qw/courseWatchLog'
 
 
 export default {
@@ -835,6 +842,7 @@ export default {
   },
   data() {
     return {
+      isBeiJingZhuoMei:false,
       zdyInfo: process.env.VUE_APP_FS_USER_INFO,
       isMedicalMall: this.$store.state.user.medicalMallConfig.medicalMall,
       dialogVisibleImage: false,
@@ -1026,6 +1034,7 @@ export default {
     getTcmScheduleList().then(response => {
       this.scheduleOptions = response.data;
     });
+    this.checkProjectName()
   },
   methods: {
     // 显示修改数量弹窗
@@ -1576,7 +1585,12 @@ export default {
         }
       });
     },
-  }
+    checkProjectName() {
+      getSignProjectName().then(r=>{
+        this.isBeiJingZhuoMei = r.signProjectName === '北京卓美';
+      });
+    },
+  },
 };
 </script>
 <style scoped>

+ 7 - 2
src/views/hisStore/storeOrder/healthStoreList.vue

@@ -461,9 +461,14 @@
       <el-table-column label="ERP电话" align="center" prop="erpPhone" width="120px" v-if="SFDFopen"/>
       <el-table-column label="ERP账号" align="center" prop="erpAccount" width="120px" v-if="SFDFopen"/>
       <el-table-column label="小程序名称" align="center" prop="miniProgramName"/>
-      <el-table-column align="center" label="用户昵称" prop="nickname" width="150px">
+      <el-table-column label="用户昵称" align="center" prop="nickname" width="150px" >
         <template slot-scope="scope">
-          <span>{{ scope.row.nickname }} </span>
+          <span>{{scope.row.userNickName}} </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="手机号" align="center" prop="nickname" width="150px" >
+        <template slot-scope="scope">
+          <span>{{scope.row.nickname}} </span>
         </template>
       </el-table-column>
       <el-table-column align="center" label="收件人" prop="realName" width="150px">

+ 7 - 1
src/views/hisStore/storeOrder/index.vue

@@ -482,9 +482,14 @@
       <el-table-column label="小程序名称" width="120px" align="center" prop="miniProgramName"/>
       <el-table-column label="用户昵称" align="center" prop="nickname" width="150px" >
           <template slot-scope="scope">
-              <span>{{scope.row.nickname}} </span>
+              <span>{{scope.row.userNickName}} </span>
           </template>
       </el-table-column>
+      <el-table-column label="手机号" align="center" prop="nickname" width="150px" >
+        <template slot-scope="scope">
+          <span>{{scope.row.nickname}} </span>
+        </template>
+      </el-table-column>
       <el-table-column label="收件人" align="center" prop="realName" width="150px" >
           <template slot-scope="scope">
               <span>{{scope.row.realName}} </span>
@@ -1211,6 +1216,7 @@ export default {
         { key: 'deliveryId', label: '快递单号', checked: false },
         { key: 'remark', label: '备注', checked: false },
         { key: 'isAudit', label: '是否审核', checked: false },
+        { key: 'userNickName', label: '用户昵称', checked: false },
         { key: 'orderRemark', label: '订单备注', checked: false },
       ],
 

+ 10 - 3
src/views/system/config/config.vue

@@ -1351,7 +1351,7 @@
             <el-radio-group v-model="form18.rewardType">
               <el-radio label="1">红包</el-radio>
               <el-radio label="2">积分</el-radio>
-              <el-radio label="3">红包+积分</el-radio>
+              <el-radio label="3" v-if="!isBeiJingZhuoMei">红包+积分</el-radio>
             </el-radio-group>
           </el-form-item>
 
@@ -2782,6 +2782,7 @@ import { getCitys } from '@/api/store/city'
 import { listCompany } from '@/api/company/company'
 import { getStoreProductColumns } from '@/api/hisStore/storeProduct'
 import { getStoreColumns } from '@/api/hisStore/store'
+import{ getSignProjectName } from '@/api/course/qw/courseWatchLog'
 
 export default {
   name: 'Config',
@@ -2792,6 +2793,7 @@ export default {
   },
   data() {
     return {
+      isBeiJingZhuoMei:false,
       citys: [],
       images: [],
       appImages: [],
@@ -3038,7 +3040,7 @@ export default {
     }
   },
   created() {
-
+    this.checkProjectName();
     this.getConfigByKey(this.activeName)
     listStore().then(response => {
       this.storeOPtions = response.rows
@@ -4116,7 +4118,12 @@ export default {
       // 转换回数字并更新
       rule[field] = parseFloat(str) || 0;
     },
-  }
+     checkProjectName() {
+       getSignProjectName().then(r=>{
+         this.isBeiJingZhuoMei = r.signProjectName === '北京卓美';
+       });
+    },
+  },
 }
 </script>
 <style scoped>