修正上传文件名

This commit is contained in:
zhonghua.li
2026-04-19 15:34:16 +08:00
parent f05a85bc1c
commit 15c554a7c2
6 changed files with 93 additions and 8 deletions

View File

@@ -401,7 +401,7 @@ export default {
this.stopRecordingTicker();
const tempFilePath = res.tempFilePath || '';
if (ctx && ctx.id) {
const name = `service_record_${ctx.id}_${Date.now()}_part${normalizedSegmentNo}.mp3`;
const name = this.getAudioUploadFileName({ segmentNo: normalizedSegmentNo });
if (!tempFilePath) {
this.pushUploadResult(String(ctx.id), {
id: `seg_${String(ctx.id)}_${normalizedSegmentNo}_${Date.now()}`,
@@ -1035,10 +1035,88 @@ export default {
}
return headers;
},
/** 上传音频文件名租户id_手机号_年月日时分秒租户id、手机号后各有一个下划线多段录音段号>1 时末尾再追加 _段号 */
getAudioUploadFileName(options = {}) {
let tenantId = '';
let phone = '';
try {
tenantId = String(uni.getStorageSync('backend-tenant-id') || '').trim();
} catch (e) {}
try {
const raw = this.currentUserPhone || '';
const login = uni.getStorageSync('backend-login-response') || {};
const fallback = login.phone || login.userName || '';
phone = String(raw || fallback || '').replace(/\D/g, '');
} catch (e) {}
const d = new Date();
const pad = (n) => String(n).padStart(2, '0');
const ts = `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
const seg = Number(options.segmentNo);
const segSuffix = Number.isFinite(seg) && seg > 1 ? `_${seg}` : '';
const ext = typeof options.ext === 'string' && options.ext ? options.ext : '.mp3';
const dotExt = ext.startsWith('.') ? ext : `.${ext}`;
const tenantPrefix = tenantId ? `${tenantId}_` : '';
const phonePrefix = phone ? `${phone}_` : '';
const base = `${tenantPrefix}${phonePrefix}${ts}${segSuffix}`.replace(/[/\\:*?"<>|]/g, '_') || `upload_${ts}${segSuffix}`;
return `${base}${dotExt}`;
},
/**
* 微信小程序等环境下 multipart 的原始文件名来自本地路径最后一段;临时路径常为随机串甚至带异常后缀。
* 复制到 USER_DATA_PATH 并使用规范文件名再上传,后端 getOriginalFilename / 落盘名才能与 fileName 参数一致。
*/
prepareAudioFileForUpload(tempPath, displayFileName) {
return new Promise((resolve) => {
if (!tempPath || !displayFileName) {
resolve({ uploadPath: tempPath, tempCopyPath: null });
return;
}
const baseName = (() => {
const seg = String(tempPath).split(/[/\\]/).pop() || '';
return seg.split('?')[0] || '';
})();
const needsRename =
baseName !== displayFileName ||
baseName.includes('=') ||
/\.durationTime=/i.test(baseName);
let userDataPath = '';
try {
userDataPath = (uni.env && uni.env.USER_DATA_PATH) || '';
} catch (e) {}
if (!userDataPath && typeof wx !== 'undefined' && wx.env) {
userDataPath = wx.env.USER_DATA_PATH || '';
}
if (!needsRename || !userDataPath || typeof uni.getFileSystemManager !== 'function') {
resolve({ uploadPath: tempPath, tempCopyPath: null });
return;
}
const destPath = `${String(userDataPath).replace(/\/+$/, '')}/${displayFileName}`;
uni.getFileSystemManager().copyFile({
srcPath: tempPath,
destPath,
success: () => resolve({ uploadPath: destPath, tempCopyPath: destPath }),
fail: (err) => {
console.warn('prepareAudioFileForUpload copyFile failed:', err);
resolve({ uploadPath: tempPath, tempCopyPath: null });
},
});
});
},
safeUnlinkAudioCopy(filePath) {
if (!filePath || typeof uni.getFileSystemManager !== 'function') {
return;
}
try {
uni.getFileSystemManager().unlink({ filePath, fail: () => {} });
} catch (e) {}
},
async uploadFileForRecord(item, selectedFile, options = {}) {
const recordId = String(item.id);
const segmentNo = Number(options.segmentNo) || 1;
const durationSeconds = Math.max(0, Number(options.durationSeconds) || 0);
const audioDurationMinutesStr = (() => {
const m = durationSeconds / 60;
return Number.isFinite(m) ? String(Math.round(m * 1e6) / 1e6) : '0';
})();
const fileSize = Math.max(0, Number(selectedFile?.size) || 0);
const resultId = `seg_${recordId}_${segmentNo}_${Date.now()}`;
this.pushUploadResult(recordId, {
@@ -1051,20 +1129,26 @@ export default {
message: '',
});
this.increaseUploadingCount(recordId);
let tempCopyPath = null;
try {
const targetFileName = this.getAudioUploadFileName({ segmentNo });
const prep = await this.prepareAudioFileForUpload(selectedFile.path, targetFileName);
const uploadPath = prep.uploadPath;
tempCopyPath = prep.tempCopyPath;
const maxAttempt = options.retryOnceOnFail ? 2 : 1;
let lastErrorMessage = '';
for (let attempt = 1; attempt <= maxAttempt; attempt += 1) {
const uploadRes = await uni.uploadFile({
url: getApiUrl('/api/audio/upload'),
filePath: selectedFile.path,
filePath: uploadPath,
name: 'file',
formData: {
id: item.id,
audioId: item.id,
audioDuration: audioDurationMinutesStr,
customerId: item.customerId || '',
customerName: item.customerName || '',
fileName: selectedFile.name || `service_file_${Date.now()}`,
fileName: targetFileName,
compress: true
},
header: this.getAuthHeaders(),
@@ -1110,6 +1194,7 @@ export default {
});
return false;
} finally {
this.safeUnlinkAudioCopy(tempCopyPath);
this.decreaseUploadingCount(recordId);
}
},