Browse Source

mrb优化

master
fengyuan_yang 3 weeks ago
parent
commit
59ac16336d
  1. 56
      cclqms-vue/src/utils/filePreview.js
  2. 8
      cclqms-vue/src/views/modules/mrb/mrbRecord.vue
  3. 8
      cclqms-vue/src/views/modules/oss/ossComponents.vue

56
cclqms-vue/src/utils/filePreview.js

@ -10,7 +10,8 @@ const FILE_TYPES = {
video: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv', 'ogg'],
audio: ['mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a', 'wma'],
pdf: ['pdf'],
txt: ['txt', 'log', 'json', 'xml', 'csv', 'html', 'htm', 'css', 'js'],
txt: ['txt', 'log', 'json', 'xml', 'html', 'htm', 'css', 'js'],
csv: ['csv'],
excel: ['xls', 'xlsx'],
word: ['doc', 'docx'],
ppt: ['ppt', 'pptx']
@ -512,6 +513,51 @@ function safeSheetToHtml(worksheet, options = {}) {
}
}
/**
* 解码CSV内容兼容UTF-8 BOM和常见中文编码
*/
async function decodeCsvBlob (blobData) {
const buffer = blobData instanceof Blob ? await blobToArrayBuffer(blobData) : blobData
const bytes = new Uint8Array(buffer)
let offset = 0
if (bytes.length >= 3 && bytes[0] === 0xEF && bytes[1] === 0xBB && bytes[2] === 0xBF) {
offset = 3
}
const slice = bytes.subarray(offset)
const utf8Text = new TextDecoder('utf-8').decode(slice)
if (utf8Text.indexOf('\uFFFD') === -1) {
return utf8Text
}
try {
return new TextDecoder('gb18030').decode(slice)
} catch (error) {
return utf8Text
}
}
/**
* 预览CSV文件按表格展示失败时回退为纯文本
*/
export async function previewCsv (blobData, fileName) {
try {
const csvText = await decodeCsvBlob(blobData)
const workbook = XLSX.read(csvText, { type: 'string' })
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' })
if (previewExcel(excelBuffer, fileName)) {
return true
}
const textBlob = new Blob([csvText], { type: 'text/plain;charset=utf-8' })
return previewText(textBlob, fileName)
} catch (error) {
console.error('CSV预览失败:', error)
try {
return await previewText(blobData, fileName)
} catch (textError) {
return false
}
}
}
/**
* 预览Excel文件
* @param {ArrayBuffer} arrayBuffer - 文件数据ArrayBuffer格式
@ -688,6 +734,13 @@ export async function previewFile(data, fileName) {
} else {
throw new Error('文本预览失败')
}
case 'csv':
if (await previewCsv(blobData, fileName)) {
return { success: true, type: 'csv' }
} else {
throw new Error('CSV预览失败')
}
case 'excel':
// Excel文件需要ArrayBuffer格式
@ -733,6 +786,7 @@ export default {
previewAudio,
previewPDF,
previewText,
previewCsv,
previewExcel,
previewWord,
previewPPT,

8
cclqms-vue/src/views/modules/mrb/mrbRecord.vue

@ -3744,7 +3744,7 @@ export default {
if (extension === 'pdf') {
return 'application/pdf;charset=UTF-8'
}
if (extension === 'txt') {
if (extension === 'txt' || extension === 'csv') {
return 'text/plain;charset=utf-8'
}
return 'application/octet-stream'
@ -3763,12 +3763,16 @@ export default {
this.$message.warning(this.$t('mrb.message.filePreviewUnsupported'))
return
}
const supportPreviewTypeList = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'txt', 'pdf', 'xls', 'xlsx', 'docx']
const supportPreviewTypeList = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'txt', 'csv', 'pdf', 'xls', 'xlsx', 'docx']
if (!supportPreviewTypeList.includes(fileType)) {
this.$message.warning(this.$t('mrb.message.filePreviewUnsupported'))
return
}
previewOssFileById({ id: row.id }).then(({ data }) => {
if (fileType === 'csv') {
const fileName = String((row && (row.fileName || row.newFileName)) || 'preview.csv')
return this.$filePreview.previewFile(data, fileName.toLowerCase().endsWith('.csv') ? fileName : `${fileName}.csv`)
}
const blob = new Blob([data], { type: this.resolvePreviewMimeType(fileType) })
const fileURL = URL.createObjectURL(blob)
if (fileType === 'xls' || fileType === 'xlsx' || fileType === 'docx') {

8
cclqms-vue/src/views/modules/oss/ossComponents.vue

@ -403,7 +403,7 @@ export default {
if (extension === 'pdf') {
return 'application/pdf;charset=UTF-8'
}
if (extension === 'txt') {
if (extension === 'txt' || extension === 'csv') {
return 'text/plain;charset=utf-8'
}
return 'application/octet-stream'
@ -422,12 +422,16 @@ export default {
this.$message.warning('该文件格式暂不支持预览')
return
}
const supportPreviewTypeList = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'txt', 'pdf', 'xls', 'xlsx', 'docx']
const supportPreviewTypeList = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm', 'txt', 'csv', 'pdf', 'xls', 'xlsx', 'docx']
if (!supportPreviewTypeList.includes(fileType)) {
this.$message.warning('该文件格式暂不支持预览')
return
}
this.requestFileBlob(row.id).then(({ data }) => {
if (fileType === 'csv') {
const fileName = String((row && (row.fileName || row.newFileName)) || 'preview.csv')
return this.$filePreview.previewFile(data, fileName.toLowerCase().endsWith('.csv') ? fileName : `${fileName}.csv`)
}
const blob = new Blob([data], { type: this.resolvePreviewMimeType(fileType) })
const fileURL = URL.createObjectURL(blob)
if (fileType === 'xls' || fileType === 'xlsx' || fileType === 'docx') {

Loading…
Cancel
Save