Con gái riêng hư hỏng muốn bạn mình xem cảnh cô ta quan hệ với bố dượng【FAMILYxxx】","lastmod":"2026-07-11","duration":"0:28:57","url":"/play/19267102.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvNjQ0NWNkODc0ZDZlODMxNTk5Y2RiOWM4MjczZWFhMjAuanBn.cache","vod_id":19038810,"title":"Cô nàng Emily Willis lãng mạn của Little Mimi đã có một cuộc gặp gỡ tình ái đầy gợi cảm với bạn trai của mình.","lastmod":"2025-03-28","duration":"","url":"/play/19038810.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTEyMjMvMjkzYWE1MmRhYjY3ZDAwNTQwYjQ4YmQwYmUyMGViMTMuanBn.cache","vod_id":19254043,"title":"\"Tôi đã xuất tinh rồi!\" Bạn thân của tôi không thể cử động và đã được kéo ra ngoài. (Diễn viên: JULIA, Yone Yuria, Honma Yuri, v.v.)","lastmod":"2026-04-15","duration":"4:01:25","url":"/play/19254043.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvY2Q4Mzc3NWExZTdhNWI4NjM3MzgwZjZmNjM4YmM5NTcuanBn.cache","vod_id":19137850,"title":"[Bản gốc phát hành lần đầu] Hy vọng mọi chuyện sẽ nhanh chóng kết thúc bằng xuất tinh sớm.","lastmod":"2025-03-29","duration":"0:28:08","url":"/play/19137850.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvMThhMjJmMjhkM2I4MjE1YzY1Y2RjZGI5ZTZiMzI3MmIuanBn.cache","vod_id":19140149,"title":"Vòng Lăn Vô Tận Của Bạn Mẹ Tôi Tập 30: Kyoka xinh đẹp, sở hữu thân hình người mẫu và vô cùng quyến rũ...","lastmod":"2025-03-29","duration":"2:10:50","url":"/play/19140149.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvYWQ0MzBjYTgxYjRhNTNhMDhmYzQ5MmM1ZDBmOWM2Y2YuanBn.cache","vod_id":19127216,"title":"[Bản gốc phát hành lần đầu] Sophia Leone, một cô gái Hồi giáo đội khăn trùm đầu, cởi hết quần áo trong cảnh threesome dâm dục này, để cho âm đạo chật hẹp của mình bị hai dương vật cứng, trắng nõn thống trị.","lastmod":"2025-03-29","duration":"0:32:15","url":"/play/19127216.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTEyMjMvZjZhODhlOTdlZTNlOWQ5YTcyY2Q3ODQ0NjAyMzQyMjYuanBn.cache","vod_id":19242495,"title":"Em họ tôi là giáo viên dạy nhảy (cô ấy thích thú với việc mang tất và tự thỏa mãn đến khi đạt cực khoái, phát ra những tiếng rên rỉ quyến rũ).","lastmod":"2026-02-01","duration":"0:16:05","url":"/play/19242495.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNjA1MTMvNTNiZWRlOTQ3YWJlYmVhYjdhMzM0ODA3ZGNjYTIxNDMuanBn.cache","vod_id":19260794,"title":"Hãy tận hưởng trải nghiệm thủ dâm đầy khinh miệt nhất trong lịch sử thông qua cuộc trò chuyện dâm dục ngọt ngào và chua chát đầy đủ! Hongo Ai S1 NO.1 STYLE","lastmod":"2026-05-27","duration":"2:27:34","url":"/play/19260794.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvYTUyNDYwYjlhODEyMmRkN2FiOWE1NmE5NGU4NGIyYTYuanBn.cache","vod_id":19031009,"title":"[Rò rỉ thông tin trên Baidu Cloud] Một tên khốn nạn đã lừa dối một nữ sinh năm nhất, chia tay với cô ấy, rồi tung video lên mạng và chia sẻ với bạn bè. Cô gái tức giận đến mức muốn tự tử sau khi bị phát hiện!","lastmod":"2025-03-28","duration":"0:32:21","url":"/play/19031009.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvYTFiYzgzYWYxZDgzZDNkYzM2NTM4OGRlMzA3MDY0MWUuanBn.cache","vod_id":19128311,"title":"RCTD-563 Nữ MC nói chuyện tục tĩu 33 Nữ MC đặc biệt với những thói quen cực kỳ tốt - Yukari Shizuki","lastmod":"2025-03-29","duration":"2:03:44","url":"/play/19128311.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvZWM1ZDUxN2U1MjYzMWU0MjMyY2M3MGUzMmE2YzA1NGYuanBn.cache","vod_id":19069444,"title":"SAME-028 Do ham muốn tình dục cao, một nữ quản lý sẽ đáp ứng nhu cầu tình dục của chúng tôi. Anna Hanayagi","lastmod":"2025-03-29","duration":"1:59:14","url":"/play/19069444.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvNGE2YmExZGQxMzc4ZDUxMmY2NWI2MjJkNDQyYTk2MzAuanBn.cache","vod_id":19190890,"title":"JUQ285C Một người bạn là mẹ đã mời tôi dùng ứng dụng hẹn hò để nhẹ nhàng chinh phục một \"chàng trai trẻ mà tôi thích\".","lastmod":"2025-03-30","duration":"2:54:15","url":"/play/19190890.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvOWYyMzI3YTA2ZWE2YzI2MjgyNmY0NTQ4ODlhYTQ1NjMuanBn.cache","vod_id":19110874,"title":"Một ngày tốt lành bắt đầu bằng việc tập thể dục.","lastmod":"2025-03-29","duration":"0:07:56","url":"/play/19110874.html"},{"img":"https://cache.sgvafs.com/base/aHR0cHM6Ly92aWRlby5kYWdlLnRvcC9zdG9yYWdlL3VwbG9hZHMvMjAyNTAzMzEvOGRjY2VjODVmNDdmZGZkNjJmYmUzODY2NWJlOGJlYmEuanBn.cache","vod_id":19165971,"title":"Vì bạn trai, một người bạn cùng lớp, không thể thỏa mãn những ham muốn thầm kín của cô, nên người chị gái có vòng ba khủng đã dạy cô về các vùng nhạy cảm thông qua việc thủ dâm cùng nhau, và cô ấy lập tức xuất tinh. Sự phát triển của người phụ nữ thật không thể chịu đựng được - Tenma Yui.","lastmod":"2025-03-30","duration":"2:40:30","url":"/play/19165971.html"}]},
videoTitle: '[Bản phát hành gốc] Leona là một người bạn gái tốt, nhưng cô ta còn là một kẻ lừa đảo tài ba hơn nữa.',
language: 'vi',
dataKey: '01',
loadingPlayer: true,
showShare: false,
pageUrl: '',
// RecommendedMovies 组件状态
isSingleColumn: false,
pageSize: 8,
currentPage: 1,
// 计算属性(使用 getter)
get layoutIconClass() {
return this.isSingleColumn ? 'icon-view-list' : 'icon-grid';
},
get layoutClass() {
return [
'row',
'g-3',
'row-cols-1',
this.isSingleColumn ? '' : 'row-cols-2',
'row-cols-lg-4'
].filter(Boolean).join(' ');
},
// 方法
onAppMounted() {
// 设置页面 URL
this.pageUrl = window.location.href;
// 保存观看历史
this.saveWatchHistory();
// 更新标签统计
if (this.videoData.tag && this.videoData.tag.length > 0) {
this.updateTagStats(this.videoData.tag);
}
// 发送点击统计
this.hitVideoId(this.videoData.id);
// 从 Cookie 读取布局偏好
const layoutCookie = this.getCookie('list_layout');
if (layoutCookie === 'single') {
this.isSingleColumn = true;
}
// 监听 iframe 加载完成,隐藏骨架屏
// 使用 setTimeout 确保 DOM 已完全渲染
setTimeout(() => {
const iframe = document.getElementById('v2-player');
const skeleton = document.getElementById('player-skeleton');
if (iframe && skeleton) {
// 定义隐藏骨架屏的函数
const hideSkeleton = () => {
skeleton.style.transition = 'opacity 0.3s ease';
skeleton.style.opacity = '0';
setTimeout(() => {
skeleton.style.display = 'none';
}, 300);
};
// 检查 iframe 是否已经加载完成
if (iframe.contentDocument || iframe.contentWindow) {
try {
// 如果 iframe 已加载,直接隐藏骨架屏
if (iframe.contentWindow.document.readyState === 'complete') {
setTimeout(hideSkeleton, 500);
return;
}
} catch (e) {
console.log('[Video] 跨域 iframe,无法检查状态:', e.message);
// 跨域情况下无法访问 contentWindow,继续监听 load 事件
}
}
// 监听 load 事件
iframe.addEventListener('load', () => {
console.log('[Video] iframe load 事件触发');
setTimeout(hideSkeleton, 500);
});
// 添加超时保护,确保骨架屏最终会被隐藏
setTimeout(() => {
if (skeleton.style.display !== 'none') {
console.log('[Video] 超时保护触发,强制隐藏骨架屏');
hideSkeleton();
}
}, 5000); // 5秒后强制隐藏
} else {
console.error('[Video] 未找到 iframe 或 skeleton 元素');
}
}, 0);
},
// 随机跳转
async jumpToRandomVideo() {
try {
const response = await fetch(`/api/qun/randomid?t=${Date.now()}`, {
headers: {
'x-data-key': this.dataKey,
'x-api-key': 'dagexxx.com'
}
});
const data = await response.json();
if (data?.status === 1 && data?.data?.id) {
window.location.href = `/${this.language}/play/${data.data.id}.html`;
} else {
console.error('获取随机视频失败:', data?.message || '未知错误');
}
} catch (err) {
console.error('获取随机视频失败:', err);
}
},
// 复制分享链接
copyShareLink() {
const input = this.$refs.shareInput;
if (input) {
input.select();
input.setSelectionRange(0, 99999); // For mobile devices
// 尝试使用现代 API
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(this.pageUrl).then(() => {
alert('Đã sao chép liên kết!');
}).catch(() => {
// 降级到旧方法
document.execCommand('copy');
alert('Đã sao chép liên kết!');
});
} else {
// 降级到旧方法
document.execCommand('copy');
alert('Đã sao chép liên kết!');
}
}
},
// 切换布局
toggleLayout() {
this.isSingleColumn = !this.isSingleColumn;
this.setCookie('list_layout', this.isSingleColumn ? 'single' : 'multi', 30);
},
// 加载更多
loadMore() {
this.currentPage++;
},
// 保存观看历史
saveWatchHistory() {
try {
const storageKey = 'watchHistory';
let history = JSON.parse(localStorage.getItem(storageKey) || '[]');
// 解码 HTML 实体编码的标题
const decodeHtmlEntities = (text) => {
const textarea = document.createElement('textarea');
textarea.innerHTML = text;
return textarea.value;
};
const video = {
id: this.videoData.id,
title: decodeHtmlEntities(this.videoData.title),
image: this.videoData.images || this.videoData.preview,
duration: this.videoData.duration || ''
};
// 过滤掉已存在的相同 ID 视频
history = history.filter(item => item.id !== video.id);
// 添加新记录到最前面
history.unshift(video);
// 限制最多保存 100 条
if (history.length > 100) {
history = history.slice(0, 100);
}
localStorage.setItem(storageKey, JSON.stringify(history));
} catch (e) {
console.error('Failed to save watch history:', e);
}
},
// 更新标签统计
updateTagStats(tags = []) {
// HTML 实体解码函数
const decodeHtmlEntities = (text) => {
const textarea = document.createElement('textarea');
textarea.innerHTML = text;
return textarea.value;
};
const storageKey = this.dataKey + 'tagWatchStats';
const lastWatchedKey = this.dataKey + 'tagLastWatched';
const raw = localStorage.getItem(storageKey);
const stats = raw ? JSON.parse(raw) : {};
// 解码标签并统计
const decodedTags = tags.map(tag => decodeHtmlEntities(tag));
decodedTags.forEach(tag => {
stats[tag] = (stats[tag] || 0) + 1;
});
localStorage.setItem(storageKey, JSON.stringify(stats));
localStorage.setItem(lastWatchedKey, JSON.stringify(decodedTags));
},
// 点击统计
hitVideoId(id) {
fetch(`/api/qun/hit?type=play&id=${id}`, {
method: 'GET',
headers: {
'x-data-key': this.dataKey,
'x-api-key': 'dagexxx.com'
}
}).catch(err => {
console.error('点击统计失败:', err);
});
},
// Cookie 工具方法
getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
},
setCookie(name, value, days) {
const expires = new Date(Date.now() + days * 864e5).toUTCString();
document.cookie = `${name}=${value}; expires=${expires}; path=/`;
}
};
}