修正上传文件名
This commit is contained in:
@@ -3,6 +3,6 @@
|
|||||||
* apiEnv 可选:'local' | 'prod'
|
* apiEnv 可选:'local' | 'prod'
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
apiEnv: 'prod'
|
apiEnv: 'local'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ export default {
|
|||||||
this.stopRecordingTicker();
|
this.stopRecordingTicker();
|
||||||
const tempFilePath = res.tempFilePath || '';
|
const tempFilePath = res.tempFilePath || '';
|
||||||
if (ctx && ctx.id) {
|
if (ctx && ctx.id) {
|
||||||
const name = `service_record_${ctx.id}_${Date.now()}_part${normalizedSegmentNo}.mp3`;
|
const name = this.getAudioUploadFileName({ segmentNo: normalizedSegmentNo });
|
||||||
if (!tempFilePath) {
|
if (!tempFilePath) {
|
||||||
this.pushUploadResult(String(ctx.id), {
|
this.pushUploadResult(String(ctx.id), {
|
||||||
id: `seg_${String(ctx.id)}_${normalizedSegmentNo}_${Date.now()}`,
|
id: `seg_${String(ctx.id)}_${normalizedSegmentNo}_${Date.now()}`,
|
||||||
@@ -1035,10 +1035,88 @@ export default {
|
|||||||
}
|
}
|
||||||
return headers;
|
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 = {}) {
|
async uploadFileForRecord(item, selectedFile, options = {}) {
|
||||||
const recordId = String(item.id);
|
const recordId = String(item.id);
|
||||||
const segmentNo = Number(options.segmentNo) || 1;
|
const segmentNo = Number(options.segmentNo) || 1;
|
||||||
const durationSeconds = Math.max(0, Number(options.durationSeconds) || 0);
|
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 fileSize = Math.max(0, Number(selectedFile?.size) || 0);
|
||||||
const resultId = `seg_${recordId}_${segmentNo}_${Date.now()}`;
|
const resultId = `seg_${recordId}_${segmentNo}_${Date.now()}`;
|
||||||
this.pushUploadResult(recordId, {
|
this.pushUploadResult(recordId, {
|
||||||
@@ -1051,20 +1129,26 @@ export default {
|
|||||||
message: '',
|
message: '',
|
||||||
});
|
});
|
||||||
this.increaseUploadingCount(recordId);
|
this.increaseUploadingCount(recordId);
|
||||||
|
let tempCopyPath = null;
|
||||||
try {
|
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;
|
const maxAttempt = options.retryOnceOnFail ? 2 : 1;
|
||||||
let lastErrorMessage = '';
|
let lastErrorMessage = '';
|
||||||
for (let attempt = 1; attempt <= maxAttempt; attempt += 1) {
|
for (let attempt = 1; attempt <= maxAttempt; attempt += 1) {
|
||||||
const uploadRes = await uni.uploadFile({
|
const uploadRes = await uni.uploadFile({
|
||||||
url: getApiUrl('/api/audio/upload'),
|
url: getApiUrl('/api/audio/upload'),
|
||||||
filePath: selectedFile.path,
|
filePath: uploadPath,
|
||||||
name: 'file',
|
name: 'file',
|
||||||
formData: {
|
formData: {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
audioId: item.id,
|
audioId: item.id,
|
||||||
|
audioDuration: audioDurationMinutesStr,
|
||||||
customerId: item.customerId || '',
|
customerId: item.customerId || '',
|
||||||
customerName: item.customerName || '',
|
customerName: item.customerName || '',
|
||||||
fileName: selectedFile.name || `service_file_${Date.now()}`,
|
fileName: targetFileName,
|
||||||
compress: true
|
compress: true
|
||||||
},
|
},
|
||||||
header: this.getAuthHeaders(),
|
header: this.getAuthHeaders(),
|
||||||
@@ -1110,6 +1194,7 @@ export default {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
|
this.safeUnlinkAudioCopy(tempCopyPath);
|
||||||
this.decreaseUploadingCount(recordId);
|
this.decreaseUploadingCount(recordId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
2
unpackage/dist/build/mp-weixin/common/env.js
vendored
2
unpackage/dist/build/mp-weixin/common/env.js
vendored
@@ -1 +1 @@
|
|||||||
"use strict";exports.envConfig={apiEnv:"prod"};
|
"use strict";exports.envConfig={apiEnv:"local"};
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user