| | |
| | | <view class="detail-section"> |
| | | <view class="section-title"> |
| | | {{ title }} |
| | | <button class="upload-btn" @click="showUploadDialog">上传附件</button> |
| | | <button class="upload-btn" @click="showUploadDialog" v-if="!readonly">上传附件</button> |
| | | </view> |
| | | <view v-if="attachmentList && attachmentList.length > 0"> |
| | | <view class="attachment-item" v-for="(item, index) in attachmentList" :key="item.attachmentId"> |
| | |
| | | </view> |
| | | <view class="attachment-actions"> |
| | | <button class="action-btn view-btn" @click="viewAttachment(item)">查看</button> |
| | | <button class="action-btn delete-btn" @click="deleteAttachment(item.attachmentId, index)">删除</button> |
| | | <button class="action-btn delete-btn" @click="deleteAttachment(item.attachmentId, index)" v-if="!readonly">删除</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getAttachmentList, uploadAttachmentFromWechat, deleteAttachment, getWechatAccessToken } from '@/api/task' |
| | | import { getAttachmentList, deleteAttachment } from '@/api/task' |
| | | import { formatDateTime } from '@/utils/common' |
| | | import { getToken } from '@/utils/auth' |
| | | import config from '@/config' |
| | | |
| | | export default { |
| | | name: 'AttachmentUpload', |
| | |
| | | autoLoad: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 是否只读模式(禁止上传和删除) |
| | | readonly: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | |
| | | { label: '系安全带', value: '6' } |
| | | ], |
| | | selectedCategoryIndex: 0, |
| | | tempImagePath: null, |
| | | isWechatMiniProgram: false |
| | | tempImagePath: null |
| | | } |
| | | }, |
| | | mounted() { |
| | | // 检测是否是微信小程序环境 |
| | | // #ifdef MP-WEIXIN |
| | | this.isWechatMiniProgram = true |
| | | // #endif |
| | | |
| | | // 自动加载附件列表 |
| | | if (this.autoLoad && this.taskId) { |
| | | this.loadAttachmentList() |
| | |
| | | const that = this |
| | | const category = this.categoryList[this.selectedCategoryIndex].value |
| | | |
| | | // 微信小程序环境:先获取AccessToken,再上传到微信服务器,最后提交mediaId到后端 |
| | | // #ifdef MP-WEIXIN |
| | | if (this.isWechatMiniProgram) { |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }) |
| | | |
| | | // 第一步:从后端获取AccessToken |
| | | getWechatAccessToken().then(tokenResponse => { |
| | | // 接口返回格式:{"msg":"token值","code":200} |
| | | console.log('获取AccessToken成功:', tokenResponse) |
| | | const accessToken = tokenResponse.msg || tokenResponse.data || tokenResponse |
| | | if (!accessToken) { |
| | | uni.hideLoading() |
| | | that.$modal.showToast('获取AccessToken失败') |
| | | console.error('获取AccessToken失败,响应数据:', tokenResponse) |
| | | return |
| | | } |
| | | |
| | | console.log('获取到AccessToken:', accessToken) |
| | | |
| | | // 第二步:上传到微信服务器 |
| | | const uploadUrl = `https://api.weixin.qq.com/cgi-bin/media/upload?access_token=${accessToken}&type=image` |
| | | |
| | | uni.uploadFile({ |
| | | url: uploadUrl, |
| | | filePath: that.tempImagePath, |
| | | name: 'media', |
| | | success: function(res) { |
| | | console.log('微信上传响应:', res) |
| | | try { |
| | | const data = JSON.parse(res.data) |
| | | if (data.media_id) { |
| | | // 第三步:提交mediaId到后端 |
| | | uploadAttachmentFromWechat(that.taskId, data.media_id, category).then(response => { |
| | | uni.hideLoading() |
| | | that.$modal.showToast('上传成功') |
| | | that.closeUploadDialog() |
| | | that.loadAttachmentList() |
| | | that.$emit('uploaded', response) |
| | | }).catch(error => { |
| | | uni.hideLoading() |
| | | console.error('提交mediaId失败:', error) |
| | | that.$modal.showToast('上传失败:' + (error.msg || '请重试')) |
| | | that.$emit('error', error) |
| | | }) |
| | | } else { |
| | | uni.hideLoading() |
| | | const errMsg = data.errmsg || '未知错误' |
| | | console.error('微信返回错误:', data) |
| | | that.$modal.showToast('微信上传失败:' + errMsg) |
| | | } |
| | | } catch (e) { |
| | | uni.hideLoading() |
| | | console.error('解析微信响应失败:', e, res.data) |
| | | that.$modal.showToast('上传失败:响应解析错误') |
| | | } |
| | | }, |
| | | fail: function(err) { |
| | | uni.hideLoading() |
| | | console.error('上传到微信失败:', err) |
| | | that.$modal.showToast('上传失败:' + (err.errMsg || '请检查网络')) |
| | | that.$emit('error', err) |
| | | } |
| | | }) |
| | | }).catch(error => { |
| | | uni.hideLoading() |
| | | console.error('获取AccessToken失败:', error) |
| | | that.$modal.showToast('获取AccessToken失败') |
| | | that.$emit('error', error) |
| | | }) |
| | | return |
| | | } |
| | | // #endif |
| | | |
| | | // 非微信小程序环境:直接上传到后端服务器 |
| | | // 统一直接上传到后端服务器 |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }) |
| | | |
| | | uni.uploadFile({ |
| | | url: that.$baseUrl + '/task/attachment/upload/' + that.taskId, |
| | | url: config.baseUrl + '/task/attachment/upload/' + that.taskId, |
| | | filePath: that.tempImagePath, |
| | | name: 'file', |
| | | formData: { |
| | | 'category': category |
| | | }, |
| | | header: { |
| | | 'Authorization': 'Bearer ' + uni.getStorageSync('token') |
| | | 'Authorization': 'Bearer ' + getToken() |
| | | }, |
| | | success: function(uploadRes) { |
| | | uni.hideLoading() |
| | |
| | | fail: function(err) { |
| | | uni.hideLoading() |
| | | console.error('上传失败:', err) |
| | | that.$modal.showToast('上传失败') |
| | | that.$modal.showToast('上传失败:' + (err.errMsg || '请检查网络')) |
| | | that.$emit('error', err) |
| | | } |
| | | }) |
| | |
| | | let imageUrl = item.fileUrl |
| | | // 如果没有fileUrl,则使用下载接口 |
| | | if (!imageUrl) { |
| | | imageUrl = this.$baseUrl + '/task/attachment/download/' + item.attachmentId |
| | | imageUrl = config.baseUrl + '/task/attachment/download/' + item.attachmentId |
| | | } |
| | | |
| | | // 微信小程序中预览图片 |
| | |
| | | } |
| | | // 使用下载接口 |
| | | if (item.attachmentId) { |
| | | return this.$baseUrl + '/task/attachment/download/' + item.attachmentId |
| | | return config.baseUrl + '/task/attachment/download/' + item.attachmentId |
| | | } |
| | | // 默认占位图 |
| | | return '/static/images/default-image.png' |