const { graphqlRequest } = require('../../lib/utils') const DETAIL_QUERY = ` query ActivityPlayerDetail($id: ID!) { activityPlayerDetail(id: $id) { id activityName projectName description feedback state playerInfo { id name phone } submissionFiles { id name fullUrl fullThumbUrl fileExt fileSize mediaType } } } ` const APPROVE_MUTATION = ` mutation ApproveActivityPlayer($id: ID!, $feedback: String) { approveActivityPlayer(activityPlayerId: $id, feedback: $feedback) } ` const REJECT_MUTATION = ` mutation RejectActivityPlayer($id: ID!, $feedback: String) { rejectActivityPlayer(activityPlayerId: $id, feedback: $feedback) } ` Page({ data: { loading: false, submitting: false, activityPlayerId: null, detail: { playerInfo: {}, submissionFiles: [] }, feedback: '', mediaList: [] }, onLoad(options) { if (options && options.id) { if (typeof this.getOpenerEventChannel === 'function') { this.eventChannel = this.getOpenerEventChannel() } this.setData({ activityPlayerId: options.id }) this.loadDetail() } else { wx.showToast({ title: '缺少报名ID', icon: 'none' }) setTimeout(() => wx.navigateBack(), 800) } }, async loadDetail() { if (!this.data.activityPlayerId) { return } this.setData({ loading: true }) try { const result = await graphqlRequest(DETAIL_QUERY, { id: this.data.activityPlayerId }) const detail = result && result.activityPlayerDetail if (!detail) { wx.showToast({ title: '未找到报名信息', icon: 'none' }) return } const mediaList = (detail.submissionFiles || []).map(item => this.transformMediaFile(item)) const playerInfo = detail.playerInfo || {} this.setData({ detail: { ...detail, playerInfo, stateText: this.getStateText(detail.state), submissionFiles: mediaList }, mediaList, feedback: detail.feedback || '' }) } catch (error) { console.error('加载审核详情失败:', error) wx.showToast({ title: '加载失败', icon: 'none' }) } finally { this.setData({ loading: false }) } }, transformMediaFile(file = {}) { const url = file.fullUrl || file.fullThumbUrl || file.url || '' const thumbUrl = file.fullThumbUrl || file.fullUrl || url const ext = (file.fileExt || '').toLowerCase() let mediaType = 'file' if (file.mediaType === 1 || ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'heic'].includes(ext)) { mediaType = 'image' } else if (file.mediaType === 2 || ['mp4', 'mov', 'avi', 'wmv', 'mkv', 'webm', 'flv'].includes(ext)) { mediaType = 'video' } else if (ext === 'pdf') { mediaType = 'pdf' } else if (['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'wps', 'txt', 'rtf'].includes(ext)) { mediaType = 'word' } return { id: file.id, name: file.name || '资料文件', url, thumbUrl, mediaType, size: Number(file.fileSize) || 0 } }, onFeedbackInput(e) { this.setData({ feedback: e.detail.value }) }, onApprove() { this.handleAudit('APPROVE') }, onReject() { this.handleAudit('REJECT') }, async handleAudit(action) { if (!this.data.activityPlayerId) { return } const mutation = action === 'APPROVE' ? APPROVE_MUTATION : REJECT_MUTATION const successText = action === 'APPROVE' ? '审核通过' : '已驳回' this.setData({ submitting: true }) try { const trimmedFeedback = (this.data.feedback || '').trim() const variables = { id: Number(this.data.activityPlayerId), feedback: trimmedFeedback ? trimmedFeedback : null } const result = await graphqlRequest(mutation, variables) const success = result && (action === 'APPROVE' ? result.approveActivityPlayer : result.rejectActivityPlayer) if (success) { wx.showToast({ title: successText, icon: 'success' }) if (this.eventChannel) { this.eventChannel.emit('auditUpdated', { id: this.data.activityPlayerId }) } setTimeout(() => wx.navigateBack(), 600) } else { wx.showToast({ title: '操作失败', icon: 'none' }) } } catch (error) { console.error('提交审核决策失败:', error) wx.showToast({ title: '操作失败', icon: 'none' }) } finally { this.setData({ submitting: false }) } }, onMediaTap(e) { const index = Number(e.currentTarget.dataset.index) const mediaList = this.data.mediaList || [] const media = mediaList[index] if (!media) return if (media.mediaType === 'image') { const images = mediaList.filter(item => item.mediaType === 'image').map(item => item.url) wx.previewImage({ current: media.url, urls: images }) } else if (media.mediaType === 'video') { wx.navigateTo({ url: `/pages/video/video?url=${encodeURIComponent(media.url)}&title=${encodeURIComponent(media.name)}` }) } else { this.openDocumentMedia(media) } }, async openDocumentMedia(media) { try { wx.showLoading({ title: '打开中...' }) const downloadRes = await new Promise((resolve, reject) => { wx.downloadFile({ url: media.url, success: resolve, fail: reject }) }) if (downloadRes.statusCode !== 200) { throw new Error('文件下载失败') } await new Promise((resolve, reject) => { wx.openDocument({ filePath: downloadRes.tempFilePath, showMenu: true, success: resolve, fail: reject }) }) } catch (error) { console.error('打开文件失败:', error) wx.showToast({ title: '无法打开文件', icon: 'error' }) } finally { wx.hideLoading() } }, getFileSizeText(size) { if (!size || size <= 0) { return '未知大小' } if (size < 1024) { return `${size}B` } if (size < 1024 * 1024) { return `${(size / 1024).toFixed(1)}KB` } return `${(size / (1024 * 1024)).toFixed(1)}MB` }, getStateText(state) { switch (state) { case 0: return '未审核' case 1: return '审核通过' case 2: return '审核驳回' default: return '未知状态' } } })