Ver Fonte

点播功能更新

Signed-off-by: 李妹妹 <1639016684@qq.com>
李妹妹 há 4 dias atrás
pai
commit
4300e1f052

+ 4 - 4
App.vue

@@ -98,13 +98,13 @@
 	const healthSeconds = 180;
 	let offlineMsg = null;
 	let offlineHandleNewMsg = null;
-	const baseUrl = 'https://userapp.zkhj6.com'
+	const baseUrl = 'https://userapp.klbycp.com'
 
 	export default {
 		globalData: {
-			wsUrl: 'ws://webim.zkhj6.com',
-			danmuWSUrl: 'wss://webim.zkhj6.com',
-			aiWSUrl: 'ws://webim.zkhj6.com',
+			wsUrl: 'ws://webim.klbycp.com',
+			danmuWSUrl: 'wss://webim.klbycp.com',
+			aiWSUrl: 'ws://webim.klbycp.com',
 			kfurl: 'https://work.weixin.qq.com/kfid/kfc3731c5008ebd8906', //企业微信客服链接
 			corpId: 'ww70ac72e824957fc9', //客服企业id
 			miniprogamId: 'gh_b51445318864',

+ 1 - 1
api/user.js

@@ -212,7 +212,7 @@ export function getProductFoots(data) {
 	return request('/store/app/user/getProductFoots', data, 'GET');
 }
 export function delProductFoots(data) {
-	return request('/app/user/delProductFoots', data, 'POST', 'application/json;charset=UTF-8');
+	return request('/store/app/user/delProductFoots', data, 'POST', 'application/json;charset=UTF-8');
 }
 
 export function doExtract(data) {

+ 5 - 0
common/request.js

@@ -38,6 +38,11 @@ export default class Request {
 			
 			// path ='http://z2fae9e9.natappfree.cc'
 		}
+		//看课点播
+		if(router.indexOf("/course_uniapp") != -1 ) {
+		    path ='https://userapp.klbycp.com';
+			router = router.replace('/course_uniapp','')
+		}
 		// 腕表模块
 		// if (router.indexOf("/watch-api") != -1) {
 		// 	router = router.replace('/watch-api', '')

+ 22 - 24
components/px-popup-bottom/px-popup-bottom.vue

@@ -3,7 +3,7 @@
 		:style="{'z-index':zindex}">
 		<view class="mask" :style="{'z-index':maskZindex,bottom:bottom+'rpx'}" v-show="show" @click.stop="onClose"
 			@touchmove.prevent.stop></view>
-		<view :class="['content',{show}]" @click.stop @touchmove.prevent.stop :style="{height:`${height}px`,maxHeight:show ? cotMaxHeight:0,'border-top-right-radius':cotRadius,
+		<view :class="['content',{show}]" @click.stop @touchmove.prevent.stop :style="{'background-color':bgColor,height:`${height}px`,maxHeight:show ? cotMaxHeight:0,'border-top-right-radius':cotRadius,
 			'border-top-left-radius':cotRadius,transition: `all ${animaTime}s ease-in`,bottom:bottom+'rpx','z-index':zindex}">
 			<view id="title-bar" class="title-bar" v-show="title">
 				<view class="title" :style="{fontWeight:fontweight}">{{title}}</view>
@@ -11,22 +11,20 @@
 					<image class="close-icon" :src="closeIcon" mode="widthFix"></image>
 				</view>
 			</view>
-			
 			<view class="scroll-wrap">
 				<scroll-view :class="{'scroll-view':isAnimaStart}" scroll-y="true" style="height:100%;"
 					@scrolltolower="onScrollToLower">
-					<view id="popup_content" class="popup_content" :style="{height:`${PopHeight}px`}">
+					<view id="popup_content" class="popup_content">
 						<slot></slot>
 					</view>
 				</scroll-view>
 			</view>
-			
 		</view>
 	</view>
 </template>
 
 <script>
-	import iconClose from '@/static/images/close40.png'
+	// import iconClose from 'https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/close40.png'
 	export default {
 		props: {
 			title: { //标题
@@ -57,6 +55,10 @@
 				type: [String, Number],
 				default: 0
 			},
+			bgColor: {
+				type: [String],
+				default: '#ffffff'
+			},
 			zindex: {
 				type: [String, Number],
 				default: 1000
@@ -71,7 +73,6 @@
 			},
 
 		},
-		
 		data() {
 			return {
 				show: false,
@@ -81,7 +82,7 @@
 				isAnimaStart: false,
 				rpxRate: "",
 				cotRadius: 0,
-				closeIcon: iconClose
+				closeIcon:'https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/close40.png'
 			}
 		},
 		watch: {
@@ -90,12 +91,15 @@
 				setTimeout(() => {
 					this.isAnimaStart = false;
 				}, this.animaTime * 1000)
+
 				if (newval && this.height === 0) {
 					if (this.PopHeight === 0 || this.always) {
 						this.setContViewHeight();
+
 					} else {
 						this.height = this.PopHeight
 					}
+
 					// #ifdef H5 
 					this.setBodyOverFlow('hidden') //阻止滚动穿透
 					//#endif
@@ -159,29 +163,24 @@
 					return `${val}rpx`;
 				}
 				return val;
+
 			},
 			preventTouch(el) {
 				el.addEventListener('touchmove', function(e) {
 					e.stopPropagation();
-				},{
+
+				}, {
 					passive: false
 				});
 			},
 			setBodyOverFlow(val) {
 				document.body.style.overflow = val
 			},
+
 			//设置内容区域高度
 			async setContViewHeight() {
 				let data = await this.computeHeight();
-				console.log("qxj setContViewHeight data:"+JSON.stringify(data));
-				
-				let temHeight=data.height + (this.title ? 100 / parseFloat(this.rpxRate) : 0);
-				const systemInfo = uni.getSystemInfoSync();
-				let viewHeight=systemInfo.screenHeight;
-				
-				this.height =viewHeight*0.7;
-				console.log("qxj viewHeight:"+this.height);
-				
+				this.height = data.height + (this.title ? 100 / parseFloat(this.rpxRate) : 0);
 				this.PopHeight = this.height;
 			},
 			//计算内容区域高度
@@ -232,7 +231,7 @@
 			right: 0;
 			height: 0;
 			height: auto;
-			background-color: white;
+			background-color: #ffffff;
 			transition: all 0.2s ease-in;
 			z-index: 1000;
 			display: flex;
@@ -245,14 +244,14 @@
 				flex-shrink: 0;
 				text-align: center;
 				position: relative;
-				padding: 15rpx 70rpx 0;
-				padding-top: 30rpx;
+				padding: 10rpx 70rpx 0;
 				box-sizing: border-box;
 				height: 80rpx;
+
 				.title {
-					font-size: 26rpx;
+					font-size: 34upx;
 					font-family: PingFang SC;
-					font-weight: normal !important;
+					font-weight: bold !important;
 					color: #111111;
 					width: 100%;
 					overflow: hidden;
@@ -300,8 +299,7 @@
 
 	.popup_content {
 		width: 100%;
-		padding: 30rpx;
-		padding-top: 0;
+		padding: 0rpx 30rpx;
 		box-sizing: border-box;
 
 		&::after {

+ 2 - 2
manifest.json

@@ -2,8 +2,8 @@
     "name" : "乐享韶华",
     "appid" : "__UNI__3983062",
     "description" : "",
-    "versionName" : "1.0.3",
-    "versionCode" : 1031,
+    "versionName" : "1.0.4",
+    "versionCode" : 104,
     "transformPx" : false,
     /* 5+App特有相关 */
     "app-plus" : {

+ 247 - 255
pages.json

@@ -2938,55 +2938,42 @@
 				}
 			]
 		},
-		{
+{
 			"root": "pages_im",
 			"pages": [
 				{
-					"path": "pages/conversation/conversationList/index",
+					"path": "pages/conversation/course/courseList",
 					"style": {
-						"navigationBarTitleText": "",
+						"navigationBarTitleText": "课程列表",
 						"enablePullDownRefresh": false,
-						"disableScroll": true,
-						"navigationStyle": "custom",
 						"navigationBarTextStyle": "black"
 					}
-				},
+				}, 
 				{
-					"path": "pages/common/searchUserOrGroup/index",
+					"path": "pages/conversation/course/courseSend",
 					"style": {
-						"navigationBarTitleText": "",
+						"navigationBarTitleText": "课程发送",
 						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black",
-						"app-plus": {
-							"bounce": "none"
-						}
-					}
-				},
-				{
-					"path": "pages/common/groupCard/index",
-					"style": {
-						"navigationBarTitleText": "",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
 						"navigationBarTextStyle": "black"
 					}
-				},
+				}, 
 				{
-					"path": "pages/conversation/chating1/index",
+					"path": "pages/conversation/conversationList/index",
 					"style": {
 						"navigationBarTitleText": "",
 						"enablePullDownRefresh": false,
-						"disableScroll": true,
-						"navigationBarTextStyle": "black",
+						
 						"navigationStyle": "custom",
+						"navigationBarTextStyle": "black",
 						"app-plus": {
-							"softinputMode": "adjustResize"
+							"bounce": "none",
+							"scrollIndicator": "none" 
 						}
 					}
-				},
+				}, 
+				
 				{
-					"path": "pages/conversation/singleSettings/index",
+					"path": "pages/common/searchUserOrGroup/index",
 					"style": {
 						"navigationBarTitleText": "",
 						"enablePullDownRefresh": false,
@@ -2996,21 +2983,87 @@
 							"bounce": "none"
 						}
 					}
+				}, 
+				{
+						"path": "pages/contact/applicationList/index",
+						"style": {
+							"navigationBarTitleText": "",
+							"enablePullDownRefresh": false,
+							"navigationStyle": "custom",
+							"navigationBarTextStyle": "black"
+						}
 				},
 				{
-					"path": "pages/conversation/groupSettings/index",
-					"style": {
-						"navigationBarTitleText": "",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black",
-						"app-plus": {
-							"bounce": "none"
+						"path": "pages/common/groupCard/index",
+						"style": {
+							 "navigationBarTitleText": "",
+							"enablePullDownRefresh": false,
+							"navigationStyle": "custom",
+							"navigationBarTextStyle": "black"
+						}
+				},
+				{
+						"path": "pages/common/setMemberMute/index",
+						"style": {
+							"navigationBarTitleText": "",
+							"enablePullDownRefresh": false,
+							"navigationStyle": "custom",
+							"navigationBarTextStyle": "black",
+							"app-plus": {
+								"titleNView": false,
+								"bounce": "none"
+							}
 						}
-					}
 				},
 				{
-					"path": "pages/conversation/groupManage/index",
+						"path": "pages/conversation/chating/index",
+						"style": {
+							"navigationBarTitleText": "详情",
+							"enablePullDownRefresh": false,
+							"disableScroll": true,
+							"navigationBarTextStyle": "black",
+							
+							"app-plus": {
+								"bounce": "none",
+								"softinputNavBar": "none",
+								"titleNView": false
+							}
+						}
+				  },
+				  {
+				  		"path": "pages/conversation/chating1/index",
+						"style": {
+							"navigationBarTitleText": "",
+							"enablePullDownRefresh": false,
+							"disableScroll": true,
+							"navigationBarTextStyle": "black",
+							"navigationStyle": "default",
+							"app-plus": {
+								"bounce": "none",
+								"softinputNavBar": "none",
+								"titleNView": {
+									"backgroundColor": "#ffffff",
+									"titleText": "",
+									"titleColor": "#333333",
+									"titleSize":"20",
+									"autoBackButton": true,
+									"buttons": [
+										{
+											"id": "more",
+											"text": "更多",
+											"fontSize": "16",
+											"color": "#333333",
+											"float": "right",
+											"width": "50px"
+											
+										}
+									]
+								}
+							}
+						}
+				}
+				,{
+					"path": "pages/conversation/singleSettings/index",
 					"style": {
 						"navigationBarTitleText": "",
 						"enablePullDownRefresh": false,
@@ -3022,8 +3075,8 @@
 					}
 				},
 				{
-					"path": "pages/conversation/groupMemberList/index",
-					"style": {
+				  "path": "pages/conversation/groupSettings/index",
+				  "style": {
 						"navigationBarTitleText": "",
 						"enablePullDownRefresh": false,
 						"navigationStyle": "custom",
@@ -3031,23 +3084,23 @@
 						"app-plus": {
 							"bounce": "none"
 						}
-					}
+				  }
 				},
 				{
-					"path": "pages/conversation/groupAnnouncement/index",
-					"style": {
+				  "path": "pages/conversation/groupManage/index",
+				  "style": {
 						"navigationBarTitleText": "",
 						"enablePullDownRefresh": false,
 						"navigationStyle": "custom",
-						"disableScroll": true,
+						"navigationBarTextStyle": "black",
 						"app-plus": {
-							"softinputMode": "adjustResize"
+							"bounce": "none"
 						}
-					}
+				  }
 				},
 				{
-					"path": "pages/conversation/groupMessageReadState/index",
-					"style": {
+				  "path": "pages/conversation/groupMemberList/index",
+				  "style": {
 						"navigationBarTitleText": "",
 						"enablePullDownRefresh": false,
 						"navigationStyle": "custom",
@@ -3055,8 +3108,34 @@
 						"app-plus": {
 							"bounce": "none"
 						}
-					}
-				},
+				  }
+				},
+				{
+				  "path": "pages/conversation/groupAnnouncement/index",
+				  "style": {
+				    "navigationBarTitleText": "",
+				    "enablePullDownRefresh": false,
+					"navigationStyle": "custom",
+				    "disableScroll": true,
+					"navigationBarTextStyle": "black",
+				    "app-plus": {
+				      "softinputMode": "adjustResize"
+				    }
+				  }
+				},
+				{
+				  "path": "pages/conversation/groupMessageReadState/index",
+				  "style": {
+				      "navigationBarTitleText": "",
+				      "enablePullDownRefresh": false,
+					  "navigationStyle": "custom",
+					  "navigationBarTextStyle": "black",
+					  "app-plus": {
+					  	 "bounce": "none"
+					  }
+				  }
+				},
+				
 				{
 					"path": "pages/conversation/searchMessage/index",
 					"style": {
@@ -3108,6 +3187,7 @@
 						}
 					}
 				},
+				
 				{
 					"path": "pages/conversation/notifyMessageList/index",
 					"style": {
@@ -3205,102 +3285,32 @@
 					}
 				},
 				{
-					"path": "pages/conversation/updateGroupOrNickname/index",
-					"style": {
-						"navigationBarTitleText": "",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black",
-						"disableScroll": true,
-						"app-plus": {
-							"bounce": "none"
-						}
-					}
-				},
-				// {
-				//   "path": "pages/moments/index/index",
-				//   "style": {
-				//     "navigationBarTitleText": "",
-				//     "enablePullDownRefresh": false,
-				//     "disableScroll": true,
-				//     "app-plus": {
-				//       "softinputMode": "adjustResize"
-				//     }
-				//   }
-				// },
-				// {
-				//   "path": "pages/moments/interactiveMessage/index",
-				//   "style": {
-				//     "navigationBarTitleText": "",
-				//     "enablePullDownRefresh": false
-				//   }
-				// },
-				// {
-				//   "path": "pages/moments/momentsDetails/index",
-				//   "style": {
-				//     "navigationBarTitleText": "",
-				//     "enablePullDownRefresh": false,
-				//     "app-plus": {
-				//       "softinputMode": "adjustResize"
-				//     }
-				//   }
-				// },
-				// {
-				//   "path": "pages/moments/momentsRelease/index",
-				//   "style": {
-				//     "navigationBarTitleText": "",
-				//     "enablePullDownRefresh": false
-				//   }
-				// },
-				// {
-				//   "path": "pages/moments/mementsVisibility/index",
-				//   "style": {
-				//     "navigationBarTitleText": "",
-				//     "enablePullDownRefresh": false
-				//   }
-				// },
-				// {
-				//   "path": "pages/moments/designatedMoments/index",
-				//   "style": {
-				//     "navigationBarTitleText": "",
-				//     "enablePullDownRefresh": false,
-				//     "app-plus": {
-				//       "softinputMode": "adjustResize"
-				//     }
-				//   }
-				// },
-				{
-					"path": "pages/common/globalSearch/index",
-					"style": {
-						"navigationBarTitleText": "搜素",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black",
-						"app-plus": {
-							"bounce": "none"
-						}
-					}
-				},
-				{
-					"path": "pages/common/globalChatLosPreview/index",
-					"style": {
-						"navigationBarTitleText": "",
-						"enablePullDownRefresh": false,
-						"disableScroll": true,
-						"navigationStyle": "custom"
-					}
-				},
-				{
-					"path": "pages/common/previewHistoryMessage/index",
-					"style": {
-						"navigationBarTitleText": "",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black",
-						"disableScroll": true
-					}
+				  "path": "pages/common/globalSearch/index",
+				  "style": {
+					"navigationBarTextStyle": "black",
+					"navigationBarTitleText": "",
+					"enablePullDownRefresh": false,
+					"disableScroll": true,
+					"navigationStyle": "custom"
+				  }
 				},
 				{
+				  "path": "pages/common/globalChatLosPreview/index",
+				  "style": {
+					"navigationBarTitleText": "",
+					"enablePullDownRefresh": false,
+					"disableScroll": true
+				  }
+				}
+				,{
+				  "path": "pages/common/previewHistoryMessage/index",
+				  "style": {
+					"navigationBarTitleText": "",
+					"enablePullDownRefresh": false,
+					"disableScroll": true
+				  }
+				}
+				,{
 					"path": "pages/common/createGroup/index",
 					"style": {
 						"navigationBarTitleText": "发起群聊",
@@ -3311,8 +3321,8 @@
 							"bounce": "none"
 						}
 					}
-				},
-				{
+				}
+				,{
 					"path": "pages/common/meetingCenter/index",
 					"style": {
 						"navigationBarTitleText": "视频会议",
@@ -3325,94 +3335,56 @@
 					}
 				},
 				{
-					"path": "pages/contact/index/index",
-					"style": {
+				  "path": "pages/profile/about/index",
+				  "style": {
 						"navigationBarTitleText": "",
 						"enablePullDownRefresh": false,
 						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
-				},
-				// {
-				// 	"path": "pages/contact/contactAdd/index",
-				// 	"style": {
-				// 		"navigationBarTitleText": "通讯录",
-				// 		"enablePullDownRefresh": false,
-				// 		"navigationStyle": "custom",
-				// 		"navigationBarTextStyle": "black"
-				// 	}
-				// },
-				// {
-				// 	"path": "pages/contact/switchJoinGroup/index",
-				// 	"style": {
-				// 		"navigationBarTitleText": "",
-				// 		"enablePullDownRefresh": false,
-				// 		"navigationStyle": "custom",
-				// 		"navigationBarTextStyle": "black"
-				// 	}
-				// },
-				{
-					"path": "pages/contact/friendList/index",
-					"style": {
-						"navigationBarTitleText": "我的好友",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+						"navigationBarTextStyle": "black",
+						"app-plus": {
+							"bounce": "none"
+						}
+				  }
 				},
-				// {
-				// 	"path": "pages/contact/groupList/index",
-				// 	"style": {
-				// 		"navigationBarTitleText": "我的群组",
-				// 		"enablePullDownRefresh": false,
-				// 		"navigationStyle": "custom",
-				// 		"navigationBarTextStyle": "black"
-				// 	}
-				// },
-				// {
-				// 	"path": "pages/contact/searchUserOrGroup/index",
-				// 	"style": {
-				// 		"navigationBarTitleText": "",
-				// 		"enablePullDownRefresh": false,
-				// 		"navigationStyle": "custom",
-				// 		"navigationBarTextStyle": "black"
-				// 	}
-				// },
 				{
-					"path": "pages/contact/applicationList/index",
-					"style": {
-						"navigationBarTitleText": "",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+				   "path": "pages/contact/friendList/index",
+				   "style": {
+				      "navigationBarTitleText": "我的好友",
+				      "enablePullDownRefresh": false,
+					  "navigationStyle": "custom",
+					  "navigationBarTextStyle": "black",
+					  "app-plus": {
+					  	"bounce": "none"
+					  }
+				   }
 				},
 				{
-					"path": "pages/contact/searchAddedFriend/index",
-					"style": {
-						"navigationBarTitleText": "搜索好友",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+				  "path": "pages/contact/searchAddedFriend/index",
+				  "style": {
+				    "navigationBarTitleText": "搜索好友",
+				    "enablePullDownRefresh": false,
+					"navigationStyle": "custom",
+					"navigationBarTextStyle": "black",
+				    "disableScroll": true
+				  }
 				},
 				{
-					"path": "pages/common/userCard/index",
-					"style": {
-						"navigationBarTitleText": "个人主页",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+				   "path": "pages/common/userCard/index",
+				   "style": {
+				     "navigationBarTitleText": "个人主页",
+				     "enablePullDownRefresh": false,
+					 "navigationStyle": "custom",
+					 "navigationBarTextStyle": "black"
+				   }
 				},
 				{
-					"path": "pages/common/userOrGroupQrCode/index",
-					"style": {
-						"navigationBarTitleText": "二维码",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+				   "path": "pages/common/userOrGroupQrCode/index",
+				   "style": {
+					  "navigationBarTitleText": "二维码",
+					  "enablePullDownRefresh": false,
+					  "navigationStyle": "custom",
+					  "navigationBarTextStyle": "black"
+				   }
 				},
 				{
 					"path": "pages/common/sendAddRequest/index",
@@ -3424,49 +3396,60 @@
 					}
 				},
 				{
-					"path": "pages/common/contactChoose/index",
-					"style": {
-						"navigationBarTitleText": "联系人",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+				  "path": "pages/common/contactChoose/index",
+				  "style": {
+				    "navigationBarTitleText": "联系人",
+				    "enablePullDownRefresh": false,
+				    "disableScroll": true,
+					"navigationBarTextStyle": "black",
+					 "navigationStyle": "custom",
+					 "app-plus": {
+					 	"bounce": "none"
+					 }
+				  }
 				},
 				{
-					"path": "pages/common/userCardMore/index",
-					"style": {
-						"navigationBarTitleText": "个人资料/好友设置",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+				  "path": "pages/common/userCardMore/index",
+				  "style": {
+				    "navigationBarTitleText": "个人资料/好友设置",
+				    "enablePullDownRefresh": false,
+					 "navigationStyle": "custom",
+					 "navigationBarTextStyle": "black",
+					 "app-plus": {
+					 	"bounce": "none"
+					 }
+				  }
 				},
 				{
-					"path": "pages/common/markOrIDPage/index",
-					"style": {
-						"navigationBarTitleText": "工作圈",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
-					}
+				  "path": "pages/common/markOrIDPage/index",
+				  "style": {
+				    "navigationBarTitleText": "工作圈",
+				    "enablePullDownRefresh": false,
+					"navigationStyle": "custom",
+					"navigationBarTextStyle": "black"
+				  }
 				},
 				{
-					"path": "pages/common/detailsFileds/index",
-					"style": {
-						"navigationBarTitleText": "个人资料明细",
-						"enablePullDownRefresh": false,
-						"navigationStyle": "custom",
-						"navigationBarTextStyle": "black"
+				  "path": "pages/common/detailsFileds/index",
+				  "style": {
+				    "navigationBarTitleText": "个人资料明细",
+				    "enablePullDownRefresh": false,
+					"navigationStyle": "custom",
+					"navigationBarTextStyle": "black",
+					"app-plus": {
+						"bounce": "none"
 					}
+				  }
 				},
 				{
 					"path": "pages/common/webH5/index",
 					"style": {
-						"navigationBarTitleText": "课程",
-						"enablePullDownRefresh": false,
-						"navigationBarTextStyle": "black"
+					"navigationBarTitleText": "课程",
+					"enablePullDownRefresh": false,
+					"navigationBarTextStyle": "black"
 					}
-				}
+					}
+		
 			]
 		},
 		{
@@ -3687,7 +3670,16 @@
 					"path": "videovip",
 					"style": {
 						"navigationBarTitleText": "看课详情",
-						"enablePullDownRefresh": false
+						"enablePullDownRefresh": false,
+						"app-plus": {
+							"screenOrientation": [
+								//可选,字符串数组类型,应用支持的横竖屏
+								"portrait-primary", //可选,字符串类型,支持竖屏
+								"portrait-secondary", //可选,字符串类型,支持反向竖屏
+								"landscape-primary", //可选,字符串类型,支持横屏
+								"landscape-secondary" //可选,字符串类型,支持反向横屏
+							]
+							}
 					}
 				},
 				{

+ 2 - 2
pages/shopping/productDetails.vue

@@ -1227,8 +1227,8 @@ import CustomToast from '@/components/custom-toast.vue';
 					margin-bottom: 30upx;
 
 					&.active {
-						background: #F1FFFE;
-						border: 1px solid #8AD5CE;
+						background: #fff;
+						border: 1px solid #FF233C;
 						color: #FF233C;
 					}
 				}

+ 1 - 1
pages/user/accountSafe.vue

@@ -79,7 +79,7 @@
 	    	);
 	    },
 		goToWeb(index){
-			uni.setStorageSync('url',"https://userapp.zkhj6.com/web/userRemoveService");
+			uni.setStorageSync('url',"https://userapp.klbycp.com/web/userRemoveService");
 			uni.navigateTo({
 				url:"/pages/index/h5"
 			})

+ 1 - 1
pages_course/becomeVIP.vue

@@ -133,7 +133,7 @@
 		onLoad(option) {
 			console.log(option)
 			// let path = 'https://userapp.fbylive.com'//福本源
-			let path = 'https://userapp.zkhj6.com'//中康
+			let path = 'https://userapp.klbycp.com'//中康
 			// let path = 'https://user.test.ylrztop.com/api'//云融融智
 			// let path = 'https://userapp.ashyisheng.com'//蜂巢快药
 			// let path = 'https://userapp.whhm.ylrzcloud.com/prod-api'//惠名大药房

+ 14 - 0
pages_course/video.vue

@@ -619,6 +619,11 @@
 						<image src="/static/images/more24.png" @click="showMore"></image>
 						<view class="tips">更多</view>
 					</view>
+					<view class="more-box" style="margin-left: 30rpx;position: relative;">
+						<image src="/static/images/kefu.png" @click="showMore"></image>
+						<view class="tips">客服</view>
+						<button class="contact-btn" open-type="contact"></button>
+					</view>
 					<image class="xianshi" v-if="showTreatment==0&&displayProductList.length>0&&!cardPopup" src="/static/images/xg.png"></image>
 					<view class="more-box" v-if="showTreatment==0">
 						<image  @click="showCart"  src="/static/images/cart.png"></image>
@@ -3844,6 +3849,15 @@
 		align-items: $alignI;
 		justify-content: $justifyC;
 	}
+	.contact-btn {
+		display: inline-block;
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		opacity: 0;
+	}
 	.notice-box{
 		padding: 12rpx 18rpx;
 		background: #FFF8F8;

+ 5764 - 0
pages_course/videovip - 副本 (2).vue

@@ -0,0 +1,5764 @@
+<template>
+	<view class="content ">
+		<!-- <view class="header-nav" :style="{height: `calc(88rpx + ${statusBarHeight}px)`,paddingTop: statusBarHeight + 'px'}"> -->
+		<!-- <u-icon name="arrow-left" size="28" @click="tosales" v-if="appToken"></u-icon> -->
+		<!-- <view class="header-title" :style="{width:menuButtonLeft + 'px',height:menuButtonH+'px',lineHeight:menuButtonH+'px'}">{{courseInfo.title}}</view>
+		</view> -->
+		
+		<view class="notice-box" v-if="isLogin&&isAddKf==1">
+			
+			<view class="notice-marquee-wrap">
+				<view class="notice-marquee-track">
+					<view class="notice-text"><image src="/static/images/course/notice.png"></image>{{notice || '央广网独家溯源&nbsp;&nbsp;全品类100%经过国标检测'}}</view>
+					<view class="notice-text"><image src="/static/images/course/notice.png"></image>{{notice || '央广网独家溯源&nbsp;&nbsp;全品类100%经过国标检测'}}</view>
+					<!-- <view class="notice-text"><image src="/static/images/notice.png"></image>央广网独家溯源&nbsp;&nbsp;全品类100%经过国标检测</view> -->
+				</view>
+			</view>
+		</view>
+		<view class="video-box" :style="{'height':isShu?'calc(100vh - 264rpx)':'420rpx'}" >
+			<image v-if="!isLogin || isAddKf!=1" class="video-poster" :src="courseInfo.imgUrl" mode="aspectFill">
+			</image>
+			<video @timeupdate="onTimeUpdate" @progress="progressChange" @error="videoErrorCallback" @play="getPlay"
+				@pause="getPause" @ended="getEnded" @fullscreenchange="fullscreenchange" :title="courseInfo.title" 
+				style="width: 100%;" :style="{'height':isShu?'100%':'420rpx'}" :poster="poster" id="video-content-box" controls
+				:auto-pause-if-open-native="false" :auto-pause-if-navigate="true" :enable-progress-gesture="false"
+				:show-progress="true" :picture-in-picture-mode="[]" :show-background-playback-button="false"
+				:src="videoUrl">
+					<cover-view v-if="remainTime > 0" class="progress-countdown">
+						<cover-view class="progress-title">完课积分</cover-view>
+						<!-- <cover-image class="progress-img" src="/static/images/course/wk.png"></cover-image> -->
+						<!-- <cover-view class="progress-bar-bg">
+							<cover-view class="progress-bar-fill" :style="{ width: countdownPercentage + '%' }"></cover-view>
+						</cover-view> -->
+						<cover-view class="progress-text">
+							<cover-view class="progress-text-label">倒计时</cover-view>
+							<cover-view style="font-size: 13px;">{{ formattedCountdown.hours||'00' }}:{{ formattedCountdown.minutes||'00' }}:{{ formattedCountdown.seconds||"00" }}</cover-view>
+						</cover-view>
+					</cover-view>
+					<!-- 虚拟下单跑马灯:视频顶层覆盖,向上滚动淡出切换 -->
+					<cover-view class="vip-order-cover-wrap vip-order-cover-wrap--triple" v-if="showFakeMarqueeOnVideoCover && isTripleMarqueeMode && marqueeTriplePayloads.length">
+						<cover-view class="vip-order-cover-triple-panel vip-order-cover-triple-current" :class="[marqueeTripleSwitching ? 'vip-order-triple-leave' : '']">
+							<cover-view
+								class="vip-order-cover-item vip-order-cover-triple-item"
+								v-for="(row, idx) in marqueeTriplePayloads"
+								:key="'triple-current-' + idx + '-' + row.nickname + row.timeOffset"
+								:class="[row.type === 'self' ? 'vip-order-cover-self' : '']"
+							>
+								<cover-view class="vip-order-cover-content" v-if="row.type === 'virtual' || row.type === 'self'">
+									<cover-view class="vip-order-seg vip-order-seg-user">{{ row.nickname }}{{ row.maskedId }}</cover-view>
+									<cover-view class="vip-order-seg vip-order-seg-time">{{ row.timeOffset }}{{ row.suffix }}</cover-view>
+									<!-- <cover-view class="vip-order-seg vip-order-seg-suffix"></cover-view> -->
+								</cover-view>
+								<cover-view class="vip-order-cover-content" v-else>
+									{{ row.fullText }}
+								</cover-view>
+							</cover-view>
+						</cover-view>
+						<cover-view v-if="marqueeTripleSwitching && marqueeTripleIncomingPayloads.length" class="vip-order-cover-triple-panel vip-order-cover-triple-incoming vip-order-triple-enter">
+							<cover-view
+								class="vip-order-cover-item vip-order-cover-triple-item"
+								v-for="(row, idx) in marqueeTripleIncomingPayloads"
+								:key="'triple-incoming-' + idx + '-' + row.nickname + row.timeOffset"
+								:class="[row.type === 'self' ? 'vip-order-cover-self' : '']"
+							>
+								<cover-view class="vip-order-cover-content" v-if="row.type === 'virtual' || row.type === 'self'">
+									<cover-view class="vip-order-seg vip-order-seg-user">{{ row.nickname }}{{ row.maskedId }}</cover-view>
+									<cover-view class="vip-order-seg vip-order-seg-time">{{ row.timeOffset }}{{ row.suffix }}</cover-view>
+									<!-- <cover-view class="vip-order-seg vip-order-seg-suffix"></cover-view> -->
+								</cover-view>
+								<cover-view class="vip-order-cover-content" v-else>
+									{{ row.fullText }}
+								</cover-view>
+							</cover-view>
+						</cover-view>
+					</cover-view>
+					<cover-view class="vip-order-cover-wrap" v-else-if="showFakeMarqueeOnVideoCover && marqueeDisplayPayload">
+						<cover-view
+							class="vip-order-cover-item vip-order-cover-current"
+							:class="[
+								marqueeSwitching ? 'vip-order-leave' : '',
+								marqueeDisplaySelf ? 'vip-order-cover-self' : ''
+							]"
+						>
+							<cover-view class="vip-order-cover-content" v-if="marqueeDisplayPayload.type === 'virtual' || marqueeDisplayPayload.type === 'self'">
+								<cover-view class="vip-order-seg vip-order-seg-user">{{ marqueeDisplayPayload.nickname }}{{ marqueeDisplayPayload.maskedId }}</cover-view>
+								<cover-view class="vip-order-seg vip-order-seg-time">{{ marqueeDisplayPayload.timeOffset }}{{ marqueeDisplayPayload.suffix }}</cover-view>
+								<!-- <cover-view class="vip-order-seg vip-order-seg-suffix"></cover-view> -->
+							</cover-view>
+							<cover-view class="vip-order-cover-content" v-else>
+								{{ marqueeDisplayPayload.fullText }}
+							</cover-view>
+						</cover-view>
+						<cover-view
+							v-if="marqueeSwitching && marqueeIncomingPayload"
+							class="vip-order-cover-item vip-order-cover-incoming"
+							:class="[
+								'vip-order-enter',
+								marqueeIncomingSelf ? 'vip-order-cover-self' : ''
+							]"
+						>
+							<cover-view class="vip-order-cover-content" v-if="marqueeIncomingPayload.type === 'virtual' || marqueeIncomingPayload.type === 'self'">
+								<cover-view class="vip-order-seg vip-order-seg-user">{{ marqueeIncomingPayload.nickname }}{{ marqueeIncomingPayload.maskedId }}</cover-view>
+								<cover-view class="vip-order-seg vip-order-seg-time">{{ marqueeIncomingPayload.timeOffset }}{{ marqueeIncomingPayload.suffix }}</cover-view>
+								<!-- <cover-view class="vip-order-seg vip-order-seg-suffix"></cover-view> -->
+							</cover-view>
+							<cover-view class="vip-order-cover-content" v-else>
+								{{ marqueeIncomingPayload.fullText }}
+							</cover-view>
+						</cover-view>
+					</cover-view>
+					<cover-view
+					  class="goods-cover"
+					  v-if="isFull && cardPopup && currentCardItem"
+					  @click.stop="goBuy(currentCardItem)"
+					>
+					  
+					  <cover-view class="goods-cover-hot" v-if="hasHotSaleTag(currentCardItem) && getProductHotCount(currentCardItem) > 0">
+					  <cover-image style="height: 30px;" src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/class/remai.png" mode="heightFix"></cover-image>
+					    <cover-view class="goods-cover-hot-text">{{ getProductHotCount(currentCardItem) }}</cover-view>
+					  </cover-view>
+					
+					  <cover-view class="goods-cover-inner">
+						  <!-- 关闭按钮 -->
+						  <cover-view class="close-box" @click.stop="closeCardPopup">
+						    <cover-image src="/static/images/course/close.png"></cover-image>
+						  </cover-view>
+					    <!-- 商品主图 -->
+					    <cover-view class="goods-cover-img">
+							<cover-image 
+							    v-if="currentCardItem && currentCardItem.images"
+							    style="width:150px;height:150px;object-fit:cover;"
+							    :src="currentCardItem.images"
+							    mode="aspectFit"
+							  ></cover-image>
+						</cover-view>
+					    <cover-view class="goods-cover-info">
+					      <cover-view class="goods-cover-title">{{ currentCardItem.productName || '-' }}</cover-view>
+					      
+					      <cover-view class="goods-cover-bottom">
+					        <cover-view class="goods-cover-tag">
+					          <cover-image class="goods-cover-tag-bg" src="/static/images/course/pbg.png" mode="widthFix"></cover-image>
+					          <cover-view class="goods-cover-tag-text">惊喜价</cover-view>
+					        </cover-view>
+					        
+					        <cover-view class="goods-cover-price">
+					          <cover-view class="unit">¥</cover-view>
+					          <cover-view class="price">
+					            {{ currentCardItem.price || '0.00' }}
+					          </cover-view>
+					        </cover-view>
+					      </cover-view>
+					    </cover-view>
+					  </cover-view>
+					</cover-view>
+			</video>
+		</view>
+		<!-- 商品卡片弹窗 -->
+		<view class="goods-card" :style="{'bottom':isShu?'280rpx':'220rpx'}" v-if="!isFull&&cardPopup && currentCardItem" @click.stop="goBuy(currentCardItem)">
+			<view class="close-box" @click.stop="closeCardPopup">
+				<image src="/static/images/course/close.png"></image>
+			</view>
+			<view class="goods-card-hot" v-if="hasHotSaleTag(currentCardItem) && getProductHotCount(currentCardItem) > 0">
+				<image style="height: 56rpx;" src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/class/remai.png" mode="heightFix"></image>
+				<text class="goods-card-hot-count">{{ getProductHotCount(currentCardItem) }}</text>
+			</view>
+			<view class="goods-card-inner">
+				<image class="goods-card-img" :src="currentCardItem.images" mode="aspectFill"></image>
+				<view class="goods-card-info">
+					<view class="goods-card-title">{{ currentCardItem.productName || '-' }}</view>
+					<view class="goods-card-bottom">
+						<view class="goods-card-tag">
+							<image class="goods-card-tag-bg" src="/static/images/course/pbg.png" mode="widthFix"></image>
+							<view class="goods-card-tag-text">惊喜价</view>
+						</view>
+						<view class="goods-card-price">
+							<view class="unit">¥</view>
+							<text class="price">
+								{{ currentCardItem.price || '0.00' }}
+							</text>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- <view v-if="remainTime > 0" class="progress-countdown end">
+			<view class="progress-title">完课积分</view>
+			<view class="progress-bar-bg">
+				<view class="progress-bar-fill" :style="{ width: countdownPercentage + '%' }"></view>
+			</view>
+			<view class="progress-text">
+				<text style="font-size: 24rpx;line-height: 40rpx;">倒计时</text>{{ formattedCountdown.hours||'00' }}:{{ formattedCountdown.minutes||'00' }}:{{ formattedCountdown.seconds||"00" }}
+			</view>
+		</view> -->
+		<!-- <view class="justify-start align-center fs24 base-color-9" v-if="userInfo.userId">
+			<view>{{nameuser?nameuser:'暂未授权昵称'}}#</view>
+			<view>{{userInfo.userId}}</view>
+		</view> -->
+		<!-- <view class="title-content" id="title-content"> -->
+			<!-- 答题时展示小节课程名,其他展示课程名 -->
+			<!-- 小节课程名 -->
+			<!-- <view class="subtitlebox " v-if="isLogin&&isAddKf==1">
+				{{courseInfo.title}}
+			</view> -->
+			<!-- 课程名字 -->
+			<!-- <view class="miantitlebox" v-else>
+				{{courseInfo.courseName}}
+			</view> -->
+		<!-- </view> -->
+		<!-- <scroll-view  style="display:none;"  v-show="!isShu" class="scroll-view" :style="{height: height}" :scroll-top="scrollTop" scroll-y="true"> -->
+			<!-- 无效或者已过期 -->
+			<!-- <view class="nocourse" v-if="msg">
+				<image :src="imgPath+'/app/image/course_expiration_img.png'" mode="widthFix"></image>
+				<view>{{msg}}</view>
+			</view> -->
+			<!-- 问题 -->
+			<!-- <view class="ques-content" v-if="isLogin&&isAddKf==1&&!isquestion">
+				<view v-if="isLogin">
+					<view class="ques-content-tit" v-if="!isquestion"
+						@click="tabChange(0)">问答题</view> -->
+					<!-- <view class="ques-content-tit" v-if="showTreatment==0"
+						:style="{ color: currentId==1? '#FF5C03':'#222'}" @click="tabChange(1)">商品</view> -->
+				<!-- </view> -->
+					<!-- <view v-for="(item,index) in quesList" :key="index">
+						<view class="ques-title">
+							<text>{{index + 1}}.</text> -->
+							<!-- <view class="ques-type" v-show="item.type == 1 || item.type == 2">
+								{{item.type == 1 ? '单选' : item.type == 2 ? '多选' : ''}}
+							</view> -->
+				<!-- 			<text class="fs40">{{item.title}}</text>
+						</view>
+						<view :class="isAnswer(item,option.name) ?'ques-option ques-option-active':'ques-option'"
+							v-for="(option,idx) in item.questionOption" :key="idx" @click="handleAnswer(item,option)">
+							<view class="fs40">
+								{{numberToLetter(idx)}}.
+							</view>
+							<view class="fs40">{{option.name}}</view>
+						</view>
+					</view>
+			</view>
+		</scroll-view> -->
+		<!-- 评价 -->
+		<view class="rating-box" :style="{paddingTop:visibleRatingTabCount == 1?'30rpx':'24rpx'}"  v-if="isLogin&&isAddKf==1&&!isShu&&hasVisibleRatingTab">
+			<image class="bg" src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/bg-back.png" mode="widthFix"></image>
+			<view class="tab-Box" v-if="visibleRatingTabCount > 1">
+				<view
+					v-for="tab in ratingTabList"
+					:key="tab.key"
+					class="tab-item"
+					:class="{ 'tab-item--active': tabIndex == tab.index }"
+					@click="selecTab(tab.index)"
+				>
+					<view class="tab-item__surface">
+						<image :src="tabIndex == tab.index ? tab.iconActive : tab.icon" mode="aspectFit"></image>
+						<text class="tab-item__text">{{ tab.label }}</text>
+					</view>
+				</view>
+			</view>
+			<!-- 仅一个 Tab:单行左对齐标题,无选中态(顺序:精选留言 / 栏目介绍 / 评价得积分) -->
+			<view class="tab-Box tab-Box--single" v-else-if="visibleRatingTabCount === 1">
+				<view v-for="tab in ratingTabList" :key="tab.key" class="tab-item tab-item--single">
+					<view class="tab-item__surface tab-item__surface--single">
+						<image :src="tab.iconActive" mode="aspectFit"></image>
+						<text class="tab-item__text tab-item__text--single">{{ tab.label }}</text>
+					</view>
+				</view>
+			</view>
+			<view class="rating-body" v-if="tabIndex == 2 && showTabReviewPoints">
+				<view class="rating-ques-block" v-for="(item,index) in quesList" :key="index">
+					<view class="title">{{item.title}}</view>
+					<view class="sat-box">
+						<view class="sat" v-for="(option,idx) in item.questionOption" :key="idx"  :class="aindex==option.indexId?'sat--active':''" @click="handleAnswer(item,option)">
+							<view class="sat-img-wrap" :class="rateBounceIndex==option.indexId?'sat-img-bounce':''">
+								<image :src="aindex==option.indexId?rateList[option.indexId].selIcon:rateList[option.indexId].icon" mode="aspectFit"></image>
+							</view>
+							<text :class="aindex==option.indexId?'active':''">{{option.name}}</text>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="rating-body rating-body--plain" :style="{padding:courseInfo.courseIntroImg?'0rpx':'30rpx'}"  v-if="tabIndex === 1 && showTabColumnIntro">
+				<!-- <view class="title">{{ (courseInfo && courseInfo.title) || '栏目介绍' }}</view> -->
+				<image
+					class="rating-intro-cover-img"
+					:src="courseInfo.courseIntroImg"
+					mode="widthFix"
+				></image>
+			</view>
+			<view class="rating-body rating-body--featured" v-if="tabIndex == 0 && showTabFeaturedComments">
+				<scroll-view
+					scroll-y
+					class="rating-msg-scroll"
+					:show-scrollbar="false"
+					lower-threshold="100"
+					@scrolltolower="onFeaturedCommentScrollToLower"
+				>
+					<view v-if="featuredCommentLoading" class="rating-msg-empty">加载中...</view>
+					<template v-else>
+						<view
+							class="rating-msg-item"
+							v-for="(it, idx) in featuredCommentDisplayList"
+							:key="it.commentId"
+						>
+							<view class="rating-msg-avatar-wrap">
+								<image
+									class="rating-msg-avatar"
+									src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/head.png"
+									mode="aspectFill"
+								/>
+							</view>
+							<view class="rating-msg-main">
+								<text class="rating-msg-name">{{ getCommentDisplayName(it) }}</text>
+								<view class="rating-msg-text">{{ getCommentTextOnly(it) }}</view>
+								<view v-if="getCommentVideoUrl(it)" class="rating-msg-media rating-msg-media--video">
+									<view class="rating-msg-video-wrap">
+										<video
+											:id="getFeaturedCommentVideoId(it, idx)"
+											class="rating-msg-video"
+											:src="getCommentVideoUrl(it)"
+											:poster="getCommentVideoPoster(it)"
+											:controls="false"
+											object-fit="fill"
+											:show-play-btn="false"
+											:show-center-play-btn="false"
+											:enable-progress-gesture="false"
+										></video>
+										<view
+											class="rating-msg-video-play-cover"
+											@tap.stop="openFeaturedCommentMediaPreview(it, idx, 'video')"
+										>
+											<image
+												class="rating-msg-video-play-icon"
+												src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/bofang.png"
+												mode="aspectFit"
+											/>
+										</view>
+									</view>
+								</view>
+								<view
+									v-else-if="commentImageUrls(it).length"
+									class="rating-msg-media rating-msg-media--imgs"
+								>
+									<image
+										v-for="(img, mi) in commentImageUrls(it)"
+										:key="mi"
+										:src="img"
+										mode="widthFix"
+										class="rating-msg-img"
+										@click="openFeaturedCommentMediaPreview(it, idx, 'image', mi)"
+									/>
+								</view>
+							</view>
+						</view>
+						<view v-if="!featuredCommentDisplayList.length" class="rating-msg-empty">暂无精选留言</view>
+						<view v-if="featuredCommentLoadingMore" class="rating-msg-load-more">加载中...</view>
+						<view
+							v-else-if="showFeaturedCommentNoMoreFooter"
+							class="rating-msg-load-more rating-msg-load-more--done"
+						>没有更多了</view>
+						<!-- 底部锚点:发布成功后 scroll-into-view 定位到最新消息一侧,避免留在顶部 -->
+						<view id="fc-scroll-anchor" class="rating-msg-scroll-anchor"></view>
+					</template>
+				</scroll-view>
+			</view>
+		</view>
+		<!-- 线路 -->
+		<!-- <view class="video-line" @click="openPop" v-if="isLogin&&isAddKf==1">
+			<image :src="imgPath+'/app/image/changePlayer-icon.png'"></image>
+			<text>线路{{lineIndex + 1 | numberToChinese}}</text>
+		</view> -->
+		<!-- 线路弹窗 -->
+		<!-- <uni-popup ref="popup" type="bottom"  class="full-width-popup">
+			<view class="popupbox">
+				<view class="popupbox-head">
+					<text>线路选择</text>
+					<image class="close-icon" :src="imgPath+'/app/image/tc_close_icon.png'" mode="aspectFill" @click="close">
+					</image>
+				</view>
+				<view class="popupbox-content">
+					<view :class="lineIndex == index ? 'line-item line-active': 'line-item'"
+						v-for="(it,index) in lineList" :key="index" @click="handleLine(index)">
+						线路{{index + 1 | numberToChinese}}</view>
+				</view>
+			</view>
+		</uni-popup> -->
+		<!-- 温馨提示弹窗 -->
+		<u-popup :show="tipsPopup" mode="center" :closeOnClickOverlay='true' @close='tipsPopup=!tipsPopup'
+			:safeAreaInsetBottom='false' round='12'>
+			<view class="tipsPopup-mask">
+				<image class="red_envelope_top" :src="imgPath+'/app/image/red_envelope_img.png'" mode="aspectFill">
+				</image>
+				<view class="tipsPopup">
+					<image class="tipsPopup-close" :src="imgPath+'/app/image/course_close_white_icon.png'"
+						mode="aspectFill" @click="closeTipsPop"></image>
+					<view class="tipsPopup-line">
+						<view class="tipsPopup-box">
+							<view class="tipsPopup-head">
+								<image class="tipsPopup-head-title" :src="imgPath+'/app/image/tips_title_img.png'"
+									mode="widthFix"></image>
+							</view>
+							<view class="tipsPopup-content">
+								<view class="tipsPopup-content-title">亲爱的用户,</view>
+								<view>您已经观看课程{{timepath}}的时间了,请注意休息并保持专注。</view>
+							</view>
+							<view class="tipsPopup-btn-box">
+								<view class="tipsPopup-btn" @click="closeTipsPop">继续观看领奖励</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</u-popup>
+		<!-- 答题弹窗 -->
+		<u-popup :show="answerPopup" mode="center" @close="closepop()" @open="open" closeOnClickOverlay
+			:safeAreaInsetBottom='false' round='12'>
+			<view :class="errTitle == '恭喜你,回答正确' ? 'answerPopup-box bg':'answerPopup-box'">
+				<!-- 正确 -->
+				<image class="tipimg" v-if="errTitle == '恭喜你,回答正确'" :src="imgPath+'/app/image/course_answer_img.png'"
+					mode="aspectFill"></image>
+				<!-- 错误 -->
+				<image class="tipimg" v-else :src="imgPath+'/app/image/course_answer_incorrectly_img.png'"
+					mode="aspectFill">
+				</image>
+				<view class="answerPopup-title">{{errTitle}}</view>
+				<view class="answerPopup-desc" v-html="errDesc"></view>
+				<!-- 选择奖励 -->
+				<!-- 错误题目 -->
+				<view class="errQuesbox" v-if="errQues&&errQues.length>0">
+					<view class="errQuesbox-item textOne" v-for="(it,index) in errQues" :key="index">{{it.title}}</view>
+				</view>
+				<view class="answerPopup-btn" v-if="errTitle == '恭喜你,回答正确'" @click="closeAnswerPopup">点击领取红包</view>
+				<view class="tipsPopup-btn-box" v-else
+					:style="{marginTop: errQues&&errQues.length>0 ? '40rpx':'54rpx'}">
+					<view class="tipsPopup-btn" @click="closeAnswerPopup">{{remain > 0 ? '重新答题': '确认'}}</view>
+				</view>
+			</view>
+		</u-popup>
+		<!-- 客服二维码弹窗 -->
+		<u-popup :show="kfPopup" mode="center" :mask-click="false" round='12' @close="kefpop">
+			<view class="kfqrcode-box">
+				<view class="justify-start align-center fs24 base-color-9">
+					<view>{{userInfo.nickName || '用户'}}#</view>
+					<view>{{userInfo.userId}}</view>
+				</view>
+				<view>请添加客服</view>
+				<image class="kfqrcode" :src="qrcode" show-menu-by-longpress="true" mode="aspectFit"></image>
+				<!-- <view v-show="qrcodeMsg" style="margin-top: 30rpx;" v-html="qrcodeMsg"></view> -->
+				<!-- <image class="kfqrcode-close" :src="imgPath+'/app/image/course_close_white_icon.png'" mode="aspectFill"
+					@click="closeKFPop"></image> -->
+			</view>
+		</u-popup>
+		<u-popup :show="timepop" mode="center" round='12'>
+			<view class="timepopbox center column">
+				<view class="fs40 bold ">不在看课时间范围内</view>
+				<view class="mtb20">看课时间</view>
+				<view>{{videocont.startDateTime}}</view>
+				<view>至</view>
+				<view>{{videocont.endDateTime}}</view>
+				<view class="base-bg-orange colorf p20 radius50 mt20" @click="getH5CourseVideoDetails">刷新时间</view>
+			</view>
+		</u-popup>
+		<u-popup :show="isCart"  @close="closeShop" round="20rpx" bgColor="#fff">
+			<scroll-view class="scroll-view" style="height:500rpx;box-sizing: border-box;padding: 24rpx;" scroll-y="true" enable-flex>
+				<goodsList ref="goodsList" :treatmentPackage="displayProductList" :hotCountMap="productHotCountMap" :urlOption="urlOption"></goodsList>
+			</scroll-view>
+		</u-popup>
+		<u-popup :show="isMore"  @close="closeMore" round="20rpx" bgColor="#fff">
+			<view class="more-actions-popup">
+				<view class="more-action-item"
+					@click="navgetTo('/pages_user/user/storeOrder?status=')">
+					<u-icon name="shopping-cart" color="#FF233C" size="40"></u-icon>
+					<view class="action-label">我的订单</view>
+				</view>
+				<view class="more-action-item"
+					@click="navgetTo('/pages_user/user/integralLogsList')">
+					<u-icon name="calendar" color="#FF233C" size="40"></u-icon>
+					<view class="action-label">积分记录</view>
+				</view>
+				<view class="more-action-item" @click="navgetTo('/pages_user/user/integralGoodsList')">
+					<u-icon name="gift" color="#FF233C" size="40"></u-icon>
+					<view class="action-label">兑换好礼</view>
+				</view>
+			</view>
+		</u-popup>
+		<u-popup
+			:show="featuredMediaActionSheetShow"
+			mode="bottom"
+			round="20rpx"
+			bgColor="#fff"
+			:duration="300"
+			@close="closeFeaturedMediaActionSheet"
+		>
+			<view class="fc-media-actions-sheet">
+				<view class="fc-media-actions-sheet-item" @tap.stop="onFeaturedMediaSheetPick(0)">相册图片</view>
+				<view class="fc-media-actions-sheet-item" @tap.stop="onFeaturedMediaSheetPick(1)">相册视频</view>
+				<!-- <view class="fc-media-actions-sheet-gap"></view> -->
+				<view
+					class="fc-media-actions-sheet-item fc-media-actions-sheet-cancel"
+					@tap.stop="closeFeaturedMediaActionSheet"
+				>取消</view>
+			</view>
+		</u-popup>
+		<!-- <view class="footer-tips">重庆云联融智提供技术支持</view> -->
+		<!-- footer -->
+		<view class="footer" v-if="videoId">
+			<view class="btns" :style="{'justify-content':isLogin&&isAddKf==1&&remainTime==0&&hasVisibleRatingTab&&!showTabColumnIntro?'space-between':'flex-end'}">
+				<template>
+					<button class="author-btn" @click="openList" v-if="isLogin&&isAddKf==1&&isShu&&(showTabFeaturedComments || showTabColumnIntro || showTabReviewPoints)">{{ showTabFeaturedComments ? '去留言' : showTabColumnIntro ? '栏目介绍' : '评价得积分' }}
+					<image v-if="showTabReviewPoints&&!showTabFeaturedComments&&!showTabColumnIntro" src="/static/images/course/jifen.png"></image></button>
+					<button class="author-btn" @click="submit" v-if="isLogin&&isAddKf==1&&remainTime==0&&!isShu&&tabIndex==2">评价得积分
+					<image src="/static/images/course/jifen.png"></image>
+					</button>
+				</template>
+				<button class="author-btn" @click="submit" v-if="!isLogin&&isAddKf!==1">立即学习</button>
+					<!-- 竖屏 isShu 下 rating 区隐藏;若仍停留在精选留言 tab,勿在 footer 展示留言框,只保留「评价得积分」按钮(与 _expandLayoutIfPortraitFeaturedCommentsOnly 竖屏体验一致) -->
+					<view v-if="tabIndex==0 && showTabFeaturedComments&&!isShu" class="rating-msg-input-shell">
+						<view
+							v-if="featuredCommentMedia"
+							class="rating-msg-media-pill"
+							@click.stop="clearFeaturedCommentMedia"
+						>
+							<image
+								v-if="featuredCommentMedia.type === 'image'"
+								class="rating-msg-media-thumb"
+								:src="featuredCommentMedia.path"
+								mode="aspectFill"
+							/>
+							<image
+								v-else
+								class="rating-msg-media-thumb"
+								:src="featuredCommentMedia.thumbTempPath || featuredCommentMedia.path"
+								mode="aspectFill"
+							/>
+							<view v-if="featuredCommentMedia.type === 'video'" class="rating-msg-media-badge">视频</view>
+							<text class="rating-msg-media-x">×</text>
+						</view>
+						<view class="rating-msg-input rating-msg-input-trigger" @tap.stop="openFeaturedCommentComposer">
+							<text
+								class="rating-msg-input-trigger-text"
+								:class="{ 'is-ph': !featuredCommentInput }"
+							>{{ featuredCommentInput || '善言善语结善缘~' }}</text>
+						</view>
+						<view class="rating-msg-input-icon" @tap.stop="openFeaturedCommentComposer">
+							<image src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/upimg.png"></image>
+						</view>
+					</view>
+				<view class="author-cart" v-show="!(tabIndex === 0 && showTabFeaturedComments && isLogin && isAddKf == 1 && !isquestion && !isShu)">
+					<view class="more-box">
+						<image src="/static/images/course/more24.png" @click="showMore"></image>
+						<view class="tips">更多</view>
+					</view>
+					<image class="xianshi" v-if="showTreatment==0&&displayProductList.length>0&&!cardPopup" src="/static/images/course/xg.png"></image>
+					<view class="more-box" v-if="showTreatment==0">
+						<image  @click="showCart"  src="/static/images/course/cart.png"></image>
+						<view class="tips">去下单</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- 更多操作弹窗 -->
+		<view>
+			<u-modal :show="showfalse" title="提示" :content='contentmsg' @confirm='showfalse=false'></u-modal>
+		</view>
+		<u-loading-page :loading="viewload" iconSize="32" loadingColor="#3c9cff" fontSize="24"
+			:loading-text="loadingtext"></u-loading-page>
+		<ykscreenRecord></ykscreenRecord>
+		<template v-if="tabIndex==0 && showTabFeaturedComments && !(showTabReviewPoints && isShu)">
+			<view
+				v-if="featuredCommentComposerActive"
+				class="featured-comment-composer-mask"
+				@tap="onFeaturedCommentComposerMaskTap"
+			></view>
+			<view
+				v-if="featuredCommentComposerActive"
+				class="featured-comment-composer-wrap"
+				:style="{ bottom: featuredCommentKeyboardBottomPx + 'px' }"
+			>
+				<view class="featured-comment-composer-inner">
+					<view
+						v-if="featuredCommentMedia"
+						class="fc-composer-media-pill"
+						@click.stop="clearFeaturedCommentMedia"
+					>
+						<image
+							v-if="featuredCommentMedia.type === 'image'"
+							class="fc-composer-media-thumb"
+							:src="featuredCommentMedia.path"
+							mode="aspectFill"
+						/>
+						<image
+							v-else
+							class="fc-composer-media-thumb"
+							:src="featuredCommentMedia.thumbTempPath || featuredCommentMedia.path"
+							mode="aspectFill"
+						/>
+						<view v-if="featuredCommentMedia.type === 'video'" class="fc-composer-media-badge">视频</view>
+						<text class="fc-composer-media-x">×</text>
+					</view>
+					<view class="featured-comment-composer-input-row">
+						<textarea
+							class="fc-composer-input"
+							v-model="featuredCommentInput"
+							type="text"
+							confirm-type="done"
+							:show-confirm-bar="false"
+							placeholder="善言善语结善缘~"
+							placeholder-class="fc-composer-ph"
+							:focus="featuredCommentInputFocused"
+							:adjust-position="false"
+							@blur="onFeaturedCommentComposerInputBlur"
+						/>
+						<view class="fc-composer-input-icon" @click.stop="onFeaturedPickMedia">
+							<image src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/upimg.png"></image>
+						</view>
+					</view>
+					<view class="featured-comment-composer-publish" @tap.stop="submitFeaturedComment">发布</view>
+				</view>
+			</view>
+		</template>
+		<!-- 精选留言:图片/视频放大查看(自定义弹窗,替代系统预览) -->
+		<view
+			v-if="featuredCommentMediaPreviewShow"
+			class="fc-media-preview-mask"
+			@tap="closeFeaturedCommentMediaPreview"
+		>
+			<view class="fc-media-preview-card" @tap.stop="featuredCommentPreviewCardTap">
+				<view
+					v-if="featuredCommentMediaPreviewMode === 'image' && featuredCommentMediaPreviewUrls.length"
+					class="fc-media-preview-img-box"
+				>
+					<view class="fc-media-preview-slide">
+						<image
+							class="fc-media-preview-main-img"
+							:src="featuredCommentMediaPreviewUrls[featuredCommentMediaPreviewIndex]"
+							mode="aspectFit"
+						/>
+					</view>
+				</view>
+				<view
+					v-else-if="featuredCommentMediaPreviewMode === 'video' && featuredCommentMediaPreviewVideoUrl"
+					class="fc-media-preview-video-box"
+				>
+					<video
+						id="fc-media-preview-video"
+						class="fc-media-preview-video"
+						:src="featuredCommentMediaPreviewVideoUrl"
+						:poster="featuredCommentMediaPreviewPoster"
+						controls
+						:show-center-play-btn="true"
+						:show-play-btn="true"
+						:show-fullscreen-btn="false"
+						:auto-pause-if-open-native="false"
+						:auto-pause-if-navigate="true"
+						:enable-progress-gesture="true"
+						:show-background-playback-button="false"
+						@play="onFeaturedMediaPreviewModalVideoPlay"
+					/>
+				</view>
+				<view class="fc-media-preview-footer">
+					<scroll-view
+						v-if="featuredCommentMediaPreviewMode === 'image' && featuredCommentMediaPreviewUrls.length > 1"
+						scroll-x
+						class="fc-media-preview-thumbs"
+						:show-scrollbar="false"
+					>
+						<view class="fc-media-preview-thumbs-inner">
+							<image
+								v-for="(tu, ti) in featuredCommentMediaPreviewUrls"
+								:key="'t-' + ti"
+								class="fc-media-preview-thumb"
+								:class="{ 'fc-media-preview-thumb--active': ti === featuredCommentMediaPreviewIndex }"
+								:src="tu"
+								mode="aspectFill"
+								@tap.stop="setFeaturedMediaPreviewIndex(ti)"
+							/>
+						</view>
+					</scroll-view>
+					<view v-else class="fc-media-preview-thumbs-spacer" />
+					<view class="fc-media-preview-close" @tap.stop="closeFeaturedCommentMediaPreview">
+						<!-- <text class="fc-media-preview-close-x">×</text> -->
+						<u-icon name="close-circle" color="#fff" size="30"></u-icon>
+					</view>
+				</view>
+			</view>
+		</view>
+		<courseExpiration v-if="showExpiration" :code="resCode" :msg="resMsg" :qrcode="qrcode"
+			:userId="user && userInfo.userId ? userInfo.userId : ''"></courseExpiration>
+	</view>
+</template>
+
+<script>
+	import goodsList from "./components/goodsList.vue"
+	import { hasHotSaleTag, getProductHotKey, clampHotSaleCount } from './utils/productHotSale.js'
+	import {
+		generateRandomString
+	} from "@/utils/common.js"
+	import {
+		buildFakeOrderPool
+	} from './utils/videovipFakeMarquee.js'
+	import dayjs from 'dayjs';
+	import {
+		mapGetters
+	} from 'vuex';
+	import ykscreenRecord from "@/components/yk-screenRecord/yk-screenRecord.vue"
+	import courseExpiration from './components/courseExpiration.vue'
+	import {
+		getErrMsg,
+		getH5CourseByVideoId,
+		getH5CourseVideoDetails,
+		courseAnswer,
+		getFinishCourseVideo,
+		getIsAddKf,
+		getInternetTraffic,
+		getIntegralByH5Video,
+		sendReward,
+		getRemainTime,
+		getCommentList,
+		addCommentWithMedia
+	} from "@/api/courseLook.js"
+	import {
+		getConfigByKey
+	} from "@/api/user.js"
+	export default {
+		components: {
+			ykscreenRecord,
+			courseExpiration,
+			goodsList
+		},
+		data() {
+			return {
+				displayType:'',
+				isMore:false,//更多
+				isCart:false,//购物车
+				isShu:false,//竖屏默认
+				aindex:null,
+				rateBounceIndex: null,
+				_rateBounceTimer: null,
+				rateList:[{
+					id:0,
+					icon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/hsat.png',
+					name:'非常满意',
+					selIcon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/hsat_sel.png'
+				},
+				{
+					id:1,
+					icon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/sat.png',
+					name:'满意',
+					selIcon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/sat_sel.png'
+				},
+				{
+					id:2,
+					icon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/fari.png',
+					name:'一般',
+					selIcon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/fari_sel.png'
+				},
+				{
+					id:3,
+					icon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/unsat.png',
+					name:'不满意',
+					selIcon:'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/vip/unsat_sel.png'
+				}
+				],
+				resMsg: "",
+				resCode: '',
+				showExpiration: false,
+				videoItem: {},
+				viewload: true,
+				loadingtext: "数据加载中...",
+				baseUrl: uni.getStorageSync('requestPath'),
+				// 1 红包 2 积分
+				rewardType: [{
+					name: '红包奖励',
+					value: 1
+				}, {
+					name: '积分奖励',
+					value: 2
+				}],
+				currentReward: 1,
+				player: null,
+				loading: true,
+				progress: 0,
+				code: null,
+				statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
+				scrollTop: 0,
+				height: '0px',
+				isLogin: false,
+				videoUrl: "",
+				videoId: "",
+				/** 恢复前台 / seek 后短时间内跳过「快进」判定,避免 iOS、鸿蒙息屏后首帧 currentTime 抖动误报 */
+				_antiSeekSuppressExpireAt: 0,
+				_videoPageHadShownOnce: false,
+				//现在的时长
+				playTime: 0,
+				//总时长
+				duration: 0,
+				playDuration: 0,
+				// 用于续播
+				playDurationSeek: 0,
+				// 温馨提醒时间节点,
+				tipsTime: 0,
+				tipsOpen: false,
+				config: {},
+				courseInfo: {},
+				quesList: [],
+				lineList: [],
+				// 错题
+				errQues: [],
+				// 答题机会
+				remain: 0,
+				errTitle: "",
+				errDesc: "",
+				showPlay: true,
+				showControls: false,
+				playStatus: "",
+				isFull: false,
+				fullscreenToggleLock: false,
+				fullscreenToggleTimer: null,
+				isAddKf: 0,
+				lineIndex: 0,
+				// 是否展开
+				isExpand: true,
+				textHeight: 0, //文本高度
+				qwUserId: "",
+				qrcode: "",
+				corpId: "",
+				periodId: "", //营期id
+				companyUserId: "", //销售id
+				companyId: "", //公司id
+				courseId: "", //课程id
+				qrcodeMsg: "",
+				urlOption: {},
+				bufferRate: 0, // 缓冲时间
+				uuId: "",
+				isEnded: false,
+				/** 当前是否处于播放中 */
+				videoPlaying: false,
+				// 是否允许拖动进度条
+				linkType: 0,
+				ip: null,
+				checked: true,
+				isFinish: 0, // 是否完课
+				interval: null,
+				intervalIntegral: null, // 积分定时
+				options: {
+					sources: [{
+						src: ""
+					}],
+					poster: "",
+					live: false /* 是否直播 */ ,
+					controls: true,
+					autoplay: false,
+					licenseUrl: 'https://license.vod2.myqcloud.com/license/v2/1323137866_1/v_cube.license', // license 地址,参考准备工作部分,在视立方控制台申请 license 后可获得 licenseUrl,
+					LicenseKey: 'bcc5bd9a14b798b48c52ff005a21d926',
+					controlBar: {
+						volumePanel: false,
+						playbackRateMenuButton: false,
+						QualitySwitcherMenuButton: false,
+						// progressControl: false
+					},
+					plugins: {
+						// ProgressMarker: false,
+						ContextMenu: {
+							statistic: false
+						}
+					},
+				},
+				// 错误请求次数
+				errorCount: 0,
+				answerPopup: false,
+				sortLink: "",
+				// 课程是否过期
+				isExpire: false,
+				menuButtonLeft: 281,
+				menuButtonH: 45,
+				timer: null,
+				flag: false,
+				msg: '',
+				poster: '',
+				userInfo: {},
+				timeid: '',
+				videocont: {},
+				timepop: false,
+				appToken: '',
+				kfPopup: false,
+				iskftype: 0,
+				courseLogo: '',
+				isquestion: false,
+				tipsPopup: false,
+				timepath: '3分之1',
+				tipsTime2: 0,
+				projectId: '',
+				showfalse: false,
+				contentmsg: null,
+				currentId: 0,
+				showTreatment: 1,
+				treatmentPackage: [],
+				// 商品栏展示列表(根据上架/下架时间过滤)
+				displayProductList: [],
+				// 商品卡片弹窗
+				cardPopup: false,
+				currentCardItem: null,
+				// 热卖标签数量(小黄车与弹窗卡片共用,按 productId)
+				productHotCountMap: {},
+				productHotTimer: null,
+				// 手动关闭后,当前卡片在其有效时段内不再重复弹出
+				dismissedCardKey: '',
+				// 完课积分倒计时(秒)
+				remainTime: 0,
+				// 完课积分总倒计时时长(秒),用于计算百分比
+				totalRemainTime: 0,
+				// 完课积分倒计时定时器
+				countdownTimer: null,
+				// 是否已从接口拉取到倒计时数据(避免 remainTime 初始为 0 时提前放开答题)
+				remainTimeReady: false,
+				// 倒计时结束后是否已补发过一次看课记录
+				hasReportedAfterCountdown: false,
+				notice:'',//跑马灯,
+				isHeight:false,
+				// 跑马灯数据就绪门禁:避免首次进入时使用旧状态导致闪现
+				marqueeDataReady: false,
+				// 虚拟下单跑马灯
+				fakeOrderPool: [],
+				marqueeTriplePayloads: [],
+				marqueeTripleIncomingPayloads: [],
+				marqueeTripleSwitching: false,
+				marqueeCurrentText: '',
+				marqueeSelfHighlight: false,
+				marqueeDisplayPayload: null,
+				marqueeDisplaySelf: false,
+				marqueeIncomingPayload: null,
+				marqueeIncomingSelf: false,
+				marqueeSwitching: false,
+				pendingSelfMarqueeFirst: false,
+				_fakeMarqueeStarted: false,
+				/** 与 computed fakeMarqueeEligible 上次值比较,避免无 watch 时在 updateProductAndCardDisplay 高频调用中反复重置防抖 */
+				_fakeMarqueeEligiblePrev: undefined,
+				_marqueeStartDebounceTimer: null,
+				_fakeMarqueeTimer: null,
+				_marqueeSwitchTimer: null,
+				_marqueeTripleSwitchTimer: null,
+				/** 本人下单条按缓存 ts 与当前时间差定时回显刷新 */
+				_selfMarqueeClockTimer: null,
+				tabIndex:0,
+				/** 与 quesList 同源:接口 questionBankList,用于 Tab「评价得积分」是否展示 */
+				questionBankList: [],
+				/** getCommentList 的 defaultPageInfo.list:控制精选留言 Tab;与用户 featuredCommentList 在 featuredCommentDisplayList 中合并展示 */
+				defaultPageInfoList: [],
+				featuredCommentList: [],
+				featuredCommentInput: '',
+				featuredCommentLoading: false,
+				featuredCommentLoadingMore: false,
+				/** 下一页页码,与 getCommentList pageNum 一致 */
+				featuredCommentPageNum: 1,
+				featuredCommentPageSize: 10,
+				featuredCommentHasMore: true,
+				/** getCommentList 最近一次返回:用户评论总条数(与运营 defaultPageInfo.total 分离) */
+				featuredCommentUserTotal: NaN,
+				/** getCommentList 最近一次返回:运营精选总条数 */
+				featuredCommentDefaultTotal: NaN,
+				featuredCommentSending: false,
+				/** 精选留言待发送的本地媒体:type image|video,path 临时路径,thumbTempPath 视频封面 */
+				featuredCommentMedia: null,
+				/**
+				 * 从相册/相机选图或选视频返回时小程序会触发 onShow,否则会误跑 getH5CourseByVideo / getH5CourseVideoDetails。
+				 * 与 uni.uploadFile 发布评论无直接关系;选媒体前置 true,onShow 消费一次或 complete 兜底清除。
+				 */
+				videovipSuppressOnShowCourseFetchOnce: false,
+				/** 从相册选留言图/视频前主课若在播,上传(含压缩)结束后恢复播放 */
+				_shouldResumeCourseVideoAfterFeaturedUpload: false,
+				/**
+				 * 打开精选留言输入前主课是否在播(快照)。
+				 * 键盘/选图页返回时常先触发 @pause,videoPlaying 已为 false,仅靠选媒体瞬间的 videoPlaying 会漏标,导致发布后不调 play。
+				 */
+				_courseWasPlayingBeforeFeaturedCommentOpen: false,
+				/** 精选留言选图/选视频:用底部 u-popup 替代 uni.showActionSheet,避免鸿蒙等机型原生弹层未贴底 */
+				featuredMediaActionSheetShow: false,
+				/** 精选留言:自定义大图/视频预览弹窗 */
+				featuredCommentMediaPreviewShow: false,
+				featuredCommentMediaPreviewMode: 'image',
+				featuredCommentMediaPreviewUrls: [],
+				featuredCommentMediaPreviewIndex: 0,
+				featuredCommentMediaPreviewVideoUrl: '',
+				featuredCommentMediaPreviewPoster: '',
+				/** 精选留言 scroll-view 滚到底部(与 id=fc-scroll-anchor 配合) */
+				featuredCommentScrollIntoView: '',
+				/** 精选留言:键盘上方白底输入条 */
+				featuredCommentComposerActive: false,
+				featuredCommentInputFocused: false,
+				featuredCommentKeyboardBottomPx: 0,
+			}
+		},
+		filters: {
+			numberToChinese(number) {
+				if (number) {
+					const chineseNumber = ['一', '二', '三', '四', '五', '六', '七', '八', '九'];
+					return chineseNumber[number - 1];
+				} else {
+					return ''
+				}
+			},
+		},
+		computed: {
+			isAnswer() {
+				return (item, name) => {
+					if (item.type == 1) {
+						return item.answer == name
+					} else if (item.type == 2) {
+						const array = item.answer.split(',')
+						return array.some(i => i == name)
+					} else {
+						return false
+					}
+				}
+			},
+			imgPath() {
+				return this.$store.state.imgpath
+			},
+			appid() {
+				return this.$store.state.appid
+			},
+			// 格式化后的倒计时
+			formattedCountdown() {
+				return this.formatCountdown(this.remainTime);
+			},
+			// 倒计时百分比
+			countdownPercentage() {
+				return this.getCountdownPercentage();
+			},
+			/** 评价得积分:questionBankList 有题 */
+			showTabReviewPoints() {
+				return Array.isArray(this.questionBankList) && this.questionBankList.length > 0
+			},
+			/** 栏目介绍:已配置 courseIntroImg */
+			showTabColumnIntro() {
+				const img = this.courseInfo && this.courseInfo.courseIntroImg
+				return typeof img === 'string' && img.trim() !== ''
+			},
+			/** 精选留言:仅当运营配置的 defaultPageInfo.list 有数据时展示 Tab */
+			showTabFeaturedComments() {
+				return Array.isArray(this.defaultPageInfoList) && this.defaultPageInfoList.length > 0
+			},
+			/** 精选留言列表:有运营 defaultPageInfo 时先展示用户新评论 featuredCommentList,再拼接运营配置项(同 id 去重) */
+			featuredCommentDisplayList() {
+				const def = Array.isArray(this.defaultPageInfoList) ? this.defaultPageInfoList : []
+				if (!def.length) return []
+				const user = Array.isArray(this.featuredCommentList) ? this.featuredCommentList : []
+				return this._mergeFeaturedUserComments(user.slice(), def)
+			},
+			/** 用户评论已加载完且无加载中时展示 */
+			showFeaturedCommentNoMoreFooter() {
+				if (this.featuredCommentLoading || this.featuredCommentLoadingMore) return false
+				const list = this.featuredCommentDisplayList
+				if (!Array.isArray(list) || !list.length) return false
+				return !this.featuredCommentHasMore
+			},
+			visibleRatingTabCount() {
+				return this.ratingTabList.length
+			},
+			/** 评价区 Tab 展示顺序:精选留言 → 栏目介绍 → 评价得积分(仅渲染有数据的项) */
+			ratingTabList() {
+				const tabs = []
+				if (this.showTabFeaturedComments) {
+					tabs.push({
+						key: 'featured',
+						index: 0,
+						label: '精选留言',
+						icon: 'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/pl.png',
+						iconActive: 'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/pl-sel.png'
+					})
+				}
+				if (this.showTabColumnIntro) {
+					tabs.push({
+						key: 'column',
+						index: 1,
+						label: '栏目介绍',
+						icon: 'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/des.png',
+						iconActive: 'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/des-sel.png'
+					})
+				}
+				if (this.showTabReviewPoints) {
+					tabs.push({
+						key: 'review',
+						index: 2,
+						label: '评价得积分',
+						icon: 'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/sel.png',
+						iconActive: 'https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/zan-sel.png'
+					})
+				}
+				return tabs
+			},
+			hasVisibleRatingTab() {
+				return this.visibleRatingTabCount > 0
+			},
+			...mapGetters(['coureLogin']),
+			/** 小黄车商品中「最早上架」时间点(秒),用于跑马灯起始展示 */
+			firstShelfSecondsAmongProducts() {
+				const list = this.treatmentPackage || []
+				if (!list.length) return Infinity
+				let minSec = Infinity
+				for (let i = 0; i < list.length; i++) {
+					const t = list[i].onShelfTime
+					if (!this._vipShelfTimeValid(t)) continue
+					const sec = this._vipTimeStrToSec(t)
+					if (sec > 0 && sec < minSec) minSec = sec
+				}
+				return minSec === Infinity ? Infinity : minSec
+			},
+			fakeMarqueeEligible() {
+				// 商品/回放数据未完成刷新前,不允许启动展示,避免首次闪现
+				if (!this.marqueeDataReady) return false
+				if (this.showTreatment !== 0) return false
+				// 以“当前应展示的商品列表非空”作为跑马灯出现条件
+				// 这样能对齐你说的“商品上架才出现”,避免只用最早上架秒点导致的一帧差异
+				return Array.isArray(this.displayProductList) && this.displayProductList.length > 0
+			},
+			// 竖屏课打开小黄车 goodsList 弹窗,或打开精选留言大图/视频预览 fc-media-preview-mask 时,先藏住视频上的虚拟下单条,关闭后再显(不影响底层跑马灯计时)
+			showFakeMarqueeOnVideoCover() {
+				if (!this.fakeMarqueeEligible) return false
+				if (this.displayType === 'portrait' && (this.isCart || this.featuredCommentMediaPreviewShow)) return false
+				return true
+			},
+			isTripleMarqueeMode() {
+				return !!(this.isShu || this.isFull)
+			},
+		},
+		watch: {
+			coureLogin: {
+				immediate: true, // 页面一进入就检查一次
+				handler(val) {
+					console.log(val, '----')
+					if (val == 2 && this.isLogin) {
+						console.log("看课AppToken失效,请重新登录")
+						this.isLogin = false
+						this.isAddKf = 0
+						this.$showLoginPage()
+					}
+				}
+			},
+			isTripleMarqueeMode(now, was) {
+				if (!now || was) return
+				if (!this.fakeMarqueeEligible || !this._fakeMarqueeStarted) return
+				this.syncTripleMarqueeImmediate()
+			},
+			/** 精选留言 Tab 出现后默认高亮 */
+			showTabFeaturedComments(now, was) {
+				if (now && was !== true) {
+					this._selectDefaultRatingTab()
+				}
+			},
+			/**
+			 * 评价 Tab 晚于栏目介绍返回时,_syncRatingTabIndex 可能暂落在 tab=1;
+			 * 若有精选留言则仍默认高亮 tab=0,否则仅校正到当前第一个可见 Tab。
+			 */
+			showTabReviewPoints(now, was) {
+				if (now && was !== true) {
+					this._selectDefaultRatingTab()
+				}
+			},
+			/** Tab 数量增加且含精选留言时,默认高亮精选留言 */
+			visibleRatingTabCount(n, o) {
+				if (n <= 0 || !this.showTabFeaturedComments) return
+				if (o != null && n <= o) return
+				this._selectDefaultRatingTab()
+			},
+			// tabIndex(n) {
+			// 	if (n !== 2) {
+			// 		this._closeFeaturedCommentComposerUi()
+			// 		this.closeFeaturedMediaActionSheet()
+			// 	}
+			// }
+			displayProductList: {
+				handler() {
+					this.syncProductHotCounts()
+				},
+				deep: true,
+			},
+			cardPopup() {
+				this.syncProductHotCounts()
+			},
+			currentCardItem() {
+				this.syncProductHotCounts()
+			},
+		},
+		onLoad(option) {
+			this.getWebviewUrl()
+			uni.$on('vipMsg', (data) => {
+				console.log(4444, data)
+				this.contentmsg = data
+				this.showfalse = true
+				uni.showToast({
+					icon: 'none',
+					title: data,
+					duration: 5000
+				});
+			})
+			this.videoContext = uni.createVideoContext('video-content-box', this)
+		    this.getVideoContainerHeight()
+			this.code = option.code
+			this.userInfo = this.$getUserInfo()
+			this.appToken = uni.getStorageSync('companyUserInfo')
+			console.log('option', option)
+			if (!option.course) {
+				const keys = decodeURIComponent(Object.keys(option)[0]);
+				this.urlOption = JSON.parse(keys.split('course=')[1])
+			} else {
+				this.urlOption = option.course ? JSON.parse(decodeURIComponent(option.course)) : {}
+			}
+			console.log(this.urlOption)
+			uni.setStorageSync('H5course', this.urlOption)
+			this.videoId = this.urlOption.videoId
+			this.courseId = this.urlOption.courseId
+			this.periodId = this.urlOption.periodId
+			this.companyId = this.urlOption.companyId
+			this.companyUserId = this.urlOption.companyUserId
+			this.projectId = this.urlOption.projectId
+			this.timeid = this.urlOption.id
+			console.log(this.urlOption)
+			console.log(decodeURIComponent(option.course))
+			// this.sortLink = this.urlOption.link || ''
+			//this.getMenuButton()
+			// #ifndef H5
+			this._featuredCommentKbHandler = (res) => {
+				const h = res && res.height != null ? res.height : 0
+				const prev = this.featuredCommentKeyboardBottomPx
+				this.featuredCommentKeyboardBottomPx = h
+				if (
+					this.featuredCommentComposerActive &&
+					prev > 0 &&
+					h === 0
+				) {
+					this.featuredCommentComposerActive = false
+					this.featuredCommentInputFocused = false
+				}
+			}
+			uni.onKeyboardHeightChange(this._featuredCommentKbHandler)
+			// #endif
+		},
+		onShow() {
+			this.userInfo = this.$getUserInfo()
+			this.tipsOpen = false
+			this.isExpand = true
+			this.uuId = generateRandomString(16)
+			this.refreshVipPurchaseMarqueeFlag()
+			if (this._videoPageHadShownOnce) {
+				this._touchAntiSeekSuppress(2000)
+			} else {
+				this._videoPageHadShownOnce = true
+			}
+			if (this.videovipSuppressOnShowCourseFetchOnce) {
+				this.videovipSuppressOnShowCourseFetchOnce = false
+				return
+			}
+			// 每次进入页面先关闭门禁,并清空旧跑马灯状态,等 getH5CourseVideoDetails 拉完数据再开启
+			this.stopFakeMarqueeLoop()
+			this.marqueeDataReady = false
+			this._fakeMarqueeEligiblePrev = undefined
+			if (this.videoId) {
+				this.getH5CourseByVideo()
+			}
+			if (this.$isLogin()) {
+				this.isLogin = true
+				if (this.isAddKf == 1 && this.userInfo.userId) {
+					this.getH5CourseVideoDetails()
+				} else {
+					this.getIsAddKf()
+				}
+			} else {
+				this.isLogin = false
+			}
+			// if(this.sortLink){
+			// 	this.getLink()
+			// } else {
+			// 	uni.showToast({
+			// 		title: 'sortLink is not found',
+			// 		icon: 'none'
+			// 	});
+			// }
+		},
+		mounted() {
+			// this.getIP()
+			this.getHeight()
+
+		},
+		onHide() {
+			this.closeFeaturedCommentMediaPreview()
+			this._closeFeaturedCommentComposerUi()
+			// this.player = uni.createVideoContext('video-content-box');
+			if (this.player) {
+				this.player.pause()
+			}
+			// 精选留言调起相册/相机时也会触发 onHide,勿停虚拟跑马灯(与 onShow 抑制拉课共用同一标志)
+			if (!this.videovipSuppressOnShowCourseFetchOnce) {
+				this.stopFakeMarqueeLoop()
+			}
+			// 页面隐藏时停止完课积分倒计时
+			this.stopCountdown()
+			this.stopProductHotTimer()
+			// if (this.interval != null) {
+			// 	clearInterval(this.interval)
+			// 	this.interval = null
+			// }
+		},
+		onPageResize(){
+			this.getVideoContainerHeight();
+		},
+		onUnload() {
+			this.closeFeaturedCommentMediaPreview()
+			this._videoPageHadShownOnce = false
+			if (this.interval != null) {
+				clearInterval(this.interval)
+				this.interval = null
+			}
+			if (this.fullscreenToggleTimer) {
+				clearTimeout(this.fullscreenToggleTimer)
+				this.fullscreenToggleTimer = null
+			}
+			if (this._rateBounceTimer) {
+				clearTimeout(this._rateBounceTimer)
+				this._rateBounceTimer = null
+			}
+			this.fullscreenToggleLock = false
+			// 页面卸载时清理完课积分倒计时
+			this.stopCountdown()
+			this.stopProductHotTimer()
+			this.clearIntegral()
+			this.stopFakeMarqueeLoop()
+			this.fakeOrderPool = []
+			// #ifndef H5
+			if (this._featuredCommentKbHandler) {
+				uni.offKeyboardHeightChange(this._featuredCommentKbHandler)
+				this._featuredCommentKbHandler = null
+			}
+			// #endif
+		},
+		beforeDestroy() {
+			this.closeFeaturedCommentMediaPreview()
+			this.player = uni.createVideoContext('video-content-box');
+			if (this.player) {
+				this.player.stop()
+				this.player = null
+			}
+			if (this.interval != null) {
+				clearInterval(this.interval)
+				this.interval = null
+			}
+			if (this.fullscreenToggleTimer) {
+				clearTimeout(this.fullscreenToggleTimer)
+				this.fullscreenToggleTimer = null
+			}
+			if (this._rateBounceTimer) {
+				clearTimeout(this._rateBounceTimer)
+				this._rateBounceTimer = null
+			}
+			this.fullscreenToggleLock = false
+			// 组件销毁前清理完课积分倒计时
+			this.stopCountdown()
+			this.stopProductHotTimer()
+			this.clearIntegral()
+			this.stopFakeMarqueeLoop()
+			// #ifndef H5
+			if (this._featuredCommentKbHandler) {
+				uni.offKeyboardHeightChange(this._featuredCommentKbHandler)
+				this._featuredCommentKbHandler = null
+			}
+			// #endif
+		},
+		methods: {
+			_closeFeaturedCommentComposerUi() {
+				this.featuredCommentComposerActive = false
+				this.featuredCommentInputFocused = false
+				this.featuredCommentKeyboardBottomPx = 0
+			},
+			openFeaturedCommentComposer() {
+				this._expandLayoutIfPortraitFeaturedCommentsOnly()
+				this._courseWasPlayingBeforeFeaturedCommentOpen = this.videoPlaying && !this.isEnded
+				this.featuredCommentComposerActive = true
+				this.$nextTick(() => {
+					this.featuredCommentInputFocused = true
+				})
+			},
+			onFeaturedCommentComposerMaskTap() {
+				this._closeFeaturedCommentComposerUi()
+			},
+			onFeaturedCommentComposerInputFocus() {
+				this._expandLayoutIfPortraitFeaturedCommentsOnly()
+			},
+			onFeaturedCommentComposerInputBlur() {
+				this.featuredCommentInputFocused = false
+			},
+			/** 有精选留言时默认 tabIndex=0,否则落到第一个可见 Tab */
+			_selectDefaultRatingTab() {
+				if (this.showTabFeaturedComments) {
+					this.tabIndex = 0
+					this.loadFeaturedComments()
+					return
+				}
+				this._syncRatingTabIndex()
+			},
+			_syncRatingTabIndex() {
+				const tabs = [
+					this.showTabFeaturedComments,
+					this.showTabColumnIntro,
+					this.showTabReviewPoints
+				]
+				if (!tabs.some(Boolean)) return
+				if (tabs[this.tabIndex]) return
+				const idx = tabs.findIndex(Boolean)
+				if (idx < 0) return
+				this.tabIndex = idx
+				if (idx === 0) {
+					this.loadFeaturedComments()
+				}
+			},
+			selecTab(idx){
+				if (idx === 0 && !this.showTabFeaturedComments) return
+				if (idx === 1 && !this.showTabColumnIntro) return
+				if (idx === 2 && !this.showTabReviewPoints) return
+				this.tabIndex = idx
+				if (idx === 0) {
+					this.loadFeaturedComments()
+				}
+			},
+			_resolveUserInfoObj() {
+				let u = this.userInfo
+				if (!u) return {}
+				if (typeof u === 'string') {
+					try {
+						return JSON.parse(u) || {}
+					} catch (e) {
+						return {}
+					}
+				}
+				return u
+			},
+			/** 从 getCommentList 结果中取出用户评论列表(兼容 data 为数组或 data.list / list 等),顺序与接口一致 */
+			_pickUserCommentListFromCommentListRes(res) {
+				if (!res || res.code != 200) return []
+				const d = res.data
+				if (d && Array.isArray(d.list)) return d.list.slice()
+				if (Array.isArray(d)) return d.slice()
+				if (Array.isArray(res.list)) return res.list.slice()
+				if (d && Array.isArray(d.records)) return d.records.slice()
+				return []
+			},
+			_pickDefaultPageInfoListFromCommentListRes(res) {
+				if (!res || res.code != 200) return []
+				const dpi = res.defaultPageInfo || (res.data && res.data.defaultPageInfo)
+				if (dpi && Array.isArray(dpi.list)) return dpi.list.slice()
+				return []
+			},
+			/** 用户新评论分页 total(与运营列表 total 分离;兼容 userTotal / listTotal / data.total) */
+			_pickFeaturedUserCommentTotalFromRes(res) {
+				if (!res || res.code != 200) return NaN
+				const d = res.data
+				const tryNum = (v) => {
+					const t = Number(v)
+					return Number.isFinite(t) && t >= 0 ? t : NaN
+				}
+				if (d && typeof d === 'object' && !Array.isArray(d)) {
+					if (typeof d.userTotal !== 'undefined') {
+						const t = tryNum(d.userTotal)
+						if (Number.isFinite(t)) return t
+					}
+					if (typeof d.commentTotal !== 'undefined') {
+						const t = tryNum(d.commentTotal)
+						if (Number.isFinite(t)) return t
+					}
+					if (typeof d.listTotal !== 'undefined') {
+						const t = tryNum(d.listTotal)
+						if (Number.isFinite(t)) return t
+					}
+					if (typeof d.total !== 'undefined') {
+						const t = tryNum(d.total)
+						if (Number.isFinite(t)) return t
+					}
+				}
+				if (typeof res.userTotal !== 'undefined') {
+					const t = tryNum(res.userTotal)
+					if (Number.isFinite(t)) return t
+				}
+				if (typeof res.total !== 'undefined') {
+					const t = tryNum(res.total)
+					if (Number.isFinite(t)) return t
+				}
+				return NaN
+			},
+			/** 运营 defaultPageInfo 条数 total(不参与用户分页 hasMore,仅缓存/排查) */
+			_pickFeaturedDefaultTotalFromRes(res) {
+				if (!res || res.code != 200) return NaN
+				const dpi = res.defaultPageInfo || (res.data && res.data.defaultPageInfo)
+				if (dpi && typeof dpi.total !== 'undefined') {
+					const t = Number(dpi.total)
+					return Number.isFinite(t) && t >= 0 ? t : NaN
+				}
+				return NaN
+			},
+			_syncFeaturedCommentTotalsFromRes(res) {
+				const u = this._pickFeaturedUserCommentTotalFromRes(res)
+				const dt = this._pickFeaturedDefaultTotalFromRes(res)
+				this.featuredCommentUserTotal = Number.isFinite(u) ? u : NaN
+				this.featuredCommentDefaultTotal = Number.isFinite(dt) ? dt : NaN
+			},
+			_mergeFeaturedUserComments(prev, incoming) {
+				const a = Array.isArray(prev) ? prev : []
+				const b = Array.isArray(incoming) ? incoming : []
+				const keyOf = (it) => {
+					if (!it) return ''
+					if (it.commentId != null && it.commentId !== '') return 'c:' + it.commentId
+					if (it.id != null && it.id !== '') return 'i:' + it.id
+					return ''
+				}
+				const seen = new Set()
+				const out = []
+				for (let i = 0; i < a.length; i++) {
+					const k = keyOf(a[i])
+					if (k) seen.add(k)
+					out.push(a[i])
+				}
+				for (let j = 0; j < b.length; j++) {
+					const it = b[j]
+					const k = keyOf(it)
+					if (k) {
+						if (seen.has(k)) continue
+						seen.add(k)
+					}
+					out.push(it)
+				}
+				return out
+			},
+			/**
+			 * 是否还有下一页用户评论(仅按用户 total 与已合并的 featuredCommentList 长度比较;
+			 * 运营 defaultPageInfo 另有 total,不参与此处 hasMore)。
+			 */
+			_applyFeaturedCommentHasMore(res, pageUserList, mergedUserList) {
+				const pageLen = Array.isArray(pageUserList) ? pageUserList.length : 0
+				const mergedLen = Array.isArray(mergedUserList) ? mergedUserList.length : 0
+				const userTotal = this._pickFeaturedUserCommentTotalFromRes(res)
+				if (Number.isFinite(userTotal)) {
+					this.featuredCommentHasMore = mergedLen < userTotal
+				} else {
+					this.featuredCommentHasMore = pageLen >= this.featuredCommentPageSize
+				}
+				if (pageLen === 0) this.featuredCommentHasMore = false
+			},
+			onFeaturedCommentScrollToLower() {
+				if (this.tabIndex !== 0 || !this.showTabFeaturedComments) return
+				this.loadFeaturedComments({ append: true })
+			},
+			loadFeaturedComments(opts) {
+				if (!this.videoId || !this.courseId) {
+					return Promise.resolve()
+				}
+				const o = opts || {}
+				const scrollToBottom = !!o.scrollToBottom
+				const append = !!o.append
+				if (append) {
+					if (!this.featuredCommentHasMore) return Promise.resolve()
+					if (this.featuredCommentLoading || this.featuredCommentLoadingMore) return Promise.resolve()
+					this.featuredCommentLoadingMore = true
+				} else {
+					if (this.featuredCommentLoading) return Promise.resolve()
+					this.featuredCommentPageNum = 1
+					this.featuredCommentHasMore = true
+					this.featuredCommentLoading = true
+				}
+				const pageNum = this.featuredCommentPageNum
+				return getCommentList({
+					pageNum,
+					pageSize: this.featuredCommentPageSize,
+					courseId: this.courseId,
+					videoId:this.videoId,
+				}).then(res => {
+					if (append) {
+						this.featuredCommentLoadingMore = false
+					} else {
+						this.featuredCommentLoading = false
+					}
+					if (res.code == 200) {
+						const pageUser = this._pickUserCommentListFromCommentListRes(res)
+						this._syncFeaturedCommentTotalsFromRes(res)
+						if (!append) {
+							this.featuredCommentList = pageUser
+							this.defaultPageInfoList = this._pickDefaultPageInfoListFromCommentListRes(res)
+							this._applyFeaturedCommentHasMore(res, pageUser, this.featuredCommentList)
+							if (pageUser.length > 0) this.featuredCommentPageNum = pageNum + 1
+						} else {
+							this.featuredCommentList = this._mergeFeaturedUserComments(
+								this.featuredCommentList,
+								pageUser
+							)
+							this._applyFeaturedCommentHasMore(res, pageUser, this.featuredCommentList)
+							if (pageUser.length > 0) this.featuredCommentPageNum = pageNum + 1
+						}
+					} else {
+						if (!append) {
+							this.defaultPageInfoList = []
+							this.featuredCommentList = []
+							this.featuredCommentHasMore = false
+							this.featuredCommentUserTotal = NaN
+							this.featuredCommentDefaultTotal = NaN
+						}
+					}
+					this._syncRatingTabIndex()
+					if (scrollToBottom) {
+						this.$nextTick(() => {
+							this._scrollFeaturedCommentsToBottom()
+							setTimeout(() => this._scrollFeaturedCommentsToBottom(), 280)
+						})
+					}
+				}).catch(() => {
+					if (append) {
+						this.featuredCommentLoadingMore = false
+					} else {
+						this.featuredCommentLoading = false
+						this.featuredCommentList = []
+						this.defaultPageInfoList = []
+						this.featuredCommentHasMore = false
+						this.featuredCommentUserTotal = NaN
+						this.featuredCommentDefaultTotal = NaN
+					}
+					this._syncRatingTabIndex()
+				})
+			},
+			_scrollFeaturedCommentsToBottom() {
+				this.featuredCommentScrollIntoView = ''
+				this.$nextTick(() => {
+					this.featuredCommentScrollIntoView = 'fc-scroll-anchor'
+					setTimeout(() => {
+						this.featuredCommentScrollIntoView = ''
+					}, 400)
+				})
+			},
+			getCommentAvatar(it) {
+				if (!it) return ''
+				return it.avatar || it.headImg || it.headimg || it.userAvatar || ''
+			},
+			getCommentDisplayName(it) {
+				if (!it) return '用户'
+				if (it.nickName) return it.nickName
+				if (it.userId != null && it.userId !== '') {
+					return it.toNickName
+				}
+			},
+			_urlsEmbeddedInCommentContent(it) {
+				const c = it && it.content
+				if (c == null || typeof c !== 'string') return []
+				const text = String(c).replace(/\u21b5/g, '\n')
+				const m = text.match(/https?:\/\/[^\s]+/gi) || []
+				const cleaned = m.map(u => u.replace(/[),.;!?]+$/g, ''))
+				return [...new Set(cleaned)]
+			},
+			_isEmbeddedCommentVideoUrl(u) {
+				if (!u) return false
+				return /\/comment\/video\//i.test(u) || /\.(mp4|m3u8|mov|webm|avi|mkv)(\?|#|$)/i.test(u)
+			},
+			_isEmbeddedCommentImageUrl(u) {
+				if (!u) return false
+				return /\/comment\/image\//i.test(u) || /\.(jpg|jpeg|png|gif|webp|bmp)(\?|#|$)/i.test(u)
+			},
+			_videoUrlFromCommentContent(it) {
+				const urls = this._urlsEmbeddedInCommentContent(it)
+				for (let i = 0; i < urls.length; i++) {
+					if (this._isEmbeddedCommentVideoUrl(urls[i])) return urls[i]
+				}
+				return ''
+			},
+			getCommentTextOnly(it) {
+				if (!it || it.content == null) return ''
+				let text = String(it.content).replace(/\u21b5/g, '\n')
+				const strip = new Set()
+				const v = this.getCommentVideoUrl(it)
+				if (v) strip.add(v)
+				const urls = this._urlsEmbeddedInCommentContent(it)
+				for (let i = 0; i < urls.length; i++) {
+					const u = urls[i]
+					if (this._isEmbeddedCommentVideoUrl(u)) strip.add(u)
+					else if (this._isEmbeddedCommentImageUrl(u) && u !== v) strip.add(u)
+				}
+				strip.forEach(u => {
+					text = text.split(u).join('')
+				})
+				return text.replace(/(\r?\n\s*){2,}/g, '\n').replace(/^\s+|\s+$/g, '').trim()
+			},
+			getCommentVideoUrl(it) {
+				if (!it) return ''
+				if (it.videoUrl) return it.videoUrl
+				if (it.video) return it.video
+				if (it.mediaType === 'video' && it.mediaUrl) return it.mediaUrl
+				return this._videoUrlFromCommentContent(it)
+			},
+			getCommentVideoPoster(it) {
+				if (!it) return ''
+				const raw =
+					it.videoCover || it.coverUrl || it.poster || it.thumbnail || ''
+				return typeof raw === 'string' ? raw.trim() : String(raw || '').trim()
+			},
+			commentImageUrls(it) {
+				if (!it) return []
+				const raw = it.images || it.imageUrl || it.imgUrl || it.picUrl || it.pic
+				let fromFields = []
+				if (raw) {
+					if (Array.isArray(raw)) fromFields = raw.filter(Boolean)
+					else fromFields = String(raw).split(',').map(s => s.trim()).filter(Boolean)
+				}
+				const videoUrl = this.getCommentVideoUrl(it)
+				const fromContent = this._urlsEmbeddedInCommentContent(it).filter(u =>
+					this._isEmbeddedCommentImageUrl(u) && !this._isEmbeddedCommentVideoUrl(u) && u !== videoUrl
+				)
+				return [...new Set([...fromFields, ...fromContent])]
+			},
+			/** 精选留言预览图 / 选图 / 留言内嵌视频播放前:暂停主课视频,避免与原生页或第二条音轨叠放 */
+			_pauseCourseVideo() {
+				try {
+					const ctx =
+						this.videoContext ||
+						uni.createVideoContext('video-content-box', this)
+					this.videoContext = ctx
+					if (ctx && ctx.pause) ctx.pause()
+				} catch (e) {}
+				try {
+					if (this.player && this.player.pause) this.player.pause()
+				} catch (e2) {}
+			},
+			/** 精选留言带图/视频上传结束后:若选媒体前主课在播则恢复 */
+			_resumeCourseVideoAfterFeaturedJob() {
+				if (!this._shouldResumeCourseVideoAfterFeaturedUpload) return
+				this._shouldResumeCourseVideoAfterFeaturedUpload = false
+				this._courseWasPlayingBeforeFeaturedCommentOpen = false
+				if (this.isEnded || !this.videoUrl || !this.videoId) return
+				const ctx =
+					this.videoContext ||
+					uni.createVideoContext('video-content-box', this)
+				this.videoContext = ctx
+				const tryPlay = () => {
+					try {
+						if (ctx && ctx.play) ctx.play()
+					} catch (e) {}
+				}
+				this.$nextTick(() => {
+					tryPlay()
+					setTimeout(tryPlay, 80)
+					setTimeout(tryPlay, 260)
+				})
+			},
+			getFeaturedCommentRowKey(it, idx) {
+				const id =
+					it && it.commentId != null && it.commentId !== ''
+						? String(it.commentId)
+						: it && it.id != null
+							? String(it.id)
+							: ''
+				return 'fc-' + idx + '-' + (id || 'n')
+			},
+			getFeaturedCommentVideoId(it, idx) {
+				return 'feat-comment-video-' + this.getFeaturedCommentRowKey(it, idx)
+			},
+			openFeaturedCommentMediaPreview(it, listIdx, mode, imageIndex) {
+				const m = mode === 'video' ? 'video' : 'image'
+				if (m === 'image') {
+					const urls = this.commentImageUrls(it).filter(u => u && !/^blob:/i.test(u))
+					if (!urls.length) return
+					const i = Math.min(
+						Math.max(0, Number(imageIndex) || 0),
+						urls.length - 1
+					)
+					this._pauseCourseVideo()
+					try {
+						if (this.getCommentVideoUrl(it)) {
+							const id = this.getFeaturedCommentVideoId(it, listIdx)
+							const c = uni.createVideoContext(id, this)
+							if (c && c.pause) c.pause()
+						}
+					} catch (e) {}
+					this.featuredCommentMediaPreviewMode = 'image'
+					this.featuredCommentMediaPreviewUrls = urls
+					this.featuredCommentMediaPreviewIndex = i
+					this.featuredCommentMediaPreviewVideoUrl = ''
+					this.featuredCommentMediaPreviewPoster = ''
+					this.featuredCommentMediaPreviewShow = true
+					return
+				}
+				const vurl = this.getCommentVideoUrl(it)
+				if (!vurl) return
+				this._pauseCourseVideo()
+				try {
+					const id = this.getFeaturedCommentVideoId(it, listIdx)
+					const c = uni.createVideoContext(id, this)
+					if (c && c.pause) c.pause()
+				} catch (e) {}
+				this.featuredCommentMediaPreviewMode = 'video'
+				this.featuredCommentMediaPreviewUrls = []
+				this.featuredCommentMediaPreviewIndex = 0
+				this.featuredCommentMediaPreviewVideoUrl = vurl
+				this.featuredCommentMediaPreviewPoster = this.getCommentVideoPoster(it) || ''
+				this.featuredCommentMediaPreviewShow = true
+				this._tryPlayFeaturedModalVideo()
+			},
+			_tryPlayFeaturedModalVideo() {
+				if (this.featuredCommentMediaPreviewMode !== 'video' || !this.featuredCommentMediaPreviewVideoUrl) {
+					return
+				}
+				const run = () => {
+					try {
+						const c = uni.createVideoContext('fc-media-preview-video', this)
+						if (c && c.play) c.play()
+					} catch (e) {}
+				}
+				this.$nextTick(() => {
+					run()
+					setTimeout(run, 100)
+					setTimeout(run, 280)
+				})
+			},
+			/** 微信小程序编译不接受 @tap.stop="",需绑定空实现以阻止冒泡到遮罩 */
+			featuredCommentPreviewCardTap() {},
+			closeFeaturedCommentMediaPreview() {
+				if (!this.featuredCommentMediaPreviewShow) return
+				try {
+					const c = uni.createVideoContext('fc-media-preview-video', this)
+					if (c && c.pause) c.pause()
+				} catch (e) {}
+				this.featuredCommentMediaPreviewShow = false
+				this.featuredCommentMediaPreviewUrls = []
+				this.featuredCommentMediaPreviewVideoUrl = ''
+				this.featuredCommentMediaPreviewPoster = ''
+			},
+			setFeaturedMediaPreviewIndex(ti) {
+				const n = Number(ti)
+				if (
+					!Number.isFinite(n) ||
+					n < 0 ||
+					n >= (this.featuredCommentMediaPreviewUrls || []).length
+				) {
+					return
+				}
+				this.featuredCommentMediaPreviewIndex = n
+			},
+			onFeaturedMediaPreviewModalVideoPlay() {
+				this._pauseCourseVideo()
+				const list = this.featuredCommentDisplayList || []
+				for (let i = 0; i < list.length; i++) {
+					const row = list[i]
+					if (!this.getCommentVideoUrl(row)) continue
+					const vid = this.getFeaturedCommentVideoId(row, i)
+					try {
+						const c = uni.createVideoContext(vid, this)
+						if (c && c.pause) c.pause()
+					} catch (e) {}
+				}
+			},
+			_featuredMediaMaxBytes() {
+				return 100 * 1024 * 1024
+			},
+			/** 相册/选中返回的本地路径大小:安卓上 chooseMedia 常给 size=0,getFileInfo 也可能失真,改用 statSync 兜底 */
+			_readFeaturedLocalFileSizeBytes(filePath) {
+				return new Promise((resolve) => {
+					const tryFsStat = () => {
+						let n = 0
+						// #ifdef MP-WEIXIN
+						try {
+							const fs = wx.getFileSystemManager && wx.getFileSystemManager()
+							if (fs && fs.statSync) {
+								const st = fs.statSync(filePath)
+								if (st && typeof st.size === 'number' && st.size > 0) n = st.size
+							}
+						} catch (e) {}
+						// #endif
+						return n
+					}
+					if (!filePath || typeof filePath !== 'string') {
+						resolve(0)
+						return
+					}
+					uni.getFileInfo({
+						filePath,
+						success: (fi) => {
+							let sz =
+								fi && fi.size != null ? Math.floor(Number(fi.size)) : 0
+							if (!Number.isFinite(sz) || sz <= 0) sz = tryFsStat()
+							resolve(sz)
+						},
+						fail: () => resolve(tryFsStat())
+					})
+				})
+			},
+			_alertFeaturedMediaLimit(content) {
+				uni.showModal({
+					title: '提示',
+					content:
+						content ||
+						'图片或视频大小不能超过100MB,请压缩或更换后再试。',
+					showCancel: false,
+					confirmText: '知道了'
+				})
+			},
+			_assertFeaturedLocalMediaUnderMaxBytes(filePath) {
+				const max = this._featuredMediaMaxBytes()
+				return new Promise((resolve) => {
+					if (!filePath || typeof filePath !== 'string') {
+						this._alertFeaturedMediaLimit('文件路径无效,请重新选择。')
+						resolve(false)
+						return
+					}
+					this._readFeaturedLocalFileSizeBytes(filePath).then((sz) => {
+						if (sz <= 0) {
+							uni.showToast({
+								title: '本地暂无法读取大小,请勿超过100MB',
+								icon: 'none',
+								duration: 2600
+							})
+							resolve(true)
+							return
+						}
+						if (sz > max) {
+							this._alertFeaturedMediaLimit()
+							resolve(false)
+							return
+						}
+						resolve(true)
+					})
+				})
+			},
+			_applyFeaturedMediaIfSizeOk(type, path, size, thumbTempPath) {
+				const max = this._featuredMediaMaxBytes()
+				const applyAccepted = () => {
+					this.featuredCommentMedia = {
+						type,
+						path,
+						thumbTempPath: thumbTempPath || ''
+					}
+				}
+				let bytes =
+					size != null && Number(size) > 0
+						? Math.floor(Number(size))
+						: 0
+				if (!Number.isFinite(bytes)) bytes = 0
+				const finalize = (n) => {
+					if (n > max) {
+						this._alertFeaturedMediaLimit()
+						return
+					}
+					applyAccepted()
+				}
+				if (bytes > 0) {
+					finalize(bytes)
+					return
+				}
+				this._readFeaturedLocalFileSizeBytes(path).then(finalize)
+			},
+			clearFeaturedCommentMedia() {
+				this.featuredCommentMedia = null
+				this._resumeCourseVideoAfterFeaturedJob()
+			},
+			/**
+			 * 竖屏课且仅「精选留言」一个 Tab 时,竖版布局下留言区被隐藏;
+			 * 切到横版布局(isShu=false),与全屏按钮切换布局一致。
+			 */
+			_expandLayoutIfPortraitFeaturedCommentsOnly() {
+				if (this.displayType !== 'portrait') return
+				if (!this.isShu) return
+				if (!(this.visibleRatingTabCount === 1 && this.showTabFeaturedComments)) return
+				this.isShu = false
+				this.tabIndex = 0
+			},
+			/** 避免选图/选视频从原生页返回时 onShow 重复拉课程详情;若未触发 onShow 则在 complete 后兜底清除标志 */
+			_armFeaturedMediaPickerOnShowSuppress() {
+				this.videovipSuppressOnShowCourseFetchOnce = true
+				const clearIfStillArmed = () => {
+					setTimeout(() => {
+						if (this.videovipSuppressOnShowCourseFetchOnce) {
+							this.videovipSuppressOnShowCourseFetchOnce = false
+						}
+					}, 600)
+				}
+				return clearIfStillArmed
+			},
+			onFeaturedPickMedia() {
+				this._expandLayoutIfPortraitFeaturedCommentsOnly()
+				this.featuredMediaActionSheetShow = true
+			},
+			closeFeaturedMediaActionSheet() {
+				this.featuredMediaActionSheetShow = false
+			},
+			onFeaturedMediaSheetPick(tapIndex) {
+				this.closeFeaturedMediaActionSheet()
+				// 立即调起相册/视频会与 u-popup 遮罩关闭叠加,小程序端易残留半透明层;对齐关闭动画后再打开系统选择器
+				const afterSheetCloseMs = 350
+				setTimeout(() => {
+					if (tapIndex === 0) {
+						this._shouldResumeCourseVideoAfterFeaturedUpload =
+							!this.isEnded &&
+							(this.videoPlaying || this._courseWasPlayingBeforeFeaturedCommentOpen)
+						this._pauseCourseVideo()
+						const clearIfStillArmed = this._armFeaturedMediaPickerOnShowSuppress()
+						uni.chooseImage({
+							count: 1,
+							sizeType: ['compressed', 'original'],
+							sourceType: ['album', 'camera'],
+							success: (res) => {
+								const f0 = res.tempFiles && res.tempFiles[0]
+								const path =
+									(res.tempFilePaths && res.tempFilePaths[0]) ||
+									(f0 && f0.path) ||
+									''
+								if (!path) return
+								const size = f0 && f0.size != null ? f0.size : 0
+								this._applyFeaturedMediaIfSizeOk('image', path, size, '')
+							},
+							fail: () => {
+								// 勿在此处清 suppress:须由 onShow 消费,避免先于 onShow 清标志导致停跑马灯
+								this._resumeCourseVideoAfterFeaturedJob()
+							},
+							complete: clearIfStillArmed
+						})
+					} else if (tapIndex === 1) {
+						this._shouldResumeCourseVideoAfterFeaturedUpload =
+							!this.isEnded &&
+							(this.videoPlaying || this._courseWasPlayingBeforeFeaturedCommentOpen)
+						this._pauseCourseVideo()
+						const clearIfStillArmed = this._armFeaturedMediaPickerOnShowSuppress()
+						wx.chooseMedia({
+							count: 1,
+							mediaType: ['video'],
+							sourceType: ['album'],
+							maxDuration: 30,
+							success: (res) => {
+								const path = res.tempFiles[0].tempFilePath
+								if (!path) return
+								const size = res.tempFiles[0].size != null ? res.tempFiles[0].size : 0
+								this._applyFeaturedMediaIfSizeOk('video', path, size, res.tempFiles[0].thumbTempFilePath || '')
+							},
+							fail: (err) => {
+								//console.log('huoqu122221212122222222', err)
+								// 勿在此处清 suppress:须由 onShow 消费,避免先于 onShow 清标志导致停跑马灯
+								this._resumeCourseVideoAfterFeaturedJob()
+							},
+							complete: clearIfStillArmed
+						})
+					}
+				}, afterSheetCloseMs)
+			},
+			async submitFeaturedComment() {
+				const raw = this.featuredCommentInput || ''
+				const text = raw.trim()
+				if (raw.length > 50) {
+					uni.showToast({
+						title: '留言不能超过50个字',
+						icon: 'none'
+					})
+					this._resumeCourseVideoAfterFeaturedJob()
+					return
+				}
+				const media = this.featuredCommentMedia
+				const hasMedia = !!(media && media.path)
+				if (!text && !hasMedia) {
+					uni.showToast({
+						title: '请输入留言或选择图片/视频',
+						icon: 'none'
+					})
+					return
+				}
+				const u = this._resolveUserInfoObj()
+				const userId = u.userId || ''
+				if (!userId) {
+					uni.showToast({
+						title: '请先登录',
+						icon: 'none'
+					})
+					this._resumeCourseVideoAfterFeaturedJob()
+					return
+				}
+				if (this.featuredCommentSending) return
+				if (hasMedia && media.path) {
+					const ok = await this._assertFeaturedLocalMediaUnderMaxBytes(media.path)
+					if (!ok) {
+						this._resumeCourseVideoAfterFeaturedJob()
+						return
+					}
+				}
+				this.featuredCommentSending = true
+				const done = (res) => {
+					this.featuredCommentSending = false
+					if (res.code == 200) {
+						this.featuredCommentInput = ''
+						this.featuredCommentMedia = null
+						this._closeFeaturedCommentComposerUi()
+						uni.showToast({
+							title: '发送成功',
+							icon: 'none'
+						})
+						this.loadFeaturedComments({
+							scrollToBottom: true
+						})
+					} else {
+						uni.showToast({
+							title: res.msg || '发送失败',
+							icon: 'none'
+						})
+					}
+				}
+				const fail = (err) => {
+					this.featuredCommentSending = false
+					const msg = err && err.message ? err.message : '网络异常,请重试'
+					uni.showToast({
+						title: msg,
+						icon: 'none'
+					})
+				}
+				const payload = {
+					toUserId: userId,
+					courseId: this.courseId,
+					videoId: this.videoId,
+					type: 1,
+					content: text
+				}
+				if (hasMedia) {
+					if (media.type === 'video') {
+						payload.videoFiles = media.path
+					} else {
+						payload.imageFiles = media.path
+					}
+				}
+				uni.showLoading({
+					title: '发布中',
+					mask: true
+				})
+				addCommentWithMedia(payload)
+					.then((res) => {
+						uni.hideLoading()
+						done(res)
+					})
+					.catch((err) => {
+						uni.hideLoading()
+						fail(err)
+					})
+					.finally(() => {
+						// 与 hideLoading、列表刷新错开一帧,避免部分机型上 play 被吞
+						this.$nextTick(() => {
+							setTimeout(() => {
+								this._resumeCourseVideoAfterFeaturedJob()
+							}, 60)
+						})
+					})
+			},
+			_vipTimeStrToSec(timeStr) {
+				if (!timeStr || typeof timeStr !== 'string') return 0
+				const parts = timeStr.split(':')
+				if (parts.length !== 3) return 0
+				const h = parseInt(parts[0], 10) || 0
+				const m = parseInt(parts[1], 10) || 0
+				const s = parseInt(parts[2], 10) || 0
+				return h * 3600 + m * 60 + s
+			},
+			_vipShelfTimeValid(timeStr) {
+				if (!timeStr || typeof timeStr !== 'string') return false
+				if (timeStr === '00:00:00') return false
+				return this._vipTimeStrToSec(timeStr) > 0
+			},
+			/** 缓存下单时间戳(videovip_myPurchase_*)序列化后可能为字符串,统一为毫秒数 */
+			_normalizePurchaseTs(ts) {
+				if (ts == null || ts === '') return 0
+				const n = typeof ts === 'number' ? ts : Number(ts)
+				return Number.isFinite(n) && n > 0 ? n : 0
+			},
+			_readVipSelfPurchaseTsMs() {
+				const row = uni.getStorageSync('videovip_myPurchase_' + this.videoId)
+				return this._normalizePurchaseTs(row && row.ts)
+			},
+			refreshVipPurchaseMarqueeFlag() {
+				const key = 'videovip_myPurchase_' + this.videoId
+				const consumedKey = 'videovip_myPurchaseMarqueeConsumed_' + this.videoId
+				const row = uni.getStorageSync(key)
+				const consumed = uni.getStorageSync(consumedKey)
+				const tsMs = this._normalizePurchaseTs(row && row.ts)
+				if (tsMs && Date.now() - tsMs <= 10 * 60 * 1000) {
+					// 同一笔下单 ts 仅允许跑马灯展示一次;中途退出再进不再展示(新下单 ts 变化后会再展示一次)
+					const consumedTs = this._normalizePurchaseTs(consumed && consumed.ts)
+					this.pendingSelfMarqueeFirst = !(consumedTs > 0 && consumedTs === tsMs)
+				} else {
+					this.pendingSelfMarqueeFirst = false
+					if (row && row.ts != null && row.ts !== '') {
+						uni.removeStorageSync(key)
+						const consumedTs = this._normalizePurchaseTs(consumed && consumed.ts)
+						if (consumedTs > 0 && consumedTs === tsMs) uni.removeStorageSync(consumedKey)
+					}
+				}
+			},
+			_markSelfPurchaseMarqueeConsumed() {
+				const tsMs = this._readVipSelfPurchaseTsMs()
+				if (!tsMs) return
+				try {
+					uni.setStorageSync('videovip_myPurchaseMarqueeConsumed_' + this.videoId, { ts: tsMs })
+				} catch (e) {}
+			},
+			formatSelfPurchaseMarqueePayload() {
+				const tsMs = this._readVipSelfPurchaseTsMs()
+				if (!tsMs) {
+					return {
+						type: 'self',
+						nickname: '您本人',
+						maskedId: '',
+						timeOffset: '刚刚',
+						suffix: '已下单',
+						fullText: '您本人刚刚已下单'
+					}
+				}
+				const secTotal = Math.floor((Date.now() - tsMs) / 1000)
+				if (secTotal < 60) {
+					const text = `${Math.max(1, secTotal)}秒前`
+					return {
+						type: 'self',
+						nickname: '您本人',
+						maskedId: '',
+						timeOffset: text,
+						suffix: '已下单',
+						fullText: `您本人${text}已下单`
+					}
+				}
+				const min = Math.min(10, Math.floor(secTotal / 60))
+				const text = `${Math.max(1, min)}分钟前`
+				return {
+					type: 'self',
+					nickname: '您本人',
+					maskedId: '',
+					timeOffset: text,
+					suffix: '已下单',
+					fullText: `您本人${text}已下单`
+				}
+			},
+			_syncFakeMarqueeIfEligibleChanged() {
+				const val = this.fakeMarqueeEligible
+				if (val === this._fakeMarqueeEligiblePrev) return
+				this._fakeMarqueeEligiblePrev = val
+				if (val) {
+					if (this._marqueeStartDebounceTimer) {
+						clearTimeout(this._marqueeStartDebounceTimer)
+						this._marqueeStartDebounceTimer = null
+					}
+					this._marqueeStartDebounceTimer = setTimeout(() => {
+						this._marqueeStartDebounceTimer = null
+						if (this.fakeMarqueeEligible && !this._fakeMarqueeStarted) {
+							this.ensureFakeMarqueeStarted()
+						}
+					}, 300)
+				} else {
+					if (this._marqueeStartDebounceTimer) {
+						clearTimeout(this._marqueeStartDebounceTimer)
+						this._marqueeStartDebounceTimer = null
+					}
+					this.stopFakeMarqueeLoop()
+				}
+			},
+			ensureFakeMarqueeStarted() {
+				if (!this.fakeMarqueeEligible || this._fakeMarqueeStarted) return
+				this._fakeMarqueeStarted = true
+				if (!this.fakeOrderPool.length) {
+					this.fakeOrderPool = buildFakeOrderPool()
+				}
+				this.applyFakeMarqueeTick()
+				this.scheduleFakeMarqueeNext()
+				this._startSelfMarqueeClockIfNeeded()
+			},
+			applyFakeMarqueeTick() {
+				if (this.isTripleMarqueeMode) {
+					const rows = this.buildTripleMarqueePayloads()
+					this.setTripleMarqueeDisplayWithAnim(rows)
+					// 本人下单在三联模式也只展示一轮,下一轮起恢复纯虚拟随机
+					if (rows.some(item => item && item.type === 'self')) {
+						this.pendingSelfMarqueeFirst = false
+						this._markSelfPurchaseMarqueeConsumed()
+					}
+					if (rows.length) {
+						this.marqueeDisplayPayload = rows[0]
+						this.marqueeDisplaySelf = this.marqueeDisplayPayload.type === 'self'
+					}
+					return
+				}
+				this.marqueeTriplePayloads = []
+				this.marqueeTripleIncomingPayloads = []
+				this.marqueeTripleSwitching = false
+				const tsMs = this._readVipSelfPurchaseTsMs()
+				const purchaseOk = !!(tsMs && Date.now() - tsMs <= 10 * 60 * 1000)
+				if (purchaseOk && this.pendingSelfMarqueeFirst) {
+					const selfPayload = this.formatSelfPurchaseMarqueePayload()
+					this.marqueeCurrentText = selfPayload.fullText
+					this.marqueeSelfHighlight = true
+					this.pendingSelfMarqueeFirst = false
+					this._markSelfPurchaseMarqueeConsumed()
+					this.setMarqueeDisplayWithAnim(selfPayload, true)
+					return
+				}
+				this.marqueeSelfHighlight = false
+				if (!this.fakeOrderPool.length) {
+					this.fakeOrderPool = buildFakeOrderPool()
+				}
+				const line = this.fakeOrderPool.shift()
+				if (line) {
+					this.fakeOrderPool.push(line)
+					this.marqueeCurrentText = `${line.nickname}${line.maskedId}${line.timeOffset}${line.suffix}`
+					this.setMarqueeDisplayWithAnim({
+						type: 'virtual',
+						nickname: line.nickname,
+						maskedId: line.maskedId,
+						timeOffset: line.timeOffset,
+						suffix: line.suffix
+					}, false)
+				}
+			},
+			buildTripleMarqueePayloads() {
+				const rows = []
+				const hasSelf = this.hasRecentSelfPurchase() && this.pendingSelfMarqueeFirst
+				if (!this.fakeOrderPool.length) {
+					this.fakeOrderPool = buildFakeOrderPool()
+				}
+				let guard = 0
+				// 有本人记录时,把本人下单放第一条,其它再补足虚拟数据
+				if (hasSelf) {
+					rows.push(this.formatSelfPurchaseMarqueePayload())
+				}
+				const targetVirtualCount = hasSelf ? 2 : 3
+				let virtualCount = 0
+				while (virtualCount < targetVirtualCount && this.fakeOrderPool.length && guard < 10) {
+					const line = this.fakeOrderPool.shift()
+					guard += 1
+					if (!line) break
+					this.fakeOrderPool.push(line)
+					rows.push({
+						type: 'virtual',
+						nickname: line.nickname,
+						maskedId: line.maskedId,
+						timeOffset: line.timeOffset,
+						suffix: line.suffix
+					})
+					virtualCount += 1
+				}
+				return rows.slice(0, 3)
+			},
+			hasRecentSelfPurchase() {
+				const tsMs = this._readVipSelfPurchaseTsMs()
+				return !!(tsMs && Date.now() - tsMs <= 10 * 60 * 1000)
+			},
+			/** 按缓存 ts 与当前时间重新计算本人下单文案(停留同一轮跑马灯时也能更新相对时间) */
+			refreshSelfPurchaseMarqueeDisplayedTiming() {
+				const fresh = this.formatSelfPurchaseMarqueePayload()
+				if (this.isTripleMarqueeMode && this.marqueeTriplePayloads.length) {
+					const upd = (arr) =>
+						arr.map((r) => (r && r.type === 'self' ? Object.assign({}, fresh) : r))
+					this.marqueeTriplePayloads = upd(this.marqueeTriplePayloads)
+					if (this.marqueeTripleIncomingPayloads.length) {
+						this.marqueeTripleIncomingPayloads = upd(this.marqueeTripleIncomingPayloads)
+					}
+				}
+				if (this.marqueeDisplayPayload && this.marqueeDisplayPayload.type === 'self') {
+					this.marqueeDisplayPayload = Object.assign({}, fresh)
+				}
+				if (this.marqueeIncomingPayload && this.marqueeIncomingPayload.type === 'self') {
+					this.marqueeIncomingPayload = Object.assign({}, fresh)
+				}
+			},
+			_startSelfMarqueeClockIfNeeded() {
+				if (this._selfMarqueeClockTimer != null) return
+				if (!this.hasRecentSelfPurchase()) return
+				this._selfMarqueeClockTimer = setInterval(() => {
+					if (!this._fakeMarqueeStarted || !this.hasRecentSelfPurchase()) {
+						this._stopSelfMarqueeClock()
+						return
+					}
+					this.refreshSelfPurchaseMarqueeDisplayedTiming()
+				}, 10000)
+			},
+			_stopSelfMarqueeClock() {
+				if (this._selfMarqueeClockTimer != null) {
+					clearInterval(this._selfMarqueeClockTimer)
+					this._selfMarqueeClockTimer = null
+				}
+			},
+			/** 进入三联布局时立即补足 marqueeTriplePayloads,否则 v-if 会因 length 为 0 仍走单条分支直到下一轮定时 tick */
+			syncTripleMarqueeImmediate() {
+				if (!this.fakeMarqueeEligible || !this._fakeMarqueeStarted || !this.isTripleMarqueeMode) return
+				const rows = this.buildTripleMarqueePayloads()
+				if (!rows.length) return
+				this.setTripleMarqueeDisplayWithAnim(rows)
+				if (rows.some(item => item && item.type === 'self')) {
+					this.pendingSelfMarqueeFirst = false
+					this._markSelfPurchaseMarqueeConsumed()
+				}
+				if (rows[0]) {
+					this.marqueeDisplayPayload = rows[0]
+					this.marqueeDisplaySelf = rows[0].type === 'self'
+				}
+			},
+			setTripleMarqueeDisplayWithAnim(rows) {
+				if (!rows || !rows.length) return
+				if (!this.marqueeTriplePayloads.length) {
+					this.marqueeTriplePayloads = rows
+					this.marqueeTripleIncomingPayloads = []
+					this.marqueeTripleSwitching = false
+					return
+				}
+				if (this._marqueeTripleSwitchTimer) {
+					clearTimeout(this._marqueeTripleSwitchTimer)
+					this._marqueeTripleSwitchTimer = null
+				}
+				this.marqueeTripleIncomingPayloads = rows
+				this.marqueeTripleSwitching = true
+				this._marqueeTripleSwitchTimer = setTimeout(() => {
+					this.marqueeTriplePayloads = this.marqueeTripleIncomingPayloads
+					this.marqueeTripleIncomingPayloads = []
+					this.marqueeTripleSwitching = false
+					this._marqueeTripleSwitchTimer = null
+				}, 460)
+			},
+			setMarqueeDisplayWithAnim(payload, isSelf) {
+				if (!payload) return
+				if (!this.marqueeDisplayPayload) {
+					this.marqueeDisplayPayload = payload
+					this.marqueeDisplaySelf = !!isSelf
+					this.marqueeSwitching = false
+					this.marqueeIncomingPayload = null
+					this.marqueeIncomingSelf = false
+					return
+				}
+				if (this._marqueeSwitchTimer) {
+					clearTimeout(this._marqueeSwitchTimer)
+					this._marqueeSwitchTimer = null
+				}
+				this.marqueeIncomingPayload = payload
+				this.marqueeIncomingSelf = !!isSelf
+				this.marqueeSwitching = true
+				this._marqueeSwitchTimer = setTimeout(() => {
+					this.marqueeDisplayPayload = this.marqueeIncomingPayload
+					this.marqueeDisplaySelf = this.marqueeIncomingSelf
+					this.marqueeIncomingPayload = null
+					this.marqueeIncomingSelf = false
+					this.marqueeSwitching = false
+					this._marqueeSwitchTimer = null
+				}, 460)
+			},
+			scheduleFakeMarqueeNext() {
+				if (this._fakeMarqueeTimer) {
+					clearTimeout(this._fakeMarqueeTimer)
+					this._fakeMarqueeTimer = null
+				}
+				const delay = 4000 + Math.floor(Math.random() * 3001)
+				this._fakeMarqueeTimer = setTimeout(() => {
+					this._fakeMarqueeTimer = null
+					if (!this.fakeMarqueeEligible || !this._fakeMarqueeStarted) return
+					this.applyFakeMarqueeTick()
+					this.scheduleFakeMarqueeNext()
+				}, delay)
+			},
+			stopFakeMarqueeLoop() {
+				if (this._marqueeStartDebounceTimer) {
+					clearTimeout(this._marqueeStartDebounceTimer)
+					this._marqueeStartDebounceTimer = null
+				}
+				if (this._fakeMarqueeTimer) {
+					clearTimeout(this._fakeMarqueeTimer)
+					this._fakeMarqueeTimer = null
+				}
+				if (this._marqueeSwitchTimer) {
+					clearTimeout(this._marqueeSwitchTimer)
+					this._marqueeSwitchTimer = null
+				}
+				if (this._marqueeTripleSwitchTimer) {
+					clearTimeout(this._marqueeTripleSwitchTimer)
+					this._marqueeTripleSwitchTimer = null
+				}
+				this._fakeMarqueeStarted = false
+				this.marqueeSwitching = false
+				// 重要:清空非三联跑马灯展示 payload,避免下一次门禁打开前渲染旧内容
+				this.marqueeDisplayPayload = null
+				this.marqueeDisplaySelf = false
+				this.marqueeCurrentText = ''
+				this.marqueeSelfHighlight = false
+				this.marqueeIncomingPayload = null
+				this.marqueeIncomingSelf = false
+				this.marqueeTriplePayloads = []
+				this.marqueeTripleIncomingPayloads = []
+				this.marqueeTripleSwitching = false
+				this._stopSelfMarqueeClock()
+			},
+			goRate(index){
+				this.aindex = index
+				if (this._rateBounceTimer) {
+					clearTimeout(this._rateBounceTimer)
+					this._rateBounceTimer = null
+				}
+				this.rateBounceIndex = null
+				this.$nextTick(() => {
+					this.rateBounceIndex = index
+					this._rateBounceTimer = setTimeout(() => {
+						this.rateBounceIndex = null
+						this._rateBounceTimer = null
+					}, 480)
+				})
+			},
+			onVideoMetaLoaded(e) {
+				// const width = e.detail.width;
+				// const height = e.detail.height;
+				// const res = uni.getSystemInfoSync();
+				// const winH = res.windowHeight;
+				// const winW = res.windowWidth;
+				// //横屏
+				// const wW = (winW / winH) * 100;
+				// console.log(winH,winW,'高度')
+				// console.log(winH,winW,'高度')
+				// //竖屏
+				// if (height < width) {
+				// 	this.isHeight = true
+				// }
+			},
+			// 获取视频容器高度
+			getVideoContainerHeight() {
+			   const { windowWidth, windowHeight } = uni.getSystemInfoSync();
+			   this.isHeight = windowWidth > windowHeight;
+			   console.log('当前是否横屏:', this.isHeight);
+			},
+			fullscreenchange(event){
+				const isFullScreen = !!(event && event.detail && event.detail.fullScreen);
+				this.isFull = event.detail.fullScreen;
+				//this.getVideoContainerHeight();
+				console.log(this.isFull,'this.isFull ')
+				// 竖屏课程下:把全屏按钮当作布局切换按钮,禁止原生全屏停留
+				if (this.displayType === 'portrait') {
+					if (event && event.stopPropagation) event.stopPropagation();
+					if (event && event.preventDefault) event.preventDefault();
+					// 只在“进入全屏”时切换,避免 exitFullScreen 触发的 false 事件二次反转
+					if (!isFullScreen || this.fullscreenToggleLock) return;
+					this.fullscreenToggleLock = true;
+					// const wasShu = this.isShu
+					this.isShu = !this.isShu
+					// if (wasShu && this.showTabReviewPoints) this.tabIndex = 0
+					// 先让布局切换完成,再退出原生全屏,减少抖动闪频
+					setTimeout(() => {
+						if (this.videoContext && this.videoContext.exitFullScreen) {
+							this.videoContext.exitFullScreen();
+						}
+						this.isFull = false;
+						this.fullscreenToggleTimer = setTimeout(() => {
+							this.fullscreenToggleLock = false;
+							this.fullscreenToggleTimer = null;
+						}, 220);
+					}, 40);
+					//console.log(this.isFull,'this.isFull111 ')
+				}
+			},
+			//购物车
+			showCart(){
+				///console.log("[---]")
+				this.isCart=true
+			},
+			showMore(){
+				///console.log("[---]")
+				this.isMore=true
+			},
+			closeShop() {
+				this.isCart = false;
+			},
+			closeMore() {
+				this.isMore = false;
+			},
+			navgetTo(url){
+				uni.navigateTo({
+					url: url
+				});
+			},
+			openList(){
+				const wasShu = this.isShu
+				this.isShu = !this.isShu
+				if (wasShu && this.showTabFeaturedComments) this.tabIndex = 0
+			},
+			// 倒计时格式化函数
+			formatCountdown(seconds) {
+				const totalSeconds = Math.max(0, Math.floor(Number(seconds) || 0));
+				const hours = Math.floor(totalSeconds / 3600);
+				const remainingAfterHours = totalSeconds % 3600;
+				const minutes = Math.floor(remainingAfterHours / 60);
+				const secs = remainingAfterHours % 60;
+				return {
+					hours: this.padZero(hours),
+					minutes: this.padZero(minutes),
+					seconds: this.padZero(secs),
+					total: totalSeconds
+				};
+			},
+			getCountdownPercentage() {
+				const total = Number(this.totalRemainTime) || 0;
+				if (!total) return 0;
+				const remain = Math.max(0, Number(this.remainTime) || 0);
+				const watched = Math.max(0, total - remain);
+				const percentage = (watched / total) * 100;
+				return Math.min(100, Math.max(0, Number(percentage.toFixed(2))));
+			},
+			// 补零函数
+			padZero(num) {
+				return num < 10 ? `0${num}` : num.toString();
+			},
+			// 启动完课积分倒计时(仅在播放时递减)
+			startCountdown() {
+				if (this.remainTime <= 0 || this.countdownTimer) return;
+				this.countdownTimer = setInterval(() => {
+					if (this.remainTime > 0) {
+						this.remainTime--;
+					}
+					if (this.remainTime <= 0 && this.countdownTimer) {
+						clearInterval(this.countdownTimer);
+						this.countdownTimer = null;
+						if (!this.hasReportedAfterCountdown) {
+							this.hasReportedAfterCountdown = true;
+							this.getFinishCourseVideo();
+							this.getInternetTraffic();
+						}
+					}
+				}, 1000);
+			},
+			// 停止完课积分倒计时(暂停/离开页面时调用)
+			stopCountdown() {
+				if (this.countdownTimer) {
+					clearInterval(this.countdownTimer);
+					this.countdownTimer = null;
+				}
+			},
+			//剩余时间
+			getRemainTime(userId) {
+				var data = {
+					"videoId": this.videoId,
+					"fsUserId": userId,
+					"courseId": this.courseId,
+					"projectId":this.projectId,
+					"periodId":this.periodId,
+					"companyUserId": this.companyUserId
+				}
+				getRemainTime(data).then(res => {
+					if (res.code == 200) {
+						const remain = Number(res.remainTime) || 0; // 积分看课剩余时间(秒)
+						this.remainTime = remain;
+						this.remainTimeReady = true;
+						this.hasReportedAfterCountdown = remain <= 0;
+						// 初始化或刷新总时长,用于进度条百分比
+						if (!this.totalRemainTime || remain > this.totalRemainTime) {
+							this.totalRemainTime = remain;
+						}
+					} else {
+						this.remainTimeReady = false
+						uni.showToast({
+							icon: 'none',
+							title: res.msg,
+						});
+					}
+				})
+			},
+			getWebviewUrl() {
+				var data = {
+					key: 'course.config'
+				}
+				getConfigByKey(data).then(res => {
+					if (res.code == 200) {
+						console.log("getConfigByKey====", JSON.parse(res.data))
+						let data = JSON.parse(res.data)
+						this.notice = data.camelCase
+						uni.setStorageSync('setWebviewUrl', data.userCourseAuthDomain)
+					} else {
+						uni.showToast({
+							icon: 'none',
+							title: res.msg,
+						});
+					}
+				})
+			},
+			tabChange(type) {
+				this.currentId = type
+			},
+			kefpop() {
+				if (this.appToken) {
+					this.kfPopup == false
+				}
+			},
+			tosales() {
+				uni.switchTab({
+					url: "/pages/index/index"
+				})
+			},
+			closepop() {
+				this.answerPopup = false
+			},
+			open() {
+
+			},
+			getMenuButton() {
+				const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
+				this.menuButtonLeft = menuButtonInfo.left
+				this.menuButtonH = menuButtonInfo.height
+			},
+			_touchAntiSeekSuppress(ms = 2000) {
+				const until = Date.now() + ms
+				if (until > (this._antiSeekSuppressExpireAt || 0)) this._antiSeekSuppressExpireAt = until
+			},
+			//播放时间更新事件方法
+			onTimeUpdate(e) {
+				let currentTime = Math.round(e.detail.currentTime)
+				if (this.playDurationSeek > 0) {
+					this.playTime = this.playDurationSeek
+					this.throttle(() => this.changeTime(this), 1000, false)
+				} else {
+					// console.log(this.isFinish)
+					const suppressAntiSeek = Date.now() < (this._antiSeekSuppressExpireAt || 0)
+					if (!suppressAntiSeek && this.linkType != 1 && (currentTime - this.playTime > 3 || currentTime - this
+						.playTime < -3) && this
+						.isFinish != 1) {
+						uni.showToast({
+							title: '不能快进哦',
+							icon: 'none',
+						});
+						currentTime = this.playTime
+						this.player.seek(this.playTime);
+					}
+
+					if (Math.floor(e.detail.currentTime) != this.flagTime) {
+						this.flagTime = Math.floor(e.detail.currentTime)
+						// 中途弹窗逻辑
+						if (!this.tipsOpen && this.tipsTime && this.playTime == this.tipsTime) {
+							this.timepath = '33%'
+							this.openTipsPop()
+						}
+						if (!this.tipsOpen && this.tipsTime2 && this.playTime == this.tipsTime2) {
+							this.timepath = '66%'
+							this.openTipsPop()
+						}
+					}
+					this.playTime = currentTime
+					this.updateProductAndCardDisplay(currentTime)
+				}
+			},
+			// 根据当前播放时间:1)扫描商品栏展示(上架/下架时间)2)控制商品卡片弹窗(弹出/关闭时间)
+			updateProductAndCardDisplay(currentSec) {
+				const toSeconds = (timeStr) => {
+					if (!timeStr || typeof timeStr !== 'string') return 0
+					const parts = timeStr.split(':')
+					if (parts.length !== 3) return 0
+					const h = parseInt(parts[0], 10) || 0
+					const m = parseInt(parts[1], 10) || 0
+					const s = parseInt(parts[2], 10) || 0
+					return h * 3600 + m * 60 + s
+				}
+				const hasValidShelfTime = (timeStr) => {
+					if (!timeStr || typeof timeStr !== 'string') return false
+					if (timeStr === '00:00:00') return false
+					return !!toSeconds(timeStr)
+				}
+				if (this.treatmentPackage.length === 0) {
+					this.displayProductList = []
+					this.cardPopup = false
+					this.currentCardItem = null
+					this._syncFakeMarqueeIfEligibleChanged()
+					return
+				}
+				// 按“上架时间”倒序排序,保证后上架商品展示在列表最前
+				const sortedTreatmentPackage = this.treatmentPackage.slice().sort((a, b) => {
+					const aOn = hasValidShelfTime(a.onShelfTime) ? toSeconds(a.onShelfTime) : 0
+					const bOn = hasValidShelfTime(b.onShelfTime) ? toSeconds(b.onShelfTime) : 0
+					if (bOn !== aOn) return bOn - aOn
+					// 上架时间相同则按下架时间倒序,进一步保证新近优先
+					const aOff = hasValidShelfTime(a.offShelfTime) ? toSeconds(a.offShelfTime) : 0
+					const bOff = hasValidShelfTime(b.offShelfTime) ? toSeconds(b.offShelfTime) : 0
+					return bOff - aOff
+				})
+				const videoDuration = this.duration || 0
+				// 1. 商品栏展示:按上架/下架时间过滤
+				this.displayProductList = sortedTreatmentPackage.filter(item => {
+					// 上架时间必填;下架时间可为空(为空表示一直展示到视频结束)
+					if (!hasValidShelfTime(item.onShelfTime)) return false
+					const onShelfSec = toSeconds(item.onShelfTime)
+					if (currentSec < onShelfSec) return false
+					const hasOffShelfTime = hasValidShelfTime(item.offShelfTime)
+					if (!hasOffShelfTime) return true
+					const offShelfSec = toSeconds(item.offShelfTime)
+					if (videoDuration > 0 && offShelfSec > videoDuration) return true
+					return currentSec < offShelfSec
+				})
+				//console.log('this.displayProductList',this.displayProductList)
+				// 2. 商品卡片弹窗:按弹出/关闭时间查找当前应展示的卡片
+				let activeCard = null
+				let activePopupSec = -1
+				for (let i = 0; i < sortedTreatmentPackage.length; i++) {
+					const item = sortedTreatmentPackage[i]
+					const popupStr = item.cardPopupTime
+					const closeStr = item.cardCloseTime
+					if (!popupStr || popupStr === '00:00:00') continue
+					const popupSec = toSeconds(popupStr)
+					if (!popupSec) continue
+					const closeSec = (closeStr && closeStr !== '00:00:00') ? toSeconds(closeStr) : null
+					if (currentSec >= popupSec && (closeSec == null || currentSec < closeSec)) {
+						// 同时命中多个弹窗时:优先展示“启动时间更晚”的后续弹窗
+						if (popupSec > activePopupSec) {
+							activePopupSec = popupSec
+							activeCard = item
+						} else if (popupSec === activePopupSec && activeCard) {
+							// 上架时间更晚优先(兜底)
+							const activeOn = hasValidShelfTime(activeCard.onShelfTime) ? toSeconds(activeCard.onShelfTime) : 0
+							const itemOn = hasValidShelfTime(item.onShelfTime) ? toSeconds(item.onShelfTime) : 0
+							if (itemOn > activeOn) activeCard = item
+						}
+					}
+				}
+				const activeCardKey = activeCard ?
+					`${activeCard.productId || ''}_${activeCard.cardPopupTime || ''}_${activeCard.cardCloseTime || ''}` :
+					''
+				if (!activeCardKey) {
+					this.dismissedCardKey = ''
+				}
+				this.cardPopup = !!activeCard && this.dismissedCardKey !== activeCardKey
+				//this.getVideoContainerHeight()
+				this.currentCardItem = activeCard
+				this.syncProductHotCounts()
+				this._syncFakeMarqueeIfEligibleChanged()
+			},
+			closeCardPopup() {
+				if (this.currentCardItem) {
+					this.dismissedCardKey =
+						`${this.currentCardItem.productId || ''}_${this.currentCardItem.cardPopupTime || ''}_${this.currentCardItem.cardCloseTime || ''}`
+				}
+				this.cardPopup = false
+			},
+			hasHotSaleTag(item) {
+				return hasHotSaleTag(item)
+			},
+			getProductHotCount(item) {
+				if (!hasHotSaleTag(item)) return 0
+				const key = getProductHotKey(item)
+				return key ? clampHotSaleCount(this.productHotCountMap[key]) : 0
+			},
+			_collectHotSaleProducts() {
+				const seen = new Set()
+				const list = []
+				const add = (item) => {
+					if (!hasHotSaleTag(item)) return
+					const key = getProductHotKey(item)
+					if (!key || seen.has(key)) return
+					seen.add(key)
+					list.push(item)
+				}
+				;(this.displayProductList || []).forEach(add)
+				if (this.cardPopup && this.currentCardItem) add(this.currentCardItem)
+				return list
+			},
+			_randomInt(min, max) {
+				return Math.floor(Math.random() * (max - min + 1)) + min
+			},
+			syncProductHotCounts() {
+				const products = this._collectHotSaleProducts()
+				const next = { ...this.productHotCountMap }
+				const activeKeys = new Set()
+				products.forEach((item) => {
+					const key = getProductHotKey(item)
+					if (!key) return
+					activeKeys.add(key)
+					if (!next[key]) {
+						next[key] = clampHotSaleCount(this._randomInt(100, 800))
+					}
+				})
+				Object.keys(next).forEach((key) => {
+					if (!activeKeys.has(key)) delete next[key]
+				})
+				this.productHotCountMap = next
+				if (activeKeys.size) {
+					this.startProductHotTimer()
+				} else {
+					this.stopProductHotTimer()
+				}
+			},
+			startProductHotTimer() {
+				if (this.productHotTimer) return
+				this.productHotTimer = setInterval(() => {
+					const products = this._collectHotSaleProducts()
+					if (!products.length) return
+					const next = { ...this.productHotCountMap }
+					products.forEach((item) => {
+						const key = getProductHotKey(item)
+						if (key && next[key]) {
+							next[key] = clampHotSaleCount(next[key] + this._randomInt(10, 20))
+						}
+					})
+					this.productHotCountMap = next
+				}, 30000)
+			},
+			stopProductHotTimer() {
+				if (this.productHotTimer) {
+					clearInterval(this.productHotTimer)
+					this.productHotTimer = null
+				}
+			},
+			changeTime(that, e) {
+				that.playDurationSeek = 0
+			},
+			videoErrorCallback(e) {
+				this.clearIntegral()
+				this.errorCount++
+				if (this.errorCount > 3) return
+				console.log(e)
+				this.getErrMsg(e.target.errMsg)
+				this.getH5CourseVideoDetails('error')
+			},
+			// 商品卡片跳转
+			goBuy(item) {
+				if (!item || !item.productId) return
+				uni.navigateTo({
+					url: '/pages/shopping/productDetails?productId=' + item.productId +
+						'&companyId=' + (this.urlOption.companyId || '') +
+						'&companyUserId=' + (this.urlOption.companyUserId || '') +
+						'&courseId=' + (this.urlOption.courseId || '') +
+						'&videoId=' + (this.urlOption.videoId || '') +
+						'&projectId=' + (this.urlOption.projectId || '') +
+						'&periodId=' + (this.urlOption.periodId || '')
+				})
+			},
+			// 当开始/继续播放时触发play事件
+			getPlay() {
+				this.errorCount = 0
+				this.videoPlaying = true
+				// this.judgeDuration()
+				// 开始播放时启动完课积分倒计时
+				this.startCountdown()
+			},
+			getPause() {
+				this.videoPlaying = false
+				this.clearIntegral()
+				// 暂停时停止完课积分倒计时
+				this.stopCountdown()
+			},
+			getEnded() {
+				this.videoPlaying = false
+				this.clearIntegral()
+				// 播放结束时停止完课积分倒计时
+				this.stopCountdown()
+				this.isEnded = true
+				this.isFinish = 1
+				this.getFinishCourseVideo()
+			},
+			getIP() {
+				uni.request({
+					url: 'https://ipinfo.io/json', //仅为示例,并非真实接口地址。
+					method: 'GET',
+					success: (res) => {
+						this.ip = res.data.ip
+					}
+				});
+			},
+			getHeight() {
+				this.height =
+					`calc(100vh - 420rpx - 160rpx)`
+				// this.$nextTick(() => {
+				// 	const query = uni.createSelectorQuery().in(this);
+				// 	query
+				// 		.select("#title-content")
+				// 		.boundingClientRect((data) => {
+				// 			this.height =
+				// 				`calc(100vh - ${data.height}px - 420rpx)`
+				// 		})
+				// 		.exec();
+				// })
+			},
+			getDescHeight() {
+				// this.$nextTick(() => {
+				// 	const query = uni.createSelectorQuery().in(this);
+				// 	query
+				// 		.select("#descbox-desc")
+				// 		.boundingClientRect((data) => {
+				// 			this.textHeight = data.height
+				// 		})
+				// 		.exec();
+				// })
+			},
+			numberToLetter(num) {
+				// 将数字转换为字母的 ASCII 码
+				let letterCode = num + 65;
+				// 将 ASCII 码转换为大写字母
+				let letter = String.fromCharCode(letterCode);
+				return letter;
+			},
+			updateTime() {
+				var that = this;
+				if (this.interval != null) {
+					clearInterval(this.interval)
+				}
+				this.interval = setInterval(function() {
+					that.getFinishCourseVideo()
+					that.getInternetTraffic()
+				}, 60000);
+			},
+			judgeDuration() {
+				var that = this;
+				if (this.intervalIntegral != null) {
+					clearInterval(this.intervalIntegral)
+					this.intervalIntegral = null
+				}
+				// 观看10分钟获得积分
+				this.intervalIntegral = setInterval(function() {
+					that.getIntegralByH5Video()
+				}, 600000);
+			},
+			clearIntegral() {
+				if (this.intervalIntegral != null) {
+					clearInterval(this.intervalIntegral)
+					this.intervalIntegral = null
+				}
+			},
+			// 展开简介
+			handleExpand() {
+				this.isExpand = !this.isExpand
+			},
+			getH5CourseByVideo() {
+				this.loading = true
+				getH5CourseByVideoId({
+					videoId: this.videoId
+				}).then(res => {
+						this.loading = false
+						if (res.code == 200) {
+							this.viewload = false
+							this.courseInfo = res.data
+							uni.setNavigationBarTitle({
+								title: this.courseInfo && this.courseInfo.title ? this.courseInfo.title : ''
+							});
+							this.$nextTick(() => {
+								this._syncRatingTabIndex()
+							})
+						}
+						this.getHeight()
+						this.getDescHeight()
+					},
+					rej => {
+						this.loading = false
+					}
+				).catch(() => {
+					this.loading = false
+				})
+			},
+			getH5CourseVideoDetails(type) {
+				uni.showLoading({
+					title: '加载中'
+				})
+				  //var user = uni.getStorageSync('userInfo');
+					const data = {
+						videoId: this.videoId,
+						fsUserId: this.userInfo.userId,
+						courseId: this.courseId,
+						companyUserId: this.companyUserId,
+						periodId: this.periodId,
+						id: this.timeid
+					}
+				getH5CourseVideoDetails(data).then(res => {
+						if (res.code == 200) {
+							this.config = res.data.courseConfig || {}
+							this.isFinish = res.data.isFinish || 0
+							this.duration = res.data.courseVideoDetails &&
+								res.data.courseVideoDetails.duration ? res.data.courseVideoDetails.duration : 0
+							this.courseLogo = this.config && JSON.stringify(this.config) != '{}' ? this.config
+								.courseLogo : ''
+							this.playDuration = res.data.playDuration || 0
+							this.playDurationSeek = res.data.playDuration || 0
+							// this.tipsTime =  38
+							this.tipsTime = res.data.tipsTime || 0
+							this.tipsTime2 = res.data.tipsTime2 || 0
+							this.displayType = res.data.courseVideoDetails && res.data.courseVideoDetails
+								.displayType != '' ? res.data.courseVideoDetails.displayType :'landscape'
+								this.isShu = this.displayType=='landscape'?false:true
+							const showTreatmentFlag = res.data.courseVideoDetails && res.data.courseVideoDetails
+								.showProduct != null ? res.data.courseVideoDetails.showProduct : 1
+							this.treatmentPackage = res.data.courseVideoDetails && res.data.courseVideoDetails
+								.fsStoreProductScrms ? res.data.courseVideoDetails.fsStoreProductScrms : []
+							this.showTreatment = showTreatmentFlag == 0 && this.treatmentPackage.length > 0 ? 0 : 1;
+							//console.log('this.showTreatment',this.showTreatment)
+							let lineList = []
+							// if (res.course && res.course.lineOne) {
+							// 	lineList.push(res.course.lineOne)
+							// }
+							// if (res.course && res.course.lineTwo) {
+							// 	lineList.push(res.course.lineTwo)
+							// }
+							// if (res.course && res.course.lineThree) {
+							// 	lineList.push(res.course.lineThree)
+							// }
+							this.lineList = lineList
+							if (!this.player || type == 'error') {
+								uni.hideLoading();
+								this.lineIndex = this.config.defaultLine
+								this.videoUrl = res.data.courseVideoDetails.videoUrl
+								this.poster = res.data.courseVideoDetails &&
+									res.data.courseVideoDetails.thumbnail ? res.data.courseVideoDetails.thumbnail : ''
+								this.videocont = res.data
+								// this.options.sources = [{
+								// 	src: this.videoUrl
+								// }]
+								// this.options.poster = res.course && res.course.imgUrl ? res.course.imgUrl : ''
+								// this.initVideo()
+								this.playTime = this.playDuration >= this.duration ? 0 : this.playDuration
+								if (this.videocont.rang) {
+									setTimeout(() => {
+										this.player = uni.createVideoContext('video-content-box');
+										this.player.seek(this.playTime)
+										this.player.play();
+										this._touchAntiSeekSuppress(2000)
+									}, 500);
+									this.timepop = false
+								} else {
+									this.timepop = true
+								}
+
+							} else {
+								// let div = document.querySelector(".vjs-progress-control");
+								// if(div) {
+								// 	if (this.isFinish == 1 || this.isEnded || this.linkType == 1) {
+								// 		div.style.pointerEvents = "auto";
+								// 	} else {
+								// 		div.style.pointerEvents = "none"; //禁止所有事件
+								// 	}
+								// }
+								this.playTime = this.playTime > this.playDuration ? this.playTime : this
+									.playDuration >= this.duration ? 0 : this.playDuration
+								this.player.seek(this.playTime)
+								this.player.play();
+								this._touchAntiSeekSuppress(2000)
+							}
+							this.updateTime();
+							// 初始扫描商品栏展示(根据上架/下架时间)
+							this.updateProductAndCardDisplay(this.playTime ?? this.playDuration ?? 0);
+							// 商品栏扫描完成后再允许虚拟跑马灯启动(延后到下一轮渲染,避免一帧闪现)
+							this.$nextTick(() => {
+								this.marqueeDataReady = true
+								this._syncFakeMarqueeIfEligibleChanged()
+							})
+							const qbl =
+								(res.data.courseVideoDetails && res.data.courseVideoDetails.questionBankList) || []
+							this.questionBankList = qbl
+							if (qbl.length === 0) {
+								this.isquestion = true
+								this.quesList = []
+							} else {
+								this.isquestion = false
+								this.quesList = qbl.map(item => ({
+									...item,
+									questionOption: JSON.parse(item.question),
+									answer: ''
+								}))
+							}
+							this.$nextTick(() => {
+								this._syncRatingTabIndex()
+							})
+						}
+						this.getHeight()
+						this.getDescHeight()
+					},
+					rej => {}
+				)
+			},
+			handleAnswer(item, option, idx) {
+				// 以“完课积分倒计时”结束作为答题资格
+				// if (!this.remainTimeReady) {
+				// 	uni.showToast({
+				// 		title: "倒计时加载中,请稍后再答题哦~",
+				// 		icon: "none"
+				// 	})
+				// 	return
+				// }
+				this.goRate(option.indexId)
+				if (Number(this.remainTime || 0) > 0) {
+					uni.showToast({
+						title: "完课倒计时结束再评分",
+						icon: "none"
+					})
+					return
+				}
+
+				if (item.type == 1) {
+					// 单选option
+					item.answer = option.name
+				} else if (item.type == 2) {
+					// 多选
+					let answer = item.answer ? item.answer.split(',') : []
+					if (answer.indexOf(option.name) === -1) {
+						answer.push(option.name)
+						item.answer = answer.join(',')
+					} else {
+						answer.splice(answer.indexOf(option.name), 1)
+						item.answer = answer.join(',')
+					}
+				}
+			},
+			submit() {
+				if (this.isExpire) {
+					uni.showToast({
+						title: '课程已过期或链接无效',
+						icon: 'none'
+					});
+					return
+				}
+				if (!this.$isLogin()) {
+					this.$showLoginPage()
+					return
+				}
+				this.isLogin = true
+				this.userInfo = this.$getUserInfo()
+				if (this.isAddKf == 1) {
+					this.courseAnswer()
+				} else if (this.videoId) {
+					this.getIsAddKf()
+				} else if (this.iskftype == 1) {
+					uni.showToast({
+						title: '已看过其他销售分享的此课程,不能重复观看',
+						icon: 'none'
+					})
+				} else {
+					this.$showLoginPage()
+				}
+			},
+			// 答题
+			courseAnswer() {
+				// 以“完课积分倒计时”结束作为答题资格
+				// if (!this.remainTimeReady) {
+				// 	uni.showToast({
+				// 		title: "倒计时加载中,请稍后再答题哦~",
+				// 		icon: "none"
+				// 	})
+				// 	return
+				// }
+				if (Number(this.remainTime || 0) > 0) {
+					uni.showToast({
+						title: "完课倒计时结束再评分",
+						icon: "none"
+					})
+					return
+				}
+				if (this.quesList.some(item => !item.answer)) {
+					uni.showToast({
+						title: "请选择评分",
+						icon: "none"
+					})
+					return
+				}
+				const questions = this.quesList.map(obj => {
+					const {
+						questionOption,
+						...rest
+					} = obj;
+					return rest;
+				});
+				const param = {
+					...this.urlOption,
+					userId: this.userInfo.userId,
+					questions: questions,
+					videoId: this.videoId,
+					duration: this.playTime,
+				}
+				this.errTitle = ""
+				this.errDesc = ""
+				this.errQues = []
+				courseAnswer(param).then(res => {
+						if (res.code == 200) {
+							if (res.incorrectQuestions) {
+								// 答题失败
+								if (res.incorrectQuestions.length > 0) {
+									this.errQues = res.incorrectQuestions
+								}
+								this.remain = res.remain || 0
+								if (res.remain > 0) {
+									this.answerPopup = true
+									this.errTitle = "很遗憾答错了"
+									this.errDesc = `<span style="color:#FF5C03">还有${res.remain}次机会,继续加油</span>`
+									// this.$refs.answerPopup.open("center")
+									this.answerPopup = true
+								}
+							} else {
+								// 答题成功
+								this.errTitle = "完课积分已到账"
+								//this.errDesc = `请选择奖励`
+								// this.$refs.answerPopup.open("center")
+								// this.answerPopup=true
+								if (res.msg == '答题成功') {
+									this.closeAnswerPopup()
+									// uni.login({
+									// 	provider: 'weixin',
+									// 	success: async loginRes => {
+									// 		console.log(loginRes)
+									// 		var code=loginRes
+									// 		this.closeAnswerPopup(loginRes.code)
+									// 	}
+									// })
+								}
+							}
+						} else {
+							if (res.msg == "该课题到达答错次数限制") {
+								this.errTitle = "答题次数超过限制"
+								this.errDesc = "以后的课程要认真学习哦"
+								// this.$refs.answerPopup.open("center")
+								this.answerPopup = true
+							} else {
+								if (res.msg.length > 14) {
+									if (res.msg == "该课程已答题完成,不可重复答题") {
+										uni.showToast({
+											title: '已评价请勿重复提交',
+											icon: 'none'
+										})
+									}else{
+										uni.showModal({
+											title: '提示',
+											content: res.msg,
+											showCancel: false,
+											confirmText: '我知道了'
+										})
+									}
+								} else {
+									uni.showToast({
+										title: res.msg,
+										icon: 'none'
+									})
+								}
+							}
+						}
+					},
+					rej => {}
+				)
+			},
+			// 选择
+			rewardChange(e) {
+				this.currentReward = e.detail.value
+			},
+			closeAnswerPopup() {
+				// this.$refs.answerPopup.close()
+				uni.showLoading({
+					title: "加载中..."
+				})
+				if (this.errTitle == '完课积分已到账') {
+					const param = {
+						...this.urlOption,
+						userId: this.userInfo.userId,
+						// rewardType: Number(this.currentReward),
+						source: 2, // 小程序
+						appId: this.appid
+					}
+					sendReward(param).then(res => {
+						if (res.code == 200) {
+							uni.hideLoading()
+							this.answerPopup = false
+							console.log('红包', res)
+							if (res.isNew && res.isNew == 1) {
+								console.log('红包配置', res)
+								const packageInfo = res.data.packageInfo || ''
+								if (packageInfo) {
+									uni.setStorageSync('receive_package', packageInfo)
+									uni.setStorageSync('mchId', res.mchId)
+									uni.navigateTo({
+										url: '/pages_course/reward'
+									})
+								}
+							} else {
+								if (res.msg.length > 14) {
+									uni.showModal({
+										title: '提示',
+										content: res.msg,
+										showCancel: false,
+										confirmText: '我知道了'
+									})
+								} else {
+									uni.showToast({
+										title: res.msg,
+										icon: 'none'
+									})
+								}
+							}
+						} else {
+							uni.hideLoading()
+							if (res.msg.length > 14) {
+								uni.showModal({
+									title: '提示',
+									content: res.msg,
+									showCancel: false,
+									confirmText: '我知道了'
+								})
+							} else {
+								uni.showToast({
+									title: res.msg,
+									icon: 'none'
+								})
+							}
+						}
+						// if(res.code == 200) {
+						// 	//重构 发红包,后台通过OPENID发零钱到 账
+						// 	//this.initWXConfig(res.package)
+						// }else {
+						// 	uni.showToast({
+						// 		title: res.msg,
+						// 		icon: 'none'
+						// 	})
+						// }
+					})
+				} else {
+					uni.hideLoading()
+					this.answerPopup = !this.answerPopup
+				}
+			},
+			// 线路
+			openPop() {
+				this.$refs.popup.open('bottom')
+			},
+			close() {
+				this.$refs.popup.close()
+			},
+			handleLine(index) {
+				var that = this;
+				if (this.lineIndex == index && this.videoUrl == this.lineList[index]) {
+					this.close()
+					return
+				} else {
+					// let div = document.querySelector(".vjs-progress-control");
+					// if(div) {
+					// 	if (this.isFinish == 1 || this.isEnded || this.linkType == 1) {
+					// 		div.style.pointerEvents = "auto";
+					// 	} else {
+					// 		div.style.pointerEvents = "none"; //禁止所有事件
+					// 	}
+					// }
+					this.lineIndex = index
+					this.videoUrl = this.lineList[index]
+					this.tipsOpen = false
+					this.playDurationSeek = this.playTime || 0
+					this.player = uni.createVideoContext('video-content-box');
+					setTimeout(function() {
+						that.player.seek(that.playDurationSeek)
+						that.player.play();
+					}, 500);
+					// this.player.src(this.lineList[index])
+					// this.player.one('loadedmetadata', () => {
+					// 	this.player.currentTime(this.playDurationSeek);
+					// 	this.player.play();
+					// });
+					this.close()
+				}
+
+			},
+			// 温馨提示
+			openTipsPop() {
+				// this.$refs.tipsPopup.open()
+				this.tipsPopup = true
+				// 暂停视频
+				this.videoContext.pause()
+				// this.tipsOpen = true
+				// this.pause()
+			},
+			closeTipsPop() {
+				// this.$refs.tipsPopup.close()
+				this.videoContext.play()
+				this.tipsPopup = !this.tipsPopup
+			},
+			// 客服
+			getIsAddKf() {
+				this.qrcode = ''
+				this.qrcodeMsg = ''
+				this.isAddKf = 0
+				this.userInfo = this.$getUserInfo()
+				if (!this.userInfo || !this.userInfo.userId) {
+					this.isLogin = false
+					return
+				}
+				const data = {
+					videoId: this.videoId,
+					userId: this.userInfo.userId,
+					companyUserId: this.companyUserId,
+					companyId: this.companyId,
+					courseId: this.courseId,
+					periodId: this.periodId,
+					projectId: this.projectId,
+					appId: this.appid,
+				}
+				// {videoId: this.videoId,qwUserId: this.qwUserId,corpId: this.corpId}
+				getIsAddKf(data).then(res => {
+						if (res.code == 200) {
+							this.isLogin = true
+							if (res.data) {
+								this.isAddKf = 1
+								if (this.userInfo) {
+								  if (typeof this.userInfo === 'string') {
+								    try {
+								      this.userInfo = JSON.parse(this.userInfo);
+								    } catch (e) {
+								      this.userInfo = {};
+								    }
+								  }
+								  if (this.userInfo.userId) {
+								    this.getH5CourseVideoDetails();
+								    this.getRemainTime(this.userInfo.userId);
+									this.loadFeaturedComments()
+								  }
+								}
+							}
+							// else{
+							// 	uni.showToast({
+							// 		title: '请联系管理员,注册为会员!',
+							// 		icon: 'none'
+							// 	});
+							// }
+						} else if (res.code == 1002) {
+							this.isAddKf = 0
+							this.qrcode = res.ext
+							this.kfPopup = true
+							uni.showToast({
+								title: "请添加管理员微信,成为会员!",
+								icon: 'none'
+							});
+							this.initExpiration(res.msg, res.code)
+						} else if (res.code == 505) {
+							this.isAddKf = 0
+							this.qrcode = res.ext
+							this.kfPopup = true
+							uni.showToast({
+								title: "管理员开启了会员审核,请等待审核!",
+								icon: 'none'
+							});
+							this.initExpiration(res.msg, res.code)
+						} else if (res.code == 406) {
+							uni.hideLoading();
+							uni.showToast({
+								icon: 'none',
+								title: '该用户已成为其他销售会员',
+							});
+							this.initExpiration(res.msg, res.code)
+						} else if (res.code == 504) {
+							this.isAddKf = 0
+							this.iskftype = 1
+							uni.showToast({
+								title: res.msg,
+								icon: 'none'
+							});
+							this.initExpiration(res.msg, res.code)
+						} else {
+							this.isAddKf = 0
+							uni.showToast({
+								title: res.msg,
+								icon: 'none'
+							});
+							this.initExpiration(res.msg, res.code)
+						}
+					},
+					err => {}
+				);
+			},
+			initExpiration(resMsg, resCode) {
+				if (resCode == 401) return;
+				this.resMsg = resMsg
+				this.resCode = resCode
+				this.showExpiration = true
+			},
+			closeKFPop() {
+				// this.$refs.kfPopup.close()
+				// this.kfPopup=!this.kfPopup
+			},
+			getFinishCourseVideo() {
+				if (!this.playTime) return
+				// {videoId: this.videoId,duration:this.playTime}
+				const param = {
+					duration: this.playTime,
+					videoId: this.videoId,
+					userId: this.userInfo.userId,
+					companyUserId: this.companyUserId
+				}
+				getFinishCourseVideo(param)
+			},
+			// 每十分钟获得积分
+			getIntegralByH5Video() {
+				const param = {
+					duration: this.playTime,
+					...this.urlOption
+				}
+				getIntegralByH5Video(param).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: "积分+10",
+							icon: "none"
+						})
+					}
+				})
+			},
+			progressChange(e) {
+				this.bufferRate = Math.ceil(e.detail.buffered)
+				// console.log('缓冲结果',this.bufferRate)
+				// console.log('缓冲',this.playTime,this.duration)
+			},
+			// 缓冲
+			getInternetTraffic() {
+				const playVideoTime = Math.ceil(this.playTime / this.duration * 100) // 播放百分比
+				// console.log('播放百分比',playVideoTime)
+				if (this.bufferRate == 0 || this.bufferRate < playVideoTime) {
+					this.bufferRate = playVideoTime
+					console.log(this.bufferRate)
+				}
+				if (this.bufferRate == 0 || Number(this.bufferRate.toFixed(2)) == 0) return
+				const param = {
+					uuId: dayjs().format('YYYYMMDD') + this.uuId,
+					duration: this.playTime,
+					bufferRate: Number(this.bufferRate.toFixed(2)),
+					userId: this.userId,
+					periodId: this.periodId,
+					...this.urlOption
+				}
+				getInternetTraffic(param)
+			},
+			getErrMsg(err) {
+				let msgerr = {
+					videoUrl: this.videoUrl,
+					lineIndex: this.lineIndex,
+					errTime: new Date(),
+					// ip: this.ip,
+					errMsg: err
+				}
+				getErrMsg({
+					msg: JSON.stringify(msgerr)
+				})
+			},
+			getLink() {
+				if (!this.$isLogin()) {
+					this.$showLoginPage()
+					return
+				}
+				this.isLogin = true
+				this.userInfo = this.$getUserInfo()
+				if (this.isLogin && this.isAddKf == 1) {
+					this.getH5CourseVideoDetails()
+				}
+				if (this.videoId && this.isAddKf != 1) {
+					this.getIsAddKf()
+				}
+			},
+			/**
+			 * 节流原理:在一定时间内,只能触发一次
+			 *
+			 * @param {Function} func 要执行的回调函数
+			 * @param {Number} wait 延时的时间
+			 * @param {Boolean} immediate 是否立即执行
+			 * @return null
+			 */
+			throttle(func, wait = 500, immediate = true) {
+				if (immediate) {
+					if (!this.flag) {
+						this.flag = true
+						// 如果是立即执行,则在wait毫秒内开始时执行
+						typeof func === 'function' && func()
+						this.timer = setTimeout(() => {
+							this.flag = false
+						}, wait)
+					}
+				} else if (!this.flag) {
+					this.flag = true
+					// 如果是非立即执行,则在wait毫秒内的结束处执行
+					this.timer = setTimeout(() => {
+						this.flag = false
+						typeof func === 'function' && func()
+					}, wait)
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.full-width-popup {
+		width: 100%;
+	}
+</style>
+<style lang="scss" scoped>
+	.contact-btn {
+		display: inline-block;
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		opacity: 0;
+	}
+	.notice-box{
+		padding: 12rpx 18rpx;
+		background: #FFF8F8;
+		display: flex;
+		align-items: center;
+		image{
+			width:40rpx;
+			height:40rpx;
+			margin-right: 10rpx;
+			flex-shrink: 0;
+		}
+		.notice-marquee-wrap{
+			flex: 1;
+			min-width: 0;
+			overflow: hidden;
+			display: flex;
+			align-items: center;
+		}
+		.notice-marquee-track{
+			display: inline-flex;
+			white-space: nowrap;
+			animation: notice-marquee-scroll 20s linear infinite;
+		}
+		.notice-text{
+			flex-shrink: 0;
+			padding-right: 60rpx;
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 600;
+			font-size: 32rpx;
+			line-height: 44rpx;
+			color: #FF0C4D;
+			display: flex;
+		}
+	}
+	@keyframes notice-marquee-scroll{
+		0%{ transform: translateX(0); }
+		100%{ transform: translateX(-50%); }
+	}
+	.vip-order-cover-wrap {
+		position: absolute;
+		left: 10px;
+		bottom:40px;
+		height: 26px;
+		z-index: 999;
+		/* 容器按内容宽度自适应 */
+		display: inline-block;
+		overflow: visible;
+		pointer-events: none;
+		width: 200px;
+	}
+	.vip-order-cover-wrap--triple {
+		height: 110px;
+		//width: 240px;
+	}
+	.vip-order-cover-triple-panel {
+		display: flex;
+		align-items: flex-start;
+		flex-direction: column;
+		position: absolute;
+		left: 0;
+		right: auto;
+		top: 0;
+	}
+	.vip-order-cover-triple-current {
+		z-index: 1;
+	}
+	.vip-order-cover-triple-incoming {
+		z-index: 2;
+	}
+	.vip-order-cover-item {
+		position: absolute;
+		left: 0;
+		/* 不再撑满整块固定宽度,让背景宽度随内容变化 */
+		right: auto;
+		top: 0;
+		display: inline-flex;
+		align-items: center;
+		background: rgba(0,0,0,0.35);
+		border-radius: 26rpx;
+		text-align: center;
+		//border: 1px solid rgba(255, 12, 77, 0.2);
+		font-family: PingFangSC, PingFang SC;
+		font-size: 16px;
+		height: 26px;
+		line-height: 26px;
+		color: #fff;
+		font-weight: 400;
+		box-sizing: border-box;
+	}
+	.vip-order-cover-triple-item {
+		position: relative;
+		top: auto;
+		margin-bottom: 8px;
+	}
+	.vip-order-cover-triple-item:last-child {
+		margin-bottom: 0;
+	}
+	.vip-order-triple-enter {
+		animation: vip-order-triple-enter-up 0.46s ease-out forwards;
+	}
+	.vip-order-triple-leave {
+		animation: vip-order-triple-leave-up 0.46s ease-in forwards;
+	}
+	@keyframes vip-order-triple-enter-up {
+		0% {
+			opacity: 0;
+			transform: translateY(38px);
+		}
+		100% {
+			opacity: 1;
+			transform: translateY(0);
+		}
+	}
+	@keyframes vip-order-triple-leave-up {
+		0% {
+			opacity: 1;
+			transform: translateY(0);
+		}
+		78% {
+			opacity: 1;
+			transform: translateY(-34px);
+		}
+		100% {
+			opacity: 0;
+			transform: translateY(-38px);
+		}
+	}
+	.vip-order-cover-content {
+		display: flex;
+		align-items: center;
+		flex-wrap: nowrap;
+		white-space: nowrap;
+		overflow: visible;
+		justify-content: flex-start;
+		height: 26px;
+		line-height: 26px;
+		padding:0 8px;
+	}
+	.vip-order-seg {
+		display: inline-block;
+	}
+	.vip-order-seg-user {
+		color: #fff;
+		//font-weight: 600;
+	}
+	.vip-order-seg-time {
+		// font-size: 14px;
+		margin-left: 6px;
+	}
+	.vip-order-seg-suffix {
+		color: #fff;
+		// margin-left: 2px;
+	}
+	.vip-order-cover-self {
+		// width: 180px !important;
+		background: rgba(230,0,26,0.5);
+		// border: 1px solid #FFB020;
+		color: #fff;
+	}
+	.vip-order-cover-self .vip-order-seg-user {
+		color: #fff;
+		
+	}
+	.vip-order-cover-self .vip-order-seg-time {
+		color: #fff;
+		margin-left: 6px;
+	}
+	.vip-order-cover-self .vip-order-seg-suffix {
+		color: #fff;
+	}
+	.vip-order-enter {
+		animation: vip-order-enter-up 0.46s ease-out forwards;
+	}
+	.vip-order-leave {
+		animation: vip-order-leave-up 0.46s ease-in forwards;
+	}
+	@keyframes vip-order-enter-up {
+		0% {
+			opacity: 0;
+			transform: translateY(24px);
+		}
+		100% {
+			opacity: 1;
+			transform: translateY(0);
+		}
+	}
+	@keyframes vip-order-leave-up {
+		0% {
+			opacity: 1;
+			transform: translateY(0);
+		}
+		100% {
+			opacity: 0;
+			transform: translateY(-24px);
+		}
+	}
+	.rating-box{
+		position: relative;
+		padding:24rpx 0rpx 24rpx;
+		z-index:0;
+		height: calc(100vh - 488rpx);
+		.bg {
+			width: 100%;
+			// height: 500rpx;
+			position: absolute;
+			top: 0;
+			left: 0;
+			z-index: -1;
+		}
+		.tab-Box {
+			display: flex;
+			align-items: flex-end;
+			justify-content: space-around;
+			padding: 0 8rpx;
+			margin-bottom: -2rpx;
+			position: relative;
+			z-index: 3;
+		}
+		.tab-Box--single {
+			align-items: center;
+			justify-content: flex-start;
+			padding: 0 24rpx 0 16rpx;
+			margin-bottom: 30rpx;
+		}
+		.tab-item--single {
+			flex: 0 1 auto;
+			justify-content: flex-start;
+			// width: 100%;
+			padding: 0;
+		}
+		.tab-item__surface--single {
+			flex-direction: row;
+			align-items: center;
+			flex-direction: row !important;
+			justify-content: flex-start;
+			width: auto;
+			max-width: 100%;
+			border-radius: 0;
+			image {
+				margin-top: 0!important;
+				margin-right: 16rpx;
+				flex-shrink: 0;
+			}
+		}
+		.tab-item__text--single {
+			padding-top: 0!important;
+			padding-bottom: 0!important;
+			text-align: left;
+			font-weight: 600 !important;
+			font-size: 40rpx !important;
+			line-height: 56rpx !important;
+		}
+		.tab-item {
+			// flex: 1;
+			display: flex;
+			justify-content: center;
+			min-width: 0;
+			padding: 0 6rpx;
+		}
+		.tab-item__surface {
+			width: 100%;
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			justify-content: flex-end;
+			box-sizing: border-box;
+			border-radius: 28rpx 28rpx 0 0;
+			transition: background-color 0.28s ease, box-shadow 0.28s ease, transform 0.22s ease;
+			image{
+				margin-top: 12rpx;
+				width: 40rpx;
+				height: 40rpx;
+			}
+		}
+		.tab-item--active .tab-item__surface {
+			background:url('https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/video/active-bg.png') no-repeat center;
+			background-size: 100% 100%;
+			padding: 0 70rpx;
+			transform: translateY(-2rpx);
+		}
+		.tab-item__text {
+			padding-top: 10rpx;
+			padding-bottom: 12rpx;
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 400;
+			font-size: 36rpx;
+			line-height: 50rpx;
+			color: #ff233c;
+			text-align: center;
+		}
+		.tab-item--active .tab-item__text{
+			font-weight: 600;
+			font-size: 40rpx;
+		}
+		
+		.rating-ques-block + .rating-ques-block {
+			margin-top: 40rpx;
+		}
+		.rating-body--plain {
+			// padding-top: 36rpx;
+			// padding-bottom: 40rpx;
+			image {
+				width: 100%;
+			}
+		}
+		.rating-intro-cover-img {
+			width: 100%;
+			height: auto;
+			display: block;
+		}
+		.rating-intro-text {
+			margin-top: 24rpx;
+			font-size: 28rpx;
+			line-height: 44rpx;
+			color: rgba(0, 0, 0, 0.65);
+			white-space: pre-wrap;
+			word-break: break-word;
+		}
+		.rating-msg-empty {
+			padding: 80rpx 24rpx;
+			text-align: center;
+			font-size: 28rpx;
+			color: rgba(0, 0, 0, 0.35);
+		}
+		.rating-body.rating-body--featured {
+			display: flex;
+			flex-direction: column;
+			overflow: hidden;
+			padding: 30rpx 24rpx 20rpx;
+		}
+		.rating-msg-scroll {
+			height:100%;
+			width: 100%;
+			box-sizing: border-box;
+		}
+		.rating-msg-scroll-anchor {
+			width: 100%;
+			height: 1px;
+		}
+		.rating-msg-load-more {
+			padding: 24rpx 0 32rpx;
+			text-align: center;
+			font-size: 26rpx;
+			color: rgba(0, 0, 0, 0.4);
+		}
+		.rating-msg-load-more--done {
+			color: rgba(0, 0, 0, 0.28);
+		}
+		.rating-msg-item {
+			display: flex;
+			flex-direction: row;
+			align-items: flex-start;
+			gap: 20rpx;
+			padding-bottom: 40rpx;
+			&:not(:first-child) {
+				padding-top: 8rpx;
+			}
+		}
+		.rating-msg-avatar-wrap {
+			flex-shrink: 0;
+			width: 64rpx;
+		}
+		.rating-msg-main {
+			flex: 1;
+			min-width: 0;
+			display: flex;
+			flex-direction: column;
+			align-items: stretch;
+		}
+		.rating-msg-avatar {
+			width: 64rpx;
+			height: 64rpx;
+			border-radius: 50%;
+			flex-shrink: 0;
+			background: #ffe4ec;
+			display: block;
+		}
+		.rating-msg-avatar--ph {
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			background: linear-gradient(145deg, #ffd6e8 0%, #ffc8df 100%);
+		}
+		.rating-msg-name {
+			font-size: 32rpx;
+			color: rgba(0,0,0,0.65);
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 400;
+			line-height: 44rpx;
+		}
+		.rating-msg-text {
+			margin-top: 12rpx;
+			font-size: 28rpx;
+			line-height: 44rpx;
+			color: rgba(0, 0, 0, 0.85);
+			word-break: break-word;
+		}
+		.rating-msg-media {
+			margin-top: 12rpx;
+			//border-radius: 16rpx;
+			overflow: hidden;
+		}
+		.rating-msg-media--video {
+			overflow: visible;
+		}
+		.rating-msg-video-wrap {
+			position: relative;
+			max-width: 320rpx;
+			// background: #000;
+		}
+		.rating-msg-video {
+			width: 100%;
+			display: block;
+			max-height: 240rpx;
+			// background: #000;
+		}
+		/* 小程序列表内用封面图代替 video,固定比例避免布局抖动 */
+		.rating-msg-video--poster {
+			width: 320rpx;
+			max-width: 100%;
+			height: 180rpx;
+			vertical-align: top;
+		}
+		/* 仅有视频地址无封面时:不能用视频 URL 当 image.src */
+		.rating-msg-video--no-poster {
+			box-sizing: border-box;
+			width: 320rpx;
+			max-width: 100%;
+			height: 180rpx;
+			background: linear-gradient(160deg, #2a2a2e 0%, #121214 100%);
+		}
+		.rating-msg-video-play-cover {
+			position: absolute;
+			left: 0;
+			top: 0;
+			right: 0;
+			bottom: 0;
+			z-index: 2;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			background: rgba(0, 0, 0, 0.18);
+		}
+		.rating-msg-video-play-icon {
+			width: 88rpx;
+			height: 88rpx;
+			flex-shrink: 0;
+		}
+		.rating-msg-media--imgs {
+			 display: flex;
+			  flex-wrap: wrap;
+			  justify-content: flex-start;
+			  gap: 12rpx; /* 图片之间间距,跟朋友圈一致 */
+			
+		}
+		.rating-msg-media--cols-1 {
+			grid-template-columns: 1fr;
+		}
+		.rating-msg-media--cols-2 {
+			grid-template-columns: repeat(2, 1fr);
+		}
+		.rating-msg-media--cols-3 {
+			grid-template-columns: repeat(3, 1fr);
+		}
+		.rating-msg-img {
+			 flex-shrink: 0;
+			  /* 关键:不设固定宽高,只限制最大宽度,和朋友圈一致 */
+			  max-width: 320rpx;
+			  height: auto;
+		}
+		.rating-msg-media--cols-1 .rating-msg-img {
+		}
+		.rating-msg-toolbar {
+			flex-shrink: 0;
+			padding-top: 20rpx;
+			margin-top: 8rpx;
+			border-top: 1rpx solid rgba(0, 0, 0, 0.06);
+		}
+		.rating-msg-toolbar-row {
+			display: flex;
+			align-items: flex-end;
+			justify-content: space-between;
+			gap: 16rpx;
+		}
+		.rating-msg-side-actions {
+			display: flex;
+			align-items: flex-end;
+			flex-shrink: 0;
+			gap: 20rpx;
+		}
+		.rating-msg-dash-btn {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			width: 100rpx;
+		}
+		.rating-msg-dash-inner {
+			width: 80rpx;
+			height: 80rpx;
+			border: 2rpx dashed #c8c8c8;
+			border-radius: 16rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			box-sizing: border-box;
+			background: #fafafa;
+		}
+		.rating-msg-dash-img {
+			width: 44rpx;
+			height: 44rpx;
+		}
+		.rating-msg-dash-label {
+			margin-top: 8rpx;
+			font-size: 24rpx;
+			color: #222222;
+			font-weight: 600;
+			line-height: 34rpx;
+		}
+		.rating-msg-cart-slot {
+			position: relative;
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+		}
+		.rating-msg-badge {
+			position: absolute;
+			right: -28rpx;
+			top: -72rpx;
+			width: 180rpx;
+			height: 76rpx;
+			z-index: 2;
+			pointer-events: none;
+		}
+		.rating-body{
+			//margin-top: 40rpx;
+			position: relative;
+			z-index: 1;
+			padding:30rpx;
+			box-sizing: border-box;
+			background: #FFFFFF;
+			border-radius: 30rpx 30rpx;
+			height: calc(100% - 300rpx);
+			overflow-y: auto;
+			-webkit-overflow-scrolling: touch;
+			margin-top: 0;
+			.title{
+				font-family: PingFangSC, PingFang SC;
+				font-weight: 600;
+				font-size: 40rpx;
+				color: rgba(0,0,0,0.85);
+				line-height: 56rpx;
+			}
+		}
+		.sat-box{
+			display: grid;
+			grid-template-columns: repeat(2, 1fr);
+			gap: 28rpx 24rpx;
+			margin-top: 32rpx;
+		}
+		.sat{
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			justify-content: center;
+			text-align: center;
+			background: #F5F7FA;
+			padding: 20rpx;
+			border-radius: 20rpx;
+			transition: background 0.3s ease, box-shadow 0.3s ease;
+			.sat-img-wrap{
+				width: 100rpx;
+				height: 100rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				will-change: transform;
+				image{
+					width: 100rpx;
+					height: 100rpx;
+					transition: transform 0.35s cubic-bezier(0.34, 1.3, 0.64, 1);
+				}
+			}
+			.sat-img-bounce{
+				animation: sat-rate-pop 0.48s cubic-bezier(0.34, 1.45, 0.64, 1);
+			}
+			text{
+				margin-top: 10rpx;
+				font-family: PingFangSC, PingFang SC;
+			    font-weight: 400;
+			    font-size: 36rpx;
+				line-height: 50rpx;
+				transition: color 0.32s ease, font-weight 0.28s ease, transform 0.28s ease;
+				color: rgba(0,0,0,0.42);
+			}
+			.active{
+				font-weight: 600;
+				color: #FF233C;
+			}
+		}
+		.sat.sat--active{
+			background: #FFEEF0;
+			//box-shadow: 0 4rpx 16rpx rgba(255, 92, 3, 0.12);
+			.sat-img-wrap image{
+				transform: scale(1.06);
+			}
+		}
+	}
+	@keyframes sat-rate-pop{
+		0%{ transform: scale(1); }
+		28%{ transform: scale(1.2); }
+		52%{ transform: scale(0.94); }
+		76%{ transform: scale(1.06); }
+		100%{ transform: scale(1); }
+	}
+	/* 精选留言:相册图片/视频(替代系统 ActionSheet,底部贴齐含安全区) */
+	.fc-media-actions-sheet {
+		display: flex;
+		flex-direction: column;
+		width: 100%;
+		box-sizing: border-box;
+		padding-bottom:68rpx;
+	}
+	.fc-media-actions-sheet-item {
+		padding: 30rpx 32rpx;
+		font-size: 32rpx;
+		color: #1e1e1e;
+		text-align: center;
+		border-bottom: 1rpx solid #f0f0f0;
+	}
+	.fc-media-actions-sheet-gap {
+		height: 16rpx;
+		background: #f3f5f9;
+		border-bottom: none;
+	}
+	.fc-media-actions-sheet-cancel {
+		border-bottom: none;
+		color: #666;
+	}
+	// 更多操作弹窗
+	.more-actions-popup {
+		border-radius: 20rpx 0 0 20rpx;
+		padding: 30rpx;
+		display: flex;
+		justify-content: space-between;
+	
+		.more-action-item {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+	
+			.action-icon {
+				width: 48rpx;
+				height: 48rpx;
+			}
+	
+			.action-label {
+				color: #1e1e1e;
+				text-align: center;
+				margin-top: 10rpx;
+			}
+		}
+	}
+	.progress-countdown {
+		position: absolute; 
+		right: 6px;
+		top: 6px;
+		z-index: 99999999;
+		// width: 112px;
+		height: 50px;
+		background: rgba(0,0,0,0.45);
+		display: flex;
+		align-items: center;
+		justify-content: space-around;
+		padding:2px 8px;
+		flex-direction: column;
+        border-radius: 6px;
+		 box-sizing: border-box; /* 避免padding撑大容器 */
+	}
+	.progress-title {
+		font-size: 16px;
+		color: #FF233C;
+		font-weight: 600;
+	}
+	.progress-img{
+		width: 63px;
+		height: 15px;
+	}
+	.progress-bar-bg {
+		width: 86px;
+		height: 6px;
+		//margin-top: 16rpx;
+		background: rgba(255,255,255,0.8);
+		border-radius: 3px;
+		overflow: hidden;
+		// margin-bottom: 16rpx;
+	}
+	.progress-bar-fill {
+		height: 100%;
+		background: #FF233C;
+		border-radius: 3px;
+		transition: width 1s linear;
+	}
+.progress-text {
+	white-space: nowrap; /* 强制不换行 */
+	color: #fff;
+	font-size: 13px;
+    display: flex;
+	align-items: flex-start; /* 垂直居中 */
+	justify-content: center; /* 水平居中 */
+		}
+	.progress-text-label {
+		font-size: 12px;
+		margin-right: 2px;
+	}
+	.ques-flex {
+		display: flex;
+		align-items: center;
+		flex-direction: row;
+		justify-content: space-around;
+	}
+
+	@mixin u-flex($flexD, $alignI, $justifyC) {
+		display: flex;
+		flex-direction: $flexD;
+		align-items: $alignI;
+		justify-content: $justifyC;
+	}
+
+	.footer-tips {
+		position: fixed;
+		width: 100%;
+		bottom: 144rpx;
+		text-align: center;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
+		font-size: 12px;
+		color: #bbb;
+		transform: scale(0.8);
+	}
+
+	.btns {
+		//position: relative;
+		width: 100%;
+		height: 96rpx;
+		display: flex;
+		    align-items: center;
+		    justify-content: space-between;
+			.rating-msg-input-shell {
+				flex: 1;
+				min-width: 0;
+				display: flex;
+				align-items: center;
+				background: #f5f5f5;
+				border-radius: 48rpx;
+				padding: 24rpx 30rpx;
+				box-sizing: border-box;
+			}
+			.rating-msg-media-pill {
+				position: relative;
+				flex-shrink: 0;
+				width: 64rpx;
+				height: 64rpx;
+				margin-right: 16rpx;
+				border-radius: 12rpx;
+				overflow: hidden;
+			}
+			.rating-msg-media-thumb {
+				width: 100%;
+				height: 100%;
+				display: block;
+			}
+			.rating-msg-media-badge {
+				position: absolute;
+				left: 0;
+				right: 0;
+				bottom: 0;
+				font-size: 18rpx;
+				color: #fff;
+				text-align: center;
+				line-height: 1.4;
+				background: rgba(0, 0, 0, 0.45);
+			}
+			.rating-msg-media-x {
+				position: absolute;
+				top: -4rpx;
+				right: -4rpx;
+				width: 32rpx;
+				height: 32rpx;
+				line-height: 32rpx;
+				text-align: center;
+				font-size: 28rpx;
+				color: #fff;
+				background: rgba(0, 0, 0, 0.5);
+				border-radius: 50%;
+			}
+			.rating-msg-send {
+				flex-shrink: 0;
+				padding: 0 12rpx 0 8rpx;
+				font-size: 28rpx;
+				color: #FF233C;
+			}
+			.rating-msg-input {
+				flex: 1;
+				min-width: 0;
+				font-size: 32rpx;
+				color: rgba(0, 0, 0, 0.85);
+				height: 48rpx;
+				line-height: 48rpx;
+			}
+			.rating-msg-input-trigger {
+				overflow: hidden;
+			}
+			.rating-msg-input-trigger-text {
+				display: block;
+				font-size: 32rpx;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				white-space: nowrap;
+				color: rgba(0, 0, 0, 0.85);
+				&.is-ph {
+					color: rgba(0, 0, 0, 0.28);
+				}
+			}
+			.rating-msg-ph {
+				color: rgba(0, 0, 0, 0.28);
+				font-size: 32rpx;
+			}
+			.rating-msg-input-icon {
+			    // width:40rpx;
+			    // height:40rpx;
+				flex-shrink: 0;
+				padding-left:24rpx;
+				display:flex;
+				image{
+					width:40rpx;
+					height:40rpx
+				}
+			}
+		.author-btn {
+			// z-index: 100;
+			// position: absolute;
+			// width: 100%;
+			flex:1;
+			height: 96rpx;
+			background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+			border-radius: 48rpx;
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 600;
+			font-style: normal;
+			font-size: 40rpx;
+			color: #FFFFFF;
+			text-align: center;
+			line-height: 96rpx;
+			display: flex;
+			    align-items: center;
+			    justify-content: center;
+				image{
+					margin-left: 4rpx;
+					width: 40rpx;
+					height: 40rpx;
+				}
+		}
+		.author-cart{
+			padding-left: 40rpx;
+			display: flex;
+			    align-items: center;
+				.more-box{
+					display: flex;
+					align-items: center;
+					flex-direction: column;
+					.tips{
+						font-family: PingFangSC, PingFang SC;
+						font-weight: 600;
+						font-size: 32rpx;
+						color: #222222;
+						line-height: 44rpx;
+						text-align: center;
+						margin-top: 12rpx;
+					}
+					image{
+						width: 80rpx;
+						height: 80rpx;
+					}
+					&:last-child{
+						margin-left: 40rpx;
+					}
+				}
+			.xianshi{
+				position: absolute;
+				z-index: 10;
+				right:20rpx;
+				bottom: 180rpx;
+				width: 214rpx;
+				height:90rpx;
+			}
+		}
+	}
+
+	.textOne {
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+	}
+
+	.textTwo {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+	}
+
+	.header-nav {
+		height: 88rpx;
+		@include u-flex(row, center, flex-start);
+		overflow: hidden;
+		background-color: #fff;
+		box-sizing: border-box;
+
+		.header-title {
+			text-align: center;
+			overflow: hidden;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+			padding: 0 10rpx 0 100rpx;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 500;
+			font-size: 15px;
+			color: #000;
+			box-sizing: border-box;
+		}
+	}
+
+	.reward-list {
+		width: 100%;
+		margin-top: 20rpx;
+		margin-bottom: -40rpx;
+
+		&-group {
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 400;
+			font-size: 14px;
+			color: #222222;
+			@include u-flex(row, center, center);
+		}
+
+		&-option {
+			@include u-flex(row, center, flex-start);
+
+			&:first-child {
+				margin-right: 40rpx;
+			}
+		}
+	}
+
+	.err {
+		color: #f56c6c !important;
+	}
+
+	.kfqrcode-box {
+		background-color: #fff;
+		border-radius: 16rpx;
+		max-width: 560rpx;
+		padding: 60rpx 40rpx;
+		margin-top: -100rpx;
+		box-sizing: border-box;
+		@include u-flex(column, center, flex-start);
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 400;
+		font-size: 34rpx;
+		color: #222;
+		position: relative;
+		text-align: center;
+
+		.kfqrcode {
+			// height: 460rpx;
+			width: 460rpx;
+		}
+	}
+
+	.kfqrcode-close {
+		width: 64rpx;
+		height: 64rpx;
+		position: absolute;
+		bottom: -100rpx;
+		left: 50%;
+		transform: translateX(-50%);
+	}
+
+	.tipsPopup-mask {
+		position: relative;
+		width: 560rpx;
+		background-color: transparent;
+
+		.red_envelope_top {
+			width: 480rpx;
+			height: 360rpx;
+			margin: 0 auto;
+			display: inherit;
+		}
+	}
+
+	.tipsPopup-btn-box {
+		width: 456rpx;
+		height: 104rpx;
+		padding: 4rpx;
+		box-sizing: border-box;
+		background: linear-gradient(180deg, rgba(252, 209, 94, 1), rgba(254, 253, 251, 1));
+		border-radius: 52rpx;
+	}
+
+	.tipsPopup-btn {
+		width: 100%;
+		height: 100%;
+		background: linear-gradient(180deg, #FF9F22 0%, #FA1E05 100%);
+		border-radius: 52rpx 52rpx 52rpx 52rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
+		font-size: 36rpx;
+		color: #FFFFFF;
+		line-height: 96rpx;
+		text-align: center;
+	}
+
+	.tipsPopup {
+		width: 560rpx;
+		padding: 12rpx;
+		margin-top: -72rpx;
+		box-sizing: border-box;
+		background: linear-gradient(180deg, #FFFBEF 0%, #FFFFF5 43%, #F5EAC2 100%);
+		border-radius: 32rpx 32rpx 32rpx 32rpx;
+		position: relative;
+
+		&-close {
+			width: 64rpx;
+			height: 64rpx;
+			position: absolute;
+			right: 0;
+			top: -188rpx;
+		}
+
+		&-line {
+			padding: 3rpx;
+			box-sizing: border-box;
+			background: linear-gradient(180deg, rgba(247, 245, 220, 1), rgba(250, 220, 157, 1));
+			border-radius: 24rpx;
+		}
+
+		&-box {
+			padding: 0 40rpx 40rpx 40rpx;
+			box-sizing: border-box;
+			background: linear-gradient(180deg, #FFFBEF 0%, #FFFFF5 43%, #F5EAC2 100%);
+			border-radius: 24rpx;
+			@include u-flex(column, center, flex-start);
+		}
+
+		&-head {
+			@include u-flex(row, center, center);
+
+			&-title {
+				width: 364rpx;
+				height: auto;
+				margin-top: -22rpx;
+			}
+		}
+
+		&-content {
+			margin: 48rpx 0;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 500;
+			font-size: 32rpx;
+			color: #222222;
+			text-align: center;
+
+			&-title {
+				margin-bottom: 26rpx;
+				font-weight: 600;
+				font-size: 40rpx;
+				color: #FF5C03;
+			}
+		}
+	}
+    
+	// 商品卡片样式
+	.goods-card {
+		position: absolute;
+		right: 24rpx;
+		bottom: 280rpx;
+		z-index: 9999;
+		width: 300rpx;
+		background: #FFFFFF;
+		border-radius: 20rpx;
+		overflow: visible;
+
+		&-hot {
+			position: absolute;
+			top: -66rpx;
+			left: 30rpx;
+			z-index: 11;
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+		}
+
+		&-hot-flame {
+			font-size: 24rpx;
+			line-height: 1;
+			margin-right: 4rpx;
+		}
+
+		&-hot-label {
+			font-size: 24rpx;
+			font-weight: 600;
+			color: #FFFFFF;
+			line-height: 44rpx;
+		}
+
+		&-hot-count {
+			position: absolute;
+			left:130rpx;
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 600;
+			font-size: 40rpx;
+			color: #FFFFFF;
+			line-height: 56rpx;
+			text-align: justify;
+		}
+
+		&-inner {
+			display: flex;
+			flex-direction:column;
+			border-radius: 20rpx;
+			overflow: hidden;
+		}
+
+		&-img {
+			width:300rpx;
+			height:300rpx;
+			flex-shrink: 0;
+		}
+
+		&-info {
+			flex: 1;
+			padding: 12rpx;
+			display: flex;
+			flex-direction: column;
+			justify-content: space-between;
+		}
+
+		&-title {
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 600;
+			font-size: 32rpx;
+			color: rgba(0,0,0,0.85);
+			line-height: 44rpx;
+			overflow: hidden;
+			text-overflow: ellipsis;
+			display: -webkit-box;
+			-webkit-line-clamp: 2;
+			-webkit-box-orient: vertical;
+		}
+		&-bottom {
+			margin-top: 12rpx;
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			//justify-content: space-between;
+		}
+
+		&-tag {
+			position: relative;
+			width: 120rpx;
+			height: 44rpx;
+		}
+
+		&-tag-bg {
+			width: 100%;
+			height: 100%;
+		}
+
+		&-tag-text {
+			position: absolute;
+			left: 0;
+			top: 0;
+			width: 100%;
+			height: 100%;
+			text-align: center;
+			line-height: 44rpx;
+			font-size: 24rpx;
+			color: #FFFFFF;
+			font-weight: 500;
+		}
+		
+		&-price{
+			margin-left: 14rpx;
+			display: flex;
+			align-items:baseline;
+			.unit{
+				font-family: PingFangSC, PingFang SC;
+				font-weight: 600;
+				font-size: 32rpx;
+				color: #FF233C;
+			}
+			.price{
+				font-family: PingFangSC, PingFang SC;
+				font-weight: 600;
+				font-size: 48rpx;
+				color: #FF233C;
+			}
+		}
+		.close-box{
+			position: absolute;
+			top:20rpx;
+			right:20rpx;
+			image{
+				width: 30rpx;
+				height: 30rpx;
+			}
+		}
+	}
+   /* 商品卡片样式 */
+   .goods-cover {
+     /* cover-view 在 video 内使用 absolute 比 fixed 更稳定 */
+     position:fixed;
+     right: 12px;
+	 width: 150px;
+     z-index: 99999;
+    
+     border-radius: 10px;
+     overflow: visible;
+     bottom: 40px;
+
+    &-hot {
+    		// margin-left: 15px;
+    margin-bottom: 15px;
+     display: flex;
+     flex-direction: row;
+     align-items: center;
+    position: relative;
+    }
+    
+    &-hot-text {
+      position: absolute;
+      left:85px;
+      font-family: PingFangSC, PingFang SC;
+      font-weight: 600;
+      font-size: 20px;
+      color: #FFFFFF;
+      line-height: 28px;
+      text-align: justify;
+    }
+    
+    &-inner {
+      display: flex;
+      flex-direction:column;
+      border-radius: 10px;
+      overflow: hidden;
+      background: #FFFFFF;
+      position: relative;
+    }
+     &-img {
+       width:150px;
+       height:150px;
+       flex-shrink: 0;
+     }
+   
+     &-info {
+       flex: 1;
+       padding: 6px;
+       display: flex;
+       flex-direction: column;
+       justify-content: space-between;
+     }
+   
+     &-title {
+       font-family: PingFangSC, PingFang SC;
+       font-weight: 600;
+       font-size: 16px;
+       color: #000000D9;
+       line-height: 22px;
+       overflow: hidden;
+        width: 150px; /* 必须给宽度 */
+        white-space: nowrap; /* 关键 */
+        text-overflow: ellipsis;
+     }
+     &-bottom {
+       margin-top: 6px;
+       display: flex;
+       flex-direction: row;
+       align-items: center;
+     }
+   
+     &-tag {
+       position: relative;
+       width: 60px;
+       height: 22px;
+     }
+   
+     &-tag-bg {
+       width: 100%;
+       height: 100%;
+     }
+   
+     &-tag-text {
+       position: absolute;
+       left: 0;
+       top: 0;
+       width: 100%;
+       height: 100%;
+       text-align: center;
+       line-height: 22px;
+       font-size: 12px;
+       color: #FFFFFF;
+       font-weight: 500;
+     }
+     
+     &-price{
+       margin-left: 7px;
+       display: flex;
+       align-items:baseline;
+       .unit{
+         font-family: PingFangSC, PingFang SC;
+         font-weight: 600;
+         font-size: 16px;
+         color: #FF233C;
+       }
+       .price{
+         font-family: PingFangSC, PingFang SC;
+         font-weight: 600;
+         font-size: 24px;
+         color: #FF233C;
+       }
+     }
+     .close-box{
+       position: absolute;
+       top:10px;
+       right:10px;
+	   z-index:9;
+       cover-image{
+         width: 15px;
+         height: 15px;
+       }
+     }
+   }
+	.video-controls-box {
+		width: 100%;
+		height: 300rpx;
+		overflow: hidden;
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		z-index: 2;
+		background: rgba(0, 0, 0, 0.2);
+
+		.video-play {
+			height: 72rpx;
+			width: 72rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			transform: translate(-50%, -50%);
+		}
+	}
+
+	.video-controls {
+		width: 100%;
+		height: 80rpx;
+		padding: 0 28rpx;
+		box-sizing: border-box;
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		background: linear-gradient(to top, #222 0%, transparent 80%);
+
+		.video-icon {
+			height: 44rpx;
+			width: 44rpx;
+		}
+	}
+
+	.errQuesbox {
+		width: 100%;
+		max-height: 260rpx;
+		overflow-y: auto;
+		margin-top: 24rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
+		font-size: 30rpx;
+		color: #222222;
+
+		&-item {
+			width: 100%;
+			height: 128rpx;
+			line-height: 128rpx;
+			margin-bottom: 24rpx;
+			padding: 0 30rpx;
+			box-sizing: border-box;
+			overflow: hidden;
+			background: #fff;
+			border-radius: 16rpx 16rpx 16rpx 16rpx;
+			position: relative;
+
+			&::after {
+				content: "题目";
+				min-width: 64rpx;
+				height: 36rpx;
+				padding: 0 12rpx;
+				line-height: 36rpx;
+				background: #FF5C03;
+				box-sizing: border-box;
+				border-radius: 0rpx 0rpx 16rpx 0rpx;
+				text-align: center;
+				font-family: PingFang SC, PingFang SC;
+				font-weight: 500;
+				font-size: 20rpx;
+				color: #fff;
+				position: absolute;
+				left: 0;
+				top: 0;
+			}
+		}
+	}
+
+	.bg {
+		background: #fff !important;
+	}
+
+	.timepopbox {
+		width: 560rpx;
+		padding: 32rpx;
+		box-sizing: border-box;
+	}
+
+	.answerPopup {
+		&-box {
+			width: 560rpx;
+			background: linear-gradient(180deg, #FFFAF6 0%, #FEECD8 100%);
+			border-radius: 32rpx 32rpx 32rpx 32rpx;
+			background-color: #fff;
+			font-weight: 400;
+			padding: 32rpx;
+			box-sizing: border-box;
+			position: relative;
+			@include u-flex(column, center, flex-start);
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 400;
+
+			.tipimg {
+				width: 206rpx;
+				height: 206rpx;
+				margin-bottom: 16rpx;
+			}
+		}
+
+		&-title {
+			font-weight: 600;
+			font-size: 36rpx;
+			color: #222222;
+		}
+
+		&-desc {
+			margin-top: 10rpx;
+			font-size: 28rpx;
+			color: #757575;
+		}
+
+		&-btn {
+			width: 464rpx;
+			height: 84rpx;
+			margin-top: 54rpx;
+			margin-bottom: 16rpx;
+			background: #FF5C03;
+			border-radius: 42rpx;
+			font-weight: 500;
+			font-size: 32rpx;
+			color: #FFFFFF;
+			text-align: center;
+			line-height: 84rpx;
+		}
+	}
+
+	.popupbox {
+		width: 100%;
+		background-color: #fff;
+		border-radius: 16rpx 16rpx 0 0;
+		padding: 24rpx 32rpx;
+		position: relative;
+
+		&-head {
+			height: 60rpx;
+			margin-bottom: 30rpx;
+			text-align: center;
+			overflow-y: auto;
+			color: #414858;
+			font-size: 32rpx;
+			font-weight: bold;
+			position: relative;
+
+			.close-icon {
+				position: absolute;
+				right: 0;
+				top: 0;
+				height: 40rpx;
+				width: 40rpx;
+			}
+		}
+
+		&-content {
+			height: 20vh;
+			overflow-y: auto;
+			display: flex;
+			align-items: flex-start;
+			flex-wrap: wrap;
+			gap: 32rpx;
+
+			.line-item {
+				display: inline-block;
+				min-width: 200rpx;
+				min-height: 60rpx;
+				padding: 0 20rpx;
+				box-sizing: border-box;
+				border-radius: 50rpx;
+				overflow: hidden;
+				background-color: #f7f7f7;
+				text-align: center;
+				color: #414858;
+				font-size: 28rpx;
+				line-height: 60rpx;
+			}
+
+			.line-active {
+				color: #f56c6c !important;
+				background-color: #fef0f0 !important;
+			}
+		}
+	}
+
+	.content {
+		//padding-bottom: calc(var(--window-bottom) + 100rpx);
+
+		.video-box {
+			width: 100%;
+			height: 420rpx;
+			overflow: hidden;
+			position: relative;
+
+			#myVideo {
+				width: 100%;
+				height: 100%;
+			}
+		}
+
+		.video-poster {
+			width: 100%;
+			height: 420rpx;
+		}
+
+		.miantitlebox {
+			padding: 30rpx 0;
+			border-bottom: 2rpx solid #F5F7FA;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 500;
+			font-size: 40rpx;
+			color: #222222;
+		}
+
+		.subtitlebox {
+			padding: 30rpx 0;
+			border-bottom: 2rpx solid #F5F7FA;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 500;
+			font-size: 40rpx;
+			color: #222222;
+		}
+
+		.title-content {
+			padding: 0 32rpx;
+			background-color: #fff;
+			font-size: 28rpx;
+			line-height: 1.6;
+
+			.title {
+				font-size: 36rpx;
+				font-weight: 500;
+				color: #414858;
+			}
+
+			.time-or-subtitle {
+				margin-top: 12rpx;
+				color: #666666;
+			}
+		}
+
+		.descbox {
+			padding: 36rpx 32rpx;
+			margin-bottom: 20rpx;
+			background-color: #fff;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #222222;
+			line-height: 42rpx;
+			word-break: break-word;
+
+			&-title {
+				margin-bottom: 24rpx;
+				font-weight: 500;
+				font-size: 32rpx;
+			}
+
+			&-info {
+				margin-bottom: 24rpx;
+				@include u-flex(row, center, space-between);
+				font-size: 26rpx;
+				color: #757575;
+
+				&-l {
+					flex: 1;
+					@include u-flex(row, center, flex-start);
+				}
+
+				&-time {
+					margin-left: 18rpx;
+					padding-left: 18rpx;
+					position: relative;
+
+					&::after {
+						content: "";
+						width: 4rpx;
+						height: 4rpx;
+						background: #999999;
+						border-radius: 50%;
+						position: absolute;
+						left: 0;
+						top: 50%;
+						transform: translateY(-50%);
+					}
+				}
+
+				&-r {
+					background: transparent;
+				}
+			}
+
+			&-desc {
+				overflow: hidden;
+				position: relative;
+			}
+		}
+
+		.expand {
+			flex-shrink: 0;
+			@include u-flex(row, center, flex-end);
+			color: #FF5C03;
+			font-weight: 400;
+			font-size: 24rpx;
+
+			image {
+				width: 32rpx;
+				height: 32rpx;
+			}
+		}
+
+		.expand-ab {
+			position: absolute;
+			top: 0;
+			right: 0;
+			box-shadow: -50rpx 0 20rpx 8rpx #FFFFFF;
+			background-color: #fff;
+		}
+
+		.ques-content {
+			background-color: #fff;
+			padding: 40rpx 32rpx;
+			box-sizing: border-box;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #222222;
+		}
+
+		.ques-content-tit {
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 600;
+			font-size: 48rpx;
+			color: rgba(0,0,0,0.85);
+			line-height: 66rpx;
+		}
+
+		.ques-title {
+			margin: 48rpx 0 34rpx 0;
+			font-weight: 600;
+			font-size: 40rpx;
+			white-space: normal;
+		}
+
+		.ques-type {
+			flex-shrink: 0;
+			min-width: 72rpx;
+			min-height: 40rpx;
+			padding: 0 12rpx;
+			margin: 0 12rpx;
+			box-sizing: border-box;
+			background: #FF5C03;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			line-height: 40rpx;
+			text-align: center;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 400;
+			font-size: 24rpx;
+			color: #FFFFFF;
+			display: inline-block;
+		}
+
+		.ques-option {
+			min-height: 88rpx;
+			padding: 24rpx 32rpx;
+			box-sizing: border-box;
+			margin-bottom: 24rpx;
+			background: #F5F7FA;
+			border-radius: 16rpx 16rpx 16rpx 16rpx;
+			display: flex;
+			align-items: center;
+
+			&-active {
+				color: #FF5C03 !important;
+				background: #FCF0E7 !important;
+			}
+		}
+
+		.video-line {
+			min-width: 140rpx;
+			max-width: 200rpx;
+			height: 60rpx;
+			padding: 0 20rpx;
+			box-sizing: border-box;
+			border-radius: 50rpx 0 0 50rpx;
+			overflow: hidden;
+			background-color: #fff;
+			text-align: center;
+			color: #888;
+			font-size: 28rpx;
+			line-height: 60rpx;
+			display: inline-flex;
+			align-items: center;
+			justify-content: center;
+			position: fixed;
+			right: 0;
+			z-index: 9;
+			bottom: calc(var(--window-bottom) + 280rpx);
+			box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, .12);
+
+			image {
+				flex-shrink: 0;
+				height: 30rpx;
+				width: 30rpx;
+				margin-right: 6rpx;
+			}
+		}
+
+		/* 精选留言:图片/视频自定义预览(设计稿弹窗) */
+		.fc-media-preview-mask {
+			position: fixed;
+			left: 0;
+			right: 0;
+			top: 0;
+			bottom: 0;
+			z-index: 10050;
+			background: rgba(0, 0, 0, 0.72);
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			padding: 32rpx 24rpx calc(32rpx + env(safe-area-inset-bottom));
+			box-sizing: border-box;
+		}
+		.fc-media-preview-card {
+			width: 100%;
+			max-width: 630rpx;
+			overflow: hidden;
+			display: flex;
+			    flex-direction: column;
+			    align-items: center;
+		}
+		.fc-media-preview-img-box {
+			width: 100%;
+			height: 62vh;
+			max-height: 820rpx;
+		}
+		.fc-media-preview-slide {
+			width: 100%;
+			height: 100%;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			padding: 16rpx;
+			box-sizing: border-box;
+		}
+		.fc-media-preview-main-img {
+			width: 100%;
+			height: 100%;
+			max-height: 100%;
+		}
+		.fc-media-preview-video-box {
+			width: 100%;
+			height: 62vh;
+			max-height: 820rpx;
+			background: #000;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+		}
+		.fc-media-preview-video {
+			width: 100%;
+			height: 100%;
+		}
+		.fc-media-preview-footer {
+			display: flex;
+			flex-direction: row;
+			align-items: center;
+			padding:30rpx;
+			// gap: 20rpx;
+		}
+		.fc-media-preview-thumbs {
+			flex: 1;
+			min-width: 0;
+			height: 112rpx;
+			white-space: nowrap;
+		}
+		.fc-media-preview-thumbs-inner {
+			display: inline-flex;
+			flex-direction: row;
+			align-items: center;
+			gap: 16rpx;
+			padding-right: 8rpx;
+		}
+		.fc-media-preview-thumb {
+			width: 96rpx;
+			height: 96rpx;
+			flex-shrink: 0;
+			border-radius: 12rpx;
+			border: 3rpx solid transparent;
+			box-sizing: border-box;
+			background: #333;
+		}
+		.fc-media-preview-thumb--active {
+			border-color: #ff5c03;
+		}
+		.fc-media-preview-thumbs-spacer {
+			flex: 1;
+			min-height: 1rpx;
+		}
+		.fc-media-preview-close {
+			flex-shrink: 0;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+		}
+		.fc-media-preview-close-x {
+			font-size: 44rpx;
+			line-height: 1;
+			color: #333;
+			font-weight: 300;
+			margin-top: -4rpx;
+		}
+
+		.featured-comment-composer-mask {
+			position: fixed;
+			left: 0;
+			right: 0;
+			top: 0;
+			bottom: 0;
+			background: rgba(0, 0, 0, 0.35);
+			z-index: 9998;
+		}
+
+		.featured-comment-composer-wrap {
+			position: fixed;
+			left: 0;
+			right: 0;
+			z-index: 9999;
+			background: #fff;
+			border-radius: 24rpx 24rpx 0 0;
+			padding: 20rpx 24rpx;
+			padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
+			box-sizing: border-box;
+			box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.06);
+		}
+
+		.featured-comment-composer-inner {
+			display: flex;
+			align-items: center;
+			gap: 24rpx;
+		}
+
+		.featured-comment-composer-input-row {
+			flex: 1;
+			min-width: 0;
+			display: flex;
+			align-items: flex-start;
+			background: #f5f5f5;
+			border-radius: 24rpx;
+			padding:20rpx;
+			box-sizing: border-box;
+		}
+
+		.fc-composer-input {
+			flex: 1;
+			min-width: 0;
+			font-size: 32rpx;
+			color: rgba(0, 0, 0, 0.85);
+			height:88rpx;
+			line-height: 44rpx;
+		}
+
+		.fc-composer-ph {
+			color: rgba(0, 0, 0, 0.28);
+			font-size: 32rpx;
+		}
+
+		.fc-composer-input-icon {
+			flex-shrink: 0;
+			margin-left: 12rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+			image {
+				width: 40rpx;
+				height: 40rpx;
+			}
+		}
+
+		.fc-composer-media-pill {
+			position: relative;
+			flex-shrink: 0;
+			width: 64rpx;
+			height: 64rpx;
+			border-radius: 12rpx;
+			overflow: hidden;
+		}
+
+		.fc-composer-media-thumb {
+			width: 100%;
+			height: 100%;
+			display: block;
+		}
+
+		.fc-composer-media-badge {
+			position: absolute;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			font-size: 18rpx;
+			color: #fff;
+			text-align: center;
+			line-height: 1.4;
+			background: rgba(0, 0, 0, 0.45);
+		}
+
+		.fc-composer-media-x {
+			position: absolute;
+			top: -4rpx;
+			right: -4rpx;
+			width: 32rpx;
+			height: 32rpx;
+			line-height: 32rpx;
+			text-align: center;
+			font-size: 28rpx;
+			color: #fff;
+			background: rgba(0, 0, 0, 0.5);
+			border-radius: 50%;
+		}
+
+		.featured-comment-composer-publish {
+			flex-shrink: 0;
+			padding: 20rpx 40rpx;
+			background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+			font-family: PingFangSC, PingFang SC;
+			font-weight: 600;
+			font-size: 40rpx;
+			color: #FFFFFF;
+			line-height: 56rpx;
+			text-align: center;
+			border-radius: 48rpx;
+		}
+
+		.footer {
+			//border-top: 1rpx solid #ededef;
+			background: #fff;
+			width: 100%;
+			position: fixed;
+			bottom: 0;
+			padding: 32rpx;
+			padding-bottom:68rpx;
+			box-sizing: border-box;
+			z-index: 0;
+
+			&-btn {
+				width: 100%;
+				height: 98rpx;
+				background: #FF5C03;
+				border-radius: 49rpx 49rpx 49rpx 49rpx;
+				line-height: 98rpx;
+				text-align: center;
+				font-family: PingFang SC, PingFang SC;
+				font-weight: 600;
+				font-size: 32rpx;
+				color: #FFFFFF;
+				@include u-flex(row, center, center);
+
+				&-img {
+					flex-shrink: 0;
+					width: 144rpx;
+					height: 144rpx;
+					margin-right: 8rpx;
+					margin-top: -24rpx;
+				}
+			}
+
+			&-btn-border {
+				position: relative;
+
+				&::after {
+					content: "";
+					background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
+					position: absolute;
+					top: -2rpx;
+					left: 0;
+					height: 103rpx;
+					width: 100%;
+					z-index: -1;
+					border-radius: 49rpx 49rpx 49rpx 49rpx;
+					box-shadow: 0rpx 8rpx 11rpx 0rpx rgba(255, 92, 3, 0.3);
+					overflow: hidden;
+				}
+			}
+		}
+	}
+
+	.agreement {
+		display: inline-flex;
+		margin-top: 16rpx;
+		font-size: 24rpx;
+		color: #525252;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.nocourse {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		padding-bottom: 88rpx;
+		justify-content: center;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 400;
+		font-size: 32rpx;
+		color: #757575;
+		line-height: 48rpx;
+		text-align: center;
+
+		image {
+			width: 328rpx;
+			height: auto;
+			margin-bottom: 30rpx;
+		}
+	}
+
+	.logo {
+		display: inline-block;
+		width: 30px;
+		height: auto;
+		margin: 20px 0 0 10px;
+		pointer-events: none;
+		object-fit: cover;
+	}
+
+	.logo-full {
+		display: inline-block;
+		width: 40px;
+		height: auto;
+		margin: 50px 0 0 30px;
+		pointer-events: none;
+		object-fit: cover;
+	}
+</style>

Diff do ficheiro suprimidas por serem muito extensas
+ 276 - 593
pages_course/videovip.vue


+ 27 - 10
pages_im/pages/conversation/chating1/components/MessageItem/CustomMessageRender.vue

@@ -298,6 +298,7 @@ export default {
 			if (uni.getStorageSync('companyUserId')) {
 				const queryString = couseItem.appRealLink.split('?')[1] || '';
 				const courseParamMatch = queryString.match(/course=({[^&]+})/);
+				
 				if (!courseParamMatch) {
 					uni.showToast({
 						icon: 'none',
@@ -311,15 +312,31 @@ export default {
 				});
 			}
 			if (couseItem.appRealLink) {
-				if (/^\//.test(couseItem.appRealLink)) {
-					uni.navigateTo({
-						url: couseItem.appRealLink,
-					})
-				} else {
-					uni.navigateTo({
-						url: "/pages_im/pages/common/webH5/index?url=" + couseItem.appRealLink
-					});
-				}
+				const match = couseItem.appRealLink.match(/appcourse\/(.*)/);
+				 if (match && match[1]) {
+				    // 截取到的页面路径 + 参数
+				    const realPath = "/" + match[1];
+				
+				    // 直接跳转 APP 原生页面 ✅
+				    uni.navigateTo({
+				      url: realPath
+				    });
+				    return;
+				  }else{
+					  uni.showToast({
+					  	icon: 'none',
+					  	title: '看课链接不存在'
+					  })
+				  }
+				// if (/^\//.test(couseItem.appRealLink)) {
+				// 	uni.navigateTo({
+				// 		url: couseItem.appRealLink,
+				// 	})
+				// } else {
+				// 	uni.navigateTo({
+				// 		url: "/pages_im/pages/common/webH5/index?url=" + couseItem.appRealLink
+				// 	});
+				// }
 			} else {
 				uni.showToast({
 					icon: 'none',
@@ -345,7 +362,7 @@ export default {
 	  else if (item.payload.data == 'live') {
 			var liveItem=item.payload.extension;
 			console.log("qxj liveItem:",JSON.stringify(liveItem));
-			let url='/pages_live/index?liveId=' + liveItem.liveId;
+			let url='/pages_live/living?liveId=' + liveItem.liveId;
 			if(liveItem.companyId){
 				url += "&companyId="+liveItem.companyId;
 			}

+ 2 - 2
pages_im/pages/conversation/conversationList/index.nvue

@@ -81,13 +81,13 @@
 			</view>
 		</view>
 		<!-- 通知栏 (仅Android显示) -->
-	<!-- 	<view class="notice" v-if="!notice && isAndroid">
+		<view class="notice" v-if="!notice && isAndroid">
 			<view class="notice-left">
 				<text class="notice-title">开启消息通知</text>
 				<text class="notice-text">及时接收消息,不受无关通知打扰</text>
 			</view>
 			<switch :checked="notice" color="#FF5C03" @change="checkPush" style="transform:scale(0.7)" />
-		</view> -->
+		</view>
 		
 		<!-- 列表区域 -->
 		<list class="list" :show-scrollbar="false" @loadmore="loadMore" loadmoreoffset="100"  @scroll="onScroll">

+ 15 - 1
pages_mall/components/RecommendSection.vue

@@ -120,7 +120,21 @@ export default {
 		// 	title: '暂无课程',
 		// 	icon: 'none'
 		// })
-		uni.navigateTo({ url: '/pages_live/livingList' })
+		uni.navigateTo({ url: '/pages_live/living?liveId=1884' })
+		// const courseData = {
+		//   companyId: 6,
+		//   companyUserId: 80,
+		//   id: 1026,
+		//   projectId: 2,
+		//   courseId: 111,
+		//   videoId: 322,
+		//   periodId: 196
+		// };
+		
+		// // 跳转到 videovip 【标准写法】
+		// uni.navigateTo({
+		//   url: "/pages_course/videovip?course=" + encodeURIComponent(JSON.stringify(courseData))
+		// });
 	},
 		onLiveSwiperChange(e) {
 			this.liveCurrent = e.detail.current

BIN
static/images/course/cart.png


BIN
static/images/course/close.png


BIN
static/images/course/jifen.png


BIN
static/images/course/more24.png


BIN
static/images/course/notice.png


BIN
static/images/course/pbg.png


BIN
static/images/course/wk.png


BIN
static/images/course/xg.png


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff