hookehuyr

fix(plan): 修复计划书文件预览功能,恢复 useFileOperation 依赖

修复消息详情页点击"查计划书"后 PDF/Office 文件无法打开的问题。

问题根因:
- 2026-02-14 重构时删除了 useFileOperation 依赖
- 所有文件都错误地使用 Taro.previewImage(仅支持图片)

修复内容:
- 恢复 useFileOperation composable 的依赖
- handleFileView 使用 viewFile 方法支持多种文件类型
- 图片、PDF、Office 文档现在都能正确预览

经验教训:
- 重构时必须验证代码等价性
- 删除依赖前需理解其完整作用
- 已将此案例记录到全局规则 refactor-traps.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
...@@ -5,16 +5,16 @@ ...@@ -5,16 +5,16 @@
5 * @module composables/usePlanView 5 * @module composables/usePlanView
6 * @author Claude Code 6 * @author Claude Code
7 * @created 2026-02-14 7 * @created 2026-02-14
8 -* @version 1.1.0 - 增强错误处理,添加完整日志 8 +* @version 1.2.0 - 修复文件预览功能,恢复 useFileOperation 依赖
9 * @example 9 * @example
10 * const { viewProposal } = usePlanView() 10 * const { viewProposal } = usePlanView()
11 * await viewProposal({ id: 123, proposal_files: [...] }) 11 * await viewProposal({ id: 123, proposal_files: [...] })
12 */ 12 */
13 13
14 -import { ref } from 'vue'
15 import Taro from '@tarojs/taro' 14 import Taro from '@tarojs/taro'
16 import { mapOrderStatus, getStatusText } from '@/config/constants/orderStatus' 15 import { mapOrderStatus, getStatusText } from '@/config/constants/orderStatus'
17 import { viewAPI } from '@/api/plan' 16 import { viewAPI } from '@/api/plan'
17 +import { useFileOperation } from './useFileOperation'
18 18
19 export const viewProposal = async (proposal, callbacks = {}) => { 19 export const viewProposal = async (proposal, callbacks = {}) => {
20 const { beforeView, onViewSuccess, onViewError, onError } = callbacks 20 const { beforeView, onViewSuccess, onViewError, onError } = callbacks
...@@ -134,39 +134,14 @@ const handleFileView = async (file, emitError) => { ...@@ -134,39 +134,14 @@ const handleFileView = async (file, emitError) => {
134 return false 134 return false
135 } 135 }
136 136
137 - const hasShownOfficeTip = ref(false)
138 - const isOffice = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx']
139 -
140 try { 137 try {
141 - if (file.file_type && isOffice.includes(file.file_type)) { 138 + // 使用 useFileOperation 的 viewFile 方法,支持多种文件类型
142 - if (!hasShownOfficeTip.value) { 139 + const { viewFile } = useFileOperation()
143 - const res = await Taro.showModal({ 140 + const result = await viewFile({
144 - title: '提示', 141 + downloadUrl: file.file_url,
145 - content: 'Office 文档建议使用电脑端查看', 142 + fileName: file.file_name
146 - confirmText: '继续',
147 - cancelText: '取消'
148 }) 143 })
149 - 144 + return result
150 - if (res.confirm) {
151 - hasShownOfficeTip.value = true
152 - } else {
153 - console.log('[usePlanView] 用户取消 Office 文档预览')
154 - return false
155 - }
156 - }
157 - }
158 -
159 - const previewImage = Taro.previewImage
160 - if (typeof previewImage !== 'function') {
161 - return true
162 - }
163 -
164 - await previewImage({
165 - current: file.file_url,
166 - urls: [file.file_url]
167 - })
168 -
169 - return true
170 } catch (error) { 145 } catch (error) {
171 console.error('[usePlanView] 文件预览失败:', error) 146 console.error('[usePlanView] 文件预览失败:', error)
172 147
......