fix: 修复报告页

This commit is contained in:
MaDaLei 2026-04-17 14:11:26 +08:00
parent c22250ba53
commit c14767db90

View File

@ -183,7 +183,7 @@
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { onPageScroll } from '@dcloudio/uni-app'
import { createReport, getServiceTypeList, imgUrl, BASE_URL } from '../../api/index.js'
import AppIcon from '../../components/AppIcon.vue'
@ -305,6 +305,18 @@ const setUploadFail = (item, reason) => {
item.error = reason || '上传失败'
}
/**
* 微信小程序异步上传回调里改嵌套字段后界面偶发不刷新点别处才更新
* nextTick + 浅拷贝换数组引用强制重绘缩略图上的遮罩
*/
async function pokeMediaList(field) {
if (!field || !Array.isArray(report.value[field])) return
await nextTick()
report.value[field] = report.value[field].map((row) => ({ ...row }))
await nextTick()
await new Promise((r) => setTimeout(r, 16))
}
/** 微信端 uploadFilestatusCode 可能为字符串或缺失;须按 2xx 判断 */
function uploadHttpOk(sc) {
if (sc == null || sc === '') return true
@ -315,7 +327,18 @@ function uploadHttpOk(sc) {
function parseUploadJson(raw) {
if (raw == null || raw === '') return null
if (typeof raw === 'object' && !Array.isArray(raw)) return raw
if (typeof raw === 'object') {
if (Array.isArray(raw)) return null
if (typeof ArrayBuffer !== 'undefined' && raw instanceof ArrayBuffer) {
const s = new TextDecoder('utf-8', { fatal: false }).decode(raw)
return parseUploadJson(s)
}
if (typeof Uint8Array !== 'undefined' && raw instanceof Uint8Array) {
const s = new TextDecoder('utf-8', { fatal: false }).decode(raw)
return parseUploadJson(s)
}
return raw
}
const s = String(raw).replace(/^\uFEFF/, '').trim()
if (!s) return null
try {
@ -325,6 +348,22 @@ function parseUploadJson(raw) {
}
}
/** 编码异常或解析失败时,用正则从纯 ASCII 字段恢复 url不依赖 message */
function parseUploadFallback(raw) {
const s =
typeof raw === 'string'
? raw
: typeof raw === 'object' && raw !== null && typeof raw.toString === 'function'
? raw.toString()
: ''
const codeM = s.match(/"code"\s*:\s*(\d+)/)
const urlM = s.match(/"url"\s*:\s*"(\/api\/upload\/image\/[^"]*)"/)
if (codeM && Number(codeM[1]) === 200 && urlM) {
return { code: 200, data: { url: urlM[1] } }
}
return null
}
function extractUploadedUrl(data) {
if (!data || typeof data !== 'object') return ''
const inner = data.data
@ -363,8 +402,15 @@ const uploadSingleFile = (filePath) =>
done({ ok: false, message: friendlyUploadError(`HTTP ${uploadRes.statusCode}`) })
return
}
const data = parseUploadJson(uploadRes.data)
const serverUrl = extractUploadedUrl(data)
let data = parseUploadJson(uploadRes.data)
let serverUrl = extractUploadedUrl(data)
if (!data || !isBizSuccess(data) || !serverUrl) {
const fb = parseUploadFallback(uploadRes.data)
if (fb) {
data = fb
serverUrl = extractUploadedUrl(data)
}
}
if (isBizSuccess(data) && serverUrl) {
done({ ok: true, url: serverUrl })
return
@ -414,6 +460,7 @@ const retryUpload = async (field, idx) => {
setUploadFail(item, r.message)
uni.showToast({ title: `重试失败:${r.message}`.slice(0, 36), icon: 'none' })
}
await pokeMediaList(field)
}
const uploadPhoto = (field) => {
@ -442,6 +489,7 @@ const uploadPhoto = (field) => {
if (!firstReason) firstReason = r.message
setUploadFail(item, r.message)
}
await pokeMediaList(field)
}
uni.hideLoading()
if (failCount > 0) showBatchUploadFail(failCount, firstReason)
@ -479,6 +527,7 @@ const uploadVideo = (field) => {
failCount++
if (!firstReason) firstReason = `视频请不超过${MAX_VIDEO_MB}MB`
setUploadFail(item, `视频请不超过${MAX_VIDEO_MB}MB`)
await pokeMediaList(field)
continue
}
const r = await uploadSingleFile(f.tempFilePath)
@ -489,6 +538,7 @@ const uploadVideo = (field) => {
if (!firstReason) firstReason = r.message
setUploadFail(item, r.message)
}
await pokeMediaList(field)
}
uni.hideLoading()
if (failCount > 0) showBatchUploadFail(failCount, firstReason)
@ -539,6 +589,7 @@ const uploadDuring = () => {
failCount++
if (!firstReason) firstReason = `视频请不超过${MAX_VIDEO_MB}MB`
setUploadFail(item, `视频请不超过${MAX_VIDEO_MB}MB`)
await pokeMediaList('duringMedia')
continue
}
}
@ -551,6 +602,7 @@ const uploadDuring = () => {
if (!firstReason) firstReason = r.message
setUploadFail(item, r.message)
}
await pokeMediaList('duringMedia')
}
uni.hideLoading()
if (failCount > 0) showBatchUploadFail(failCount, firstReason)