| | |
| | | this.setData({ attachments: updatedAttachments }) |
| | | |
| | | try { |
| | | const uploadResult = await cosUtil.uploadFile(attachment.path, { |
| | | onProgress: (progress) => { |
| | | const uploadResult = await cosUtil.uploadFile( |
| | | attachment.path, |
| | | 'attachment', |
| | | attachment.name || 'attachment', |
| | | (percent) => { |
| | | // 更新上传进度 |
| | | const progressAttachments = this.data.attachments.map(item => { |
| | | if (item.id === attachment.id) { |
| | | return { ...item, progress: Math.round(progress.percent) } |
| | | return { ...item, progress: Math.round(percent) } |
| | | } |
| | | return item |
| | | }) |
| | | this.setData({ attachments: progressAttachments }) |
| | | } |
| | | }) |
| | | ) |
| | | |
| | | // 上传成功 |
| | | const successAttachments = this.data.attachments.map(item => { |
| | |
| | | wx.hideLoading() |
| | | wx.showToast({ |
| | | title: '删除失败', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | }, |
| | | |
| | | // 预览附件 |
| | | async onPreviewAttachment(e) { |
| | | try { |
| | | const index = e.currentTarget.dataset.index |
| | | const attachment = this.data.attachments[index] |
| | | |
| | | if (!attachment.uploaded || !attachment.url) { |
| | | wx.showToast({ |
| | | title: '文件未上传完成', |
| | | icon: 'none' |
| | | }) |
| | | return |
| | | } |
| | | |
| | | const fileType = attachment.type |
| | | |
| | | if (fileType === 'image') { |
| | | // 预览图片 (media_type = 1) |
| | | wx.previewImage({ |
| | | current: attachment.url, |
| | | urls: [attachment.url] |
| | | }) |
| | | } else if (fileType === 'video') { |
| | | // 播放视频 (media_type = 2) - 跳转到视频播放页面 |
| | | wx.navigateTo({ |
| | | url: `/pages/video/video?url=${encodeURIComponent(attachment.url)}&title=${encodeURIComponent(attachment.name)}` |
| | | }) |
| | | } else if (fileType === 'pdf') { |
| | | // PDF文件 (media_type = 4) - 使用小程序内置的文档预览 |
| | | wx.showLoading({ |
| | | title: '正在打开...', |
| | | mask: true |
| | | }) |
| | | |
| | | wx.downloadFile({ |
| | | url: attachment.url, |
| | | success: (res) => { |
| | | wx.hideLoading() |
| | | if (res.statusCode === 200) { |
| | | wx.openDocument({ |
| | | filePath: res.tempFilePath, |
| | | fileType: 'pdf', |
| | | success: () => { |
| | | console.log('PDF打开成功') |
| | | }, |
| | | fail: (err) => { |
| | | console.error('PDF打开失败:', err) |
| | | wx.showToast({ |
| | | title: 'PDF打开失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | wx.showToast({ |
| | | title: '文件下载失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | wx.hideLoading() |
| | | console.error('PDF下载失败:', err) |
| | | wx.showToast({ |
| | | title: '文件下载失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | }) |
| | | } else if (fileType === 'word' || fileType === 'excel' || fileType === 'ppt') { |
| | | // Office文档 (media_type = 4) - 使用小程序内置的文档预览 |
| | | wx.showLoading({ |
| | | title: '正在打开...', |
| | | mask: true |
| | | }) |
| | | |
| | | wx.downloadFile({ |
| | | url: attachment.url, |
| | | success: (res) => { |
| | | wx.hideLoading() |
| | | if (res.statusCode === 200) { |
| | | const fileTypeMap = { |
| | | 'word': 'doc', |
| | | 'excel': 'xls', |
| | | 'ppt': 'ppt' |
| | | } |
| | | |
| | | wx.openDocument({ |
| | | filePath: res.tempFilePath, |
| | | fileType: fileTypeMap[fileType] || 'doc', |
| | | success: () => { |
| | | console.log('文档打开成功') |
| | | }, |
| | | fail: (err) => { |
| | | console.error('文档打开失败:', err) |
| | | wx.showToast({ |
| | | title: '文档打开失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | wx.showToast({ |
| | | title: '文件下载失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | wx.hideLoading() |
| | | console.error('文档下载失败:', err) |
| | | wx.showToast({ |
| | | title: '文件下载失败', |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | // 其他文件类型 (media_type = 5) - 提示用户 |
| | | wx.showModal({ |
| | | title: '文件预览', |
| | | content: `暂不支持预览${fileType}类型的文件,请下载后查看`, |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }) |
| | | } |
| | | } catch (error) { |
| | | console.error('预览附件失败:', error) |
| | | wx.showToast({ |
| | | title: '预览失败', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | |
| | | }) |
| | | |
| | | // 上传到COS |
| | | const uploadResult = await cosUtil.uploadAvatar(this.data.localAvatarPath, { |
| | | onProgress: (progress) => { |
| | | this.setData({ |
| | | avatarUploadProgress: Math.round(progress.percent) |
| | | }) |
| | | } |
| | | }) |
| | | const uploadResult = await cosUtil.uploadAvatar( |
| | | this.data.localAvatarPath, |
| | | 'avatar.jpg', |
| | | (percent) => { |
| | | this.setData({ |
| | | avatarUploadProgress: Math.round(percent) |
| | | }) |
| | | } |
| | | ) |
| | | |
| | | // 上传成功,更新表单数据 |
| | | this.setData({ |
| | |
| | | }) |
| | | |
| | | // 第一步:上传到COS |
| | | const uploadResult = await cosUtil.uploadAvatar(this.data.localAvatarPath, 'avatar.jpg', (progress) => { |
| | | this.setData({ |
| | | avatarUploadProgress: Math.round(progress.percent) |
| | | }) |
| | | }) |
| | | const uploadResult = await cosUtil.uploadAvatar( |
| | | this.data.localAvatarPath, |
| | | 'avatar.jpg', |
| | | (percent) => { |
| | | this.setData({ |
| | | avatarUploadProgress: Math.round(percent) |
| | | }) |
| | | } |
| | | ) |
| | | |
| | | // 第二步:保存媒体记录到数据库 |
| | | await this.saveMediaRecord({ |
| | | targetType: 7, // USER_AVATAR |
| | | targetType: 'player', // V2 使用字符串:player 表示用户头像,对应 DB 的 7 (USER_AVATAR) |
| | | targetId: idInfo.userId, |
| | | url: uploadResult.url, |
| | | path: uploadResult.key, |
| | | fileName: uploadResult.fileName || 'avatar.jpg', |
| | | fileExt: this.getFileExtension(uploadResult.fileName || 'avatar.jpg'), |
| | | fileSize: uploadResult.fileSize, |
| | | mediaType: 1 // 图片 |
| | | }) |
| | |
| | | async uploadAttachmentsWithRegistrationId(idInfo) { |
| | | for (let i = 0; i < this.data.attachments.length; i++) { |
| | | const attachment = this.data.attachments[i] |
| | | if (!attachment.uploaded && attachment.localPath) { |
| | | if (!attachment.uploaded && attachment.path) { |
| | | try { |
| | | // 第一步:上传到COS |
| | | const uploadResult = await cosUtil.uploadFile(attachment.localPath, 'attachment', attachment.name || 'attachment', (progress) => { |
| | | this.setData({ |
| | | [`attachments[${i}].uploadProgress`]: Math.round(progress.percent) |
| | | }) |
| | | }) |
| | | const uploadResult = await cosUtil.uploadFile( |
| | | attachment.path, |
| | | 'attachment', |
| | | attachment.name || 'attachment', |
| | | (percent) => { |
| | | this.setData({ |
| | | [`attachments[${i}].uploadProgress`]: Math.round(percent) |
| | | }) |
| | | } |
| | | ) |
| | | |
| | | // 第二步:保存媒体记录到数据库 |
| | | await this.saveMediaRecord({ |
| | | targetType: 5, // ACTIVITY_PLAYER_SUBMISSION |
| | | targetType: 'activity_player', // V2 使用字符串:activity_player 表示报名附件,对应 DB 的 5 |
| | | targetId: idInfo.activityPlayerId, |
| | | url: uploadResult.url, |
| | | path: uploadResult.key, |
| | | fileName: uploadResult.fileName || attachment.name, |
| | | fileExt: this.getFileExtension(uploadResult.fileName || attachment.name), |
| | | fileSize: uploadResult.fileSize, |
| | | mediaType: this.getMediaType(attachment.name) // 根据文件扩展名判断类型 |
| | | }) |
| | |
| | | // 保存媒体记录到数据库 |
| | | async saveMediaRecord(mediaData) { |
| | | const mutation = ` |
| | | mutation SaveMedia($input: MediaInput!) { |
| | | saveMedia(input: $input) { |
| | | id |
| | | url |
| | | fileName |
| | | mutation SaveMediaV2($input: MediaSaveInput!) { |
| | | saveMediaV2(input: $input) { |
| | | success |
| | | message |
| | | mediaId |
| | | } |
| | | } |
| | | ` |
| | |
| | | input: { |
| | | targetType: mediaData.targetType, |
| | | targetId: mediaData.targetId, |
| | | url: mediaData.url, |
| | | fileName: mediaData.fileName, |
| | | path: mediaData.path, |
| | | fileName: mediaData.fileName || mediaData.name, // V2 字段为 fileName,兼容旧字段 name |
| | | fileExt: mediaData.fileExt, |
| | | fileSize: mediaData.fileSize, |
| | | mediaType: mediaData.mediaType |
| | | } |
| | |
| | | |
| | | try { |
| | | const result = await app.graphqlRequest(mutation, variables) |
| | | console.log('媒体记录保存成功:', result.saveMedia) |
| | | return result.saveMedia |
| | | console.log('媒体记录保存成功(V2):', result.saveMediaV2) |
| | | return result.saveMediaV2 |
| | | } catch (error) { |
| | | console.error('媒体记录保存失败:', error) |
| | | console.error('媒体记录保存失败(V2):', error) |
| | | throw error |
| | | } |
| | | }, |
| | | |
| | | // 获取文件扩展名 |
| | | getFileExtension(fileName) { |
| | | if (!fileName) return '' |
| | | return fileName.split('.').pop().toLowerCase() |
| | | }, |
| | | |
| | | // 根据文件名获取媒体类型 |
| | | getMediaType(fileName) { |
| | | if (!fileName) return 1 // 默认图片 |