wlzboy
2025-11-22 fd047fa7234dc11643dab8ecbf38e8d7a8ba0854
app/components/AttachmentUpload.vue
@@ -3,7 +3,7 @@
    <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">
@@ -20,7 +20,7 @@
          </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>
@@ -67,8 +67,10 @@
</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',
@@ -87,6 +89,11 @@
      autoLoad: {
        type: Boolean,
        default: true
      },
      // 是否只读模式(禁止上传和删除)
      readonly: {
        type: Boolean,
        default: false
      }
    },
    data() {
@@ -101,16 +108,10 @@
          { 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()
@@ -184,95 +185,20 @@
        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()
@@ -296,7 +222,7 @@
          fail: function(err) {
            uni.hideLoading()
            console.error('上传失败:', err)
            that.$modal.showToast('上传失败')
            that.$modal.showToast('上传失败:' + (err.errMsg || '请检查网络'))
            that.$emit('error', err)
          }
        })
@@ -313,7 +239,7 @@
          let imageUrl = item.fileUrl
          // 如果没有fileUrl,则使用下载接口
          if (!imageUrl) {
            imageUrl = this.$baseUrl + '/task/attachment/download/' + item.attachmentId
            imageUrl = config.baseUrl + '/task/attachment/download/' + item.attachmentId
          }
          
          // 微信小程序中预览图片
@@ -400,7 +326,7 @@
        }
        // 使用下载接口
        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'