/**
							 | 
						|
								 * 可见性监听混入
							 | 
						|
								 * 提供元素可见性监听功能,支持H5、微信小程序、App端
							 | 
						|
								 * 用于实现浏览记录等功能
							 | 
						|
								 */
							 | 
						|
								import { VIEWPORT_CONFIG, createBrowseRecordParams } from '@/config/browseConfig.js'
							 | 
						|
								
							 | 
						|
								export default {
							 | 
						|
									data() {
							 | 
						|
										return {
							 | 
						|
											hasRecordedView: false, // 标记是否已记录浏览
							 | 
						|
											viewTimer: null, // 浏览计时器
							 | 
						|
											isInViewport: false, // 是否在可视区域内
							 | 
						|
											observer: null, // 观察者实例
							 | 
						|
										}
							 | 
						|
									},
							 | 
						|
									
							 | 
						|
									mounted() {
							 | 
						|
										// 组件挂载后,使用Intersection Observer监听可见性
							 | 
						|
										this.observeVisibility()
							 | 
						|
									},
							 | 
						|
									
							 | 
						|
									beforeDestroy() {
							 | 
						|
										// 组件销毁前清理observer和计时器
							 | 
						|
										this.cleanupObserver()
							 | 
						|
									},
							 | 
						|
									
							 | 
						|
									methods: {
							 | 
						|
										/**
							 | 
						|
										 * 监听元素可见性
							 | 
						|
										 * @param {String} selector - 要监听的元素选择器,默认为'.works'
							 | 
						|
										 * @param {Object} config - 配置参数
							 | 
						|
										 */
							 | 
						|
										observeVisibility(selector = '.works', config = {}) {
							 | 
						|
											const {
							 | 
						|
												threshold = VIEWPORT_CONFIG.THRESHOLD,
							 | 
						|
												dwellTime = VIEWPORT_CONFIG.DWELL_TIME,
							 | 
						|
												margins = VIEWPORT_CONFIG.VIEWPORT_MARGINS
							 | 
						|
											} = config
							 | 
						|
											
							 | 
						|
											// #ifdef H5
							 | 
						|
											if (typeof IntersectionObserver !== 'undefined') {
							 | 
						|
												this.observer = new IntersectionObserver((entries) => {
							 | 
						|
													entries.forEach(entry => {
							 | 
						|
														if (entry.isIntersecting && !this.hasRecordedView) {
							 | 
						|
															// 元素进入可视区域且未记录过浏览
							 | 
						|
															this.handleViewportEnter(dwellTime)
							 | 
						|
														} else if (!entry.isIntersecting && this.isInViewport) {
							 | 
						|
															// 元素离开可视区域
							 | 
						|
															this.handleViewportLeave()
							 | 
						|
														}
							 | 
						|
													})
							 | 
						|
												}, {
							 | 
						|
													threshold: threshold
							 | 
						|
												})
							 | 
						|
												
							 | 
						|
												this.observer.observe(this.$el)
							 | 
						|
											} else {
							 | 
						|
												// 降级方案:延迟记录浏览
							 | 
						|
												setTimeout(() => {
							 | 
						|
													if (!this.hasRecordedView) {
							 | 
						|
														this.recordBrowseView()
							 | 
						|
													}
							 | 
						|
												}, dwellTime)
							 | 
						|
											}
							 | 
						|
											// #endif
							 | 
						|
											
							 | 
						|
											// #ifdef MP-WEIXIN
							 | 
						|
											// 使用微信小程序原生的IntersectionObserver API
							 | 
						|
											this.observer = wx.createIntersectionObserver(this, {
							 | 
						|
												thresholds: [threshold],
							 | 
						|
												initialRatio: 0,
							 | 
						|
												observeAll: false
							 | 
						|
											})
							 | 
						|
											
							 | 
						|
											// 指定页面显示区域作为参照区域
							 | 
						|
											this.observer.relativeToViewport(margins)
							 | 
						|
											
							 | 
						|
											// 开始监听目标节点
							 | 
						|
											this.observer.observe(selector, (res) => {
							 | 
						|
												if (res.intersectionRatio > threshold && !this.hasRecordedView) {
							 | 
						|
													// 当元素达到配置阈值以上进入可视区域且未记录过浏览时,处理进入可视区域事件
							 | 
						|
													this.handleViewportEnter(dwellTime)
							 | 
						|
												} else if (res.intersectionRatio <= threshold && this.isInViewport) {
							 | 
						|
													// 元素离开可视区域
							 | 
						|
													this.handleViewportLeave()
							 | 
						|
												}
							 | 
						|
											})
							 | 
						|
											// #endif
							 | 
						|
											
							 | 
						|
											// #ifdef APP-PLUS
							 | 
						|
											// App端使用uni-app的createIntersectionObserver
							 | 
						|
											this.observer = uni.createIntersectionObserver(this, {
							 | 
						|
												thresholds: [threshold],
							 | 
						|
												initialRatio: 0,
							 | 
						|
												observeAll: false
							 | 
						|
											})
							 | 
						|
											
							 | 
						|
											this.observer.relativeToViewport(margins)
							 | 
						|
											
							 | 
						|
											this.observer.observe(selector, (res) => {
							 | 
						|
												if (res.intersectionRatio > threshold && !this.hasRecordedView) {
							 | 
						|
													this.handleViewportEnter(dwellTime)
							 | 
						|
												} else if (res.intersectionRatio <= threshold && this.isInViewport) {
							 | 
						|
													this.handleViewportLeave()
							 | 
						|
												}
							 | 
						|
											})
							 | 
						|
											// #endif
							 | 
						|
										},
							 | 
						|
										
							 | 
						|
										/**
							 | 
						|
										 * 处理进入可视区域事件
							 | 
						|
										 * @param {Number} dwellTime - 停留时间
							 | 
						|
										 */
							 | 
						|
										handleViewportEnter(dwellTime = VIEWPORT_CONFIG.DWELL_TIME) {
							 | 
						|
											if (this.hasRecordedView) return
							 | 
						|
											
							 | 
						|
											this.isInViewport = true
							 | 
						|
											
							 | 
						|
											// 设置延迟计时器,确保用户真正浏览了内容
							 | 
						|
											this.viewTimer = setTimeout(() => {
							 | 
						|
												if (this.isInViewport && !this.hasRecordedView) {
							 | 
						|
													this.recordBrowseView()
							 | 
						|
												}
							 | 
						|
											}, dwellTime)
							 | 
						|
										},
							 | 
						|
										
							 | 
						|
										/**
							 | 
						|
										 * 处理离开可视区域事件
							 | 
						|
										 */
							 | 
						|
										handleViewportLeave() {
							 | 
						|
											this.isInViewport = false
							 | 
						|
											
							 | 
						|
											// 清除计时器,如果用户快速滚动过去,不记录浏览
							 | 
						|
											if (this.viewTimer) {
							 | 
						|
												clearTimeout(this.viewTimer)
							 | 
						|
												this.viewTimer = null
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										
							 | 
						|
										/**
							 | 
						|
										 * 记录浏览行为
							 | 
						|
										 * @param {String} itemType - 项目类型,默认为'dynamic'
							 | 
						|
										 * @param {String} itemId - 项目ID,默认从this.item.id获取
							 | 
						|
										 */
							 | 
						|
										recordBrowseView(itemType = 'dynamic', itemId = null) {
							 | 
						|
											const id = itemId || (this.item && this.item.id)
							 | 
						|
											
							 | 
						|
											if (this.hasRecordedView || !id) return
							 | 
						|
											
							 | 
						|
											this.hasRecordedView = true
							 | 
						|
											
							 | 
						|
											// 清除计时器
							 | 
						|
											if (this.viewTimer) {
							 | 
						|
												clearTimeout(this.viewTimer)
							 | 
						|
												this.viewTimer = null
							 | 
						|
											}
							 | 
						|
											
							 | 
						|
											// 使用配置文件中的参数创建API请求参数
							 | 
						|
											const params = createBrowseRecordParams(id, itemType)
							 | 
						|
											
							 | 
						|
											// 调用浏览记录API
							 | 
						|
											this.$api('addBrowseRecord', params, res => {
							 | 
						|
												if (res.code === 200) {
							 | 
						|
													console.log('浏览记录已保存:', id)
							 | 
						|
												}
							 | 
						|
											})
							 | 
						|
										},
							 | 
						|
										
							 | 
						|
										/**
							 | 
						|
										 * 清理观察者和计时器
							 | 
						|
										 */
							 | 
						|
										cleanupObserver() {
							 | 
						|
											if (this.observer) {
							 | 
						|
												// #ifdef H5
							 | 
						|
												if (typeof this.observer.disconnect === 'function') {
							 | 
						|
													this.observer.disconnect()
							 | 
						|
												}
							 | 
						|
												// #endif
							 | 
						|
												
							 | 
						|
												// #ifdef MP-WEIXIN || APP-PLUS
							 | 
						|
												if (typeof this.observer.disconnect === 'function') {
							 | 
						|
													this.observer.disconnect()
							 | 
						|
												}
							 | 
						|
												// #endif
							 | 
						|
												
							 | 
						|
												this.observer = null
							 | 
						|
											}
							 | 
						|
											
							 | 
						|
											if (this.viewTimer) {
							 | 
						|
												clearTimeout(this.viewTimer)
							 | 
						|
												this.viewTimer = null
							 | 
						|
											}
							 | 
						|
										},
							 | 
						|
										
							 | 
						|
										/**
							 | 
						|
										 * 重置浏览记录状态
							 | 
						|
										 */
							 | 
						|
										resetBrowseRecord() {
							 | 
						|
											this.hasRecordedView = false
							 | 
						|
											this.isInViewport = false
							 | 
						|
											this.cleanupObserver()
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								}
							 |