findme-miniprogram-frontend/components/media-preview/media-preview.js
2025-12-27 17:16:03 +08:00

550 lines
11 KiB
JavaScript

// 🎨 媒体预览组件逻辑
const mediaManager = require('../../subpackages/media/utils/media-manager.js');
Component({
properties: {
// 是否显示预览
visible: {
type: Boolean,
value: false
},
// 媒体列表
mediaList: {
type: Array,
value: []
},
// 当前索引
currentIndex: {
type: Number,
value: 0
},
// 是否可以分享
canShare: {
type: Boolean,
value: true
},
// 是否可以编辑
canEdit: {
type: Boolean,
value: false
},
// 是否可以删除
canDelete: {
type: Boolean,
value: false
},
// 是否显示底部操作栏
showFooter: {
type: Boolean,
value: true
},
// 是否显示手势提示
showGestureTips: {
type: Boolean,
value: true
}
},
data: {
// 当前媒体
currentMedia: {},
// 音频播放状态
audioPlaying: false,
audioProgress: 0,
audioCurrentTime: 0,
// 手势提示定时器
gestureTimer: null
},
observers: {
'mediaList, currentIndex': function(mediaList, currentIndex) {
if (mediaList && mediaList.length > 0 && currentIndex >= 0 && currentIndex < mediaList.length) {
this.setData({
currentMedia: mediaList[currentIndex]
});
}
}
},
lifetimes: {
attached() {
},
detached() {
this.cleanup();
}
},
methods: {
// 🎨 ===== 基础操作 =====
// 阻止事件冒泡
stopPropagation() {
// 阻止点击事件冒泡到遮罩层
},
// 遮罩点击
onMaskTap() {
this.closePreview();
},
// 关闭预览
closePreview() {
this.setData({
visible: false
});
this.triggerEvent('close');
this.cleanup();
},
// 清理资源
cleanup() {
// 停止音频播放
if (this.data.audioPlaying) {
this.stopAudio();
}
// 清理定时器
if (this.data.gestureTimer) {
clearTimeout(this.data.gestureTimer);
}
},
// 🎨 ===== 图片操作 =====
// 轮播图切换
onSwiperChange(e) {
const currentIndex = e.detail.current;
this.setData({
currentIndex: currentIndex
});
this.triggerEvent('indexchange', {
currentIndex: currentIndex
});
},
// 图片加载完成
onImageLoad(e) {
const index = e.currentTarget.dataset.index;
const mediaList = this.data.mediaList;
if (mediaList[index]) {
mediaList[index].loading = false;
mediaList[index].error = false;
this.setData({
mediaList: mediaList
});
}
},
// 图片加载失败
onImageError(e) {
console.error('❌ 图片加载失败');
const index = e.currentTarget.dataset.index;
const mediaList = this.data.mediaList;
if (mediaList[index]) {
mediaList[index].loading = false;
mediaList[index].error = true;
this.setData({
mediaList: mediaList
});
}
},
// 图片点击
onImageTap(e) {
// 可以实现双击放大等功能
},
// 重试加载
retryLoad(e) {
const index = e.currentTarget.dataset.index;
const mediaList = this.data.mediaList;
if (mediaList[index]) {
mediaList[index].loading = true;
mediaList[index].error = false;
this.setData({
mediaList: mediaList
});
}
},
// 🎨 ===== 视频操作 =====
// 视频播放
onVideoPlay() {
this.triggerEvent('videoplay');
},
// 视频暂停
onVideoPause() {
this.triggerEvent('videopause');
},
// 视频结束
onVideoEnded() {
this.triggerEvent('videoended');
},
// 视频错误
onVideoError(e) {
console.error('❌ 视频播放错误:', e.detail);
wx.showToast({
title: '视频播放失败',
icon: 'none'
});
},
// 视频时间更新
onVideoTimeUpdate(e) {
// 可以用于显示播放进度
},
// 🎨 ===== 音频操作 =====
// 切换音频播放
toggleAudioPlay() {
if (this.data.audioPlaying) {
this.pauseAudio();
} else {
this.playAudio();
}
},
// 播放音频
playAudio() {
// 这里需要实现音频播放逻辑
this.setData({
audioPlaying: true
});
// 模拟播放进度
this.startAudioProgress();
},
// 暂停音频
pauseAudio() {
this.setData({
audioPlaying: false
});
this.stopAudioProgress();
},
// 停止音频
stopAudio() {
this.setData({
audioPlaying: false,
audioProgress: 0,
audioCurrentTime: 0
});
this.stopAudioProgress();
},
// 开始音频进度更新
startAudioProgress() {
this.audioProgressTimer = setInterval(() => {
const currentTime = this.data.audioCurrentTime + 1;
const duration = this.data.currentMedia.duration || 100;
const progress = (currentTime / duration) * 100;
this.setData({
audioCurrentTime: currentTime,
audioProgress: Math.min(progress, 100)
});
if (progress >= 100) {
this.stopAudio();
}
}, 1000);
},
// 停止音频进度更新
stopAudioProgress() {
if (this.audioProgressTimer) {
clearInterval(this.audioProgressTimer);
this.audioProgressTimer = null;
}
},
// 🎨 ===== 文件操作 =====
// 打开文件
openFile() {
const currentMedia = this.data.currentMedia;
wx.openDocument({
filePath: currentMedia.tempFilePath || currentMedia.url,
fileType: currentMedia.extension,
success: () => {
},
fail: (error) => {
console.error('❌ 文件打开失败:', error);
wx.showToast({
title: '无法打开此文件',
icon: 'none'
});
}
});
},
// 保存文件
async saveFile() {
const currentMedia = this.data.currentMedia;
try {
wx.showLoading({
title: '保存中...'
});
// 如果是网络文件,先下载
let filePath = currentMedia.tempFilePath;
if (!filePath && currentMedia.url) {
const downloadResult = await mediaManager.downloadFile(currentMedia.url);
if (downloadResult.success) {
filePath = downloadResult.tempFilePath;
} else {
throw new Error('下载失败');
}
}
// 保存到本地
const result = await new Promise((resolve, reject) => {
wx.saveFile({
tempFilePath: filePath,
success: resolve,
fail: reject
});
});
wx.hideLoading();
wx.showToast({
title: '保存成功',
icon: 'success'
});
} catch (error) {
wx.hideLoading();
console.error('❌ 文件保存失败:', error);
wx.showToast({
title: '保存失败',
icon: 'none'
});
}
},
// 🎨 ===== 操作按钮 =====
// 下载媒体
async downloadMedia() {
const currentMedia = this.data.currentMedia;
if (!currentMedia.url) {
wx.showToast({
title: '无法下载',
icon: 'none'
});
return;
}
try {
wx.showLoading({
title: '下载中...'
});
const result = await mediaManager.downloadFile(currentMedia.url, {
fileName: currentMedia.name
});
wx.hideLoading();
if (result.success) {
wx.showToast({
title: '下载完成',
icon: 'success'
});
this.triggerEvent('download', {
media: currentMedia,
filePath: result.tempFilePath
});
} else {
throw new Error(result.error);
}
} catch (error) {
wx.hideLoading();
console.error('❌ 下载失败:', error);
wx.showToast({
title: '下载失败',
icon: 'none'
});
}
},
// 分享媒体
shareMedia() {
const currentMedia = this.data.currentMedia;
this.triggerEvent('share', {
media: currentMedia
});
},
// 编辑媒体
editMedia() {
const currentMedia = this.data.currentMedia;
this.triggerEvent('edit', {
media: currentMedia,
index: this.data.currentIndex
});
},
// 删除媒体
deleteMedia() {
const currentMedia = this.data.currentMedia;
wx.showModal({
title: '删除确认',
content: '确定要删除这个文件吗?',
success: (res) => {
if (res.confirm) {
this.triggerEvent('delete', {
media: currentMedia,
index: this.data.currentIndex
});
}
}
});
},
// 收藏媒体
favoriteMedia() {
const currentMedia = this.data.currentMedia;
const favorited = !currentMedia.favorited;
// 更新收藏状态
currentMedia.favorited = favorited;
this.setData({
currentMedia: currentMedia
});
this.triggerEvent('favorite', {
media: currentMedia,
favorited: favorited
});
wx.showToast({
title: favorited ? '已收藏' : '已取消收藏',
icon: 'success'
});
},
// 显示更多操作
showMoreActions() {
const actions = ['转发', '设为壁纸', '添加到相册', '举报'];
wx.showActionSheet({
itemList: actions,
success: (res) => {
this.triggerEvent('moreaction', {
action: actions[res.tapIndex],
media: this.data.currentMedia
});
}
});
},
// 🎨 ===== 工具方法 =====
// 格式化文件大小
formatFileSize(size) {
if (!size) return '未知大小';
const units = ['B', 'KB', 'MB', 'GB'];
let unitIndex = 0;
let fileSize = size;
while (fileSize >= 1024 && unitIndex < units.length - 1) {
fileSize /= 1024;
unitIndex++;
}
return `${fileSize.toFixed(1)} ${units[unitIndex]}`;
},
// 格式化时长
formatDuration(duration) {
if (!duration) return '00:00';
const minutes = Math.floor(duration / 60);
const seconds = Math.floor(duration % 60);
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
},
// 格式化时间
formatTime(time) {
if (!time) return '00:00';
const minutes = Math.floor(time / 60);
const seconds = Math.floor(time % 60);
return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
},
// 获取文件图标
getFileIcon(extension) {
const iconMap = {
'pdf': '📄',
'doc': '📝',
'docx': '📝',
'xls': '📊',
'xlsx': '📊',
'ppt': '📽️',
'pptx': '📽️',
'txt': '📃',
'zip': '🗜️',
'rar': '🗜️',
'mp3': '🎵',
'wav': '🎵',
'mp4': '🎬',
'avi': '🎬'
};
return iconMap[extension] || '📄';
}
}
});