文件上传
This commit is contained in:
parent
2000837d10
commit
7c31fc85a9
|
|
@ -74,15 +74,21 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
files: this.fileList,
|
files: [...this.fileList], // 使用展开运算符创建新数组
|
||||||
previewImageUrl: '',
|
previewImageUrl: '',
|
||||||
previewImageName: '',
|
previewImageName: '',
|
||||||
previewFileName: '',
|
previewFileName: '',
|
||||||
previewFileType: ''
|
previewFileType: '',
|
||||||
|
isUploading: false // 添加上传状态标识
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
beforeUpload(file) {
|
beforeUpload(file) {
|
||||||
|
// 如果正在上传中,阻止新的上传
|
||||||
|
if (this.isUploading) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// 验证文件类型
|
// 验证文件类型
|
||||||
const fileExtension = file.name.split('.').pop().toLowerCase();
|
const fileExtension = file.name.split('.').pop().toLowerCase();
|
||||||
const isAllowedType = this.allowedTypes.includes(fileExtension);
|
const isAllowedType = this.allowedTypes.includes(fileExtension);
|
||||||
|
|
@ -107,7 +113,13 @@ export default {
|
||||||
},
|
},
|
||||||
// 文件状态改变
|
// 文件状态改变
|
||||||
handleFileChange(file, fileList) {
|
handleFileChange(file, fileList) {
|
||||||
this.files = fileList;
|
// 如果文件状态是移除或失败,不处理
|
||||||
|
if (file.status === 'removed' || file.status === 'fail') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 不使用深拷贝,直接使用 fileList,但确保 files 是响应式的
|
||||||
|
this.files = this.formatFileList(fileList);
|
||||||
|
|
||||||
// 生成预览
|
// 生成预览
|
||||||
if (file.raw && fileList.length === 1) {
|
if (file.raw && fileList.length === 1) {
|
||||||
|
|
@ -122,41 +134,180 @@ export default {
|
||||||
// 如果不是单个文件,清除预览
|
// 如果不是单个文件,清除预览
|
||||||
this.clearPreview();
|
this.clearPreview();
|
||||||
}
|
}
|
||||||
console.log('文件列表更新:', this.files.length, '个文件');
|
|
||||||
// this.$emit('file-change', this.files);
|
|
||||||
|
|
||||||
// 如果启用自动上传且文件验证通过,触发上传
|
// 如果启用自动上传且文件验证通过,触发上传
|
||||||
if (this.autoUpload && file.status === 'ready') {
|
if (this.autoUpload && file.status === 'ready' && !this.isUploading) {
|
||||||
|
if (this.fileUploadRule.fields_json) {
|
||||||
if(Object.keys(this.fileUploadRule).length !== 0){
|
|
||||||
// 文件需要ocr识别
|
// 文件需要ocr识别
|
||||||
this.uploadFile(file, '识别中');
|
this.uploadFile(file, '识别中');
|
||||||
} else {
|
} else {
|
||||||
// 文件不需要ocr识别
|
// 文件不需要ocr识别
|
||||||
this.uploadFile(file, '上传中');
|
this.uploadFile(file, '上传中');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 格式化文件列表,确保数据结构正确
|
||||||
|
formatFileList(fileList) {
|
||||||
|
return fileList.map(file => {
|
||||||
|
// 创建一个标准的文件对象
|
||||||
|
const formattedFile = {
|
||||||
|
uid: file.uid,
|
||||||
|
name: file.name,
|
||||||
|
size: file.size,
|
||||||
|
type: file.type,
|
||||||
|
status: file.status,
|
||||||
|
raw: file.raw
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确保 percentage 属性存在且有效
|
||||||
|
if (file.percentage !== undefined && file.percentage !== null) {
|
||||||
|
formattedFile.percentage = Math.max(0, Math.min(100, file.percentage));
|
||||||
|
} else if (file.status === 'uploading') {
|
||||||
|
formattedFile.percentage = 0;
|
||||||
|
} else if (file.status === 'success') {
|
||||||
|
formattedFile.percentage = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留其他可能存在的属性
|
||||||
|
if (file.response) {
|
||||||
|
formattedFile.response = file.response;
|
||||||
|
formattedFile.url = file.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.statusText) {
|
||||||
|
formattedFile.statusText = file.statusText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedFile;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// 上传文件
|
// 上传文件
|
||||||
uploadFile(file,text){
|
async uploadFile(file, text) {
|
||||||
console.log(file);
|
// 设置上传状态
|
||||||
this.$bus.$emit('startUpload', text);
|
this.isUploading = true;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file.raw);
|
formData.append('file', file.raw);
|
||||||
formData.append('params', JSON.stringify(this.fileUploadRule));
|
formData.append('params', JSON.stringify(this.fileUploadRule));
|
||||||
uploadSmallFileByOcr(formData).then(res => {
|
// 更新文件状态为上传中,并设置初始进度为 0
|
||||||
console.log(res);
|
this.updateFileStatus(file.uid, 'uploading', text, null, 0);
|
||||||
this.$message.success(res.msg);
|
try {
|
||||||
|
this.$bus.$emit('startUpload', text);
|
||||||
|
const res = await uploadSmallFileByOcr(formData);
|
||||||
|
console.log('上传成功:', res);
|
||||||
this.$bus.$emit('endUpload');
|
this.$bus.$emit('endUpload');
|
||||||
}).catch(err => {
|
// 上传成功,更新文件状态,设置进度为 100
|
||||||
this.$message.error(err.msg);
|
this.updateFileStatus(file.uid, 'success', '', res.data, 100);
|
||||||
|
console.log('上传成功后的文件列表:', this.files);
|
||||||
|
// 触发文件变化事件,传递当前的文件列表
|
||||||
|
this.$emit('file-change', this.getCurrentFiles());
|
||||||
|
} catch (err) {
|
||||||
this.$bus.$emit('endUpload');
|
this.$bus.$emit('endUpload');
|
||||||
})
|
// 上传失败,移除文件
|
||||||
|
this.removeFailedFile(file.uid);
|
||||||
|
} finally {
|
||||||
|
// 无论成功失败,都重置上传状态
|
||||||
|
this.isUploading = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 移除上传失败的文件
|
||||||
|
removeFailedFile(fileUid) {
|
||||||
|
console.log('移除上传失败的文件:', fileUid);
|
||||||
|
const fileIndex = this.files.findIndex(item => item.uid === fileUid);
|
||||||
|
if (fileIndex !== -1) {
|
||||||
|
// 从文件列表中移除
|
||||||
|
this.files.splice(fileIndex, 1);
|
||||||
|
console.log('移除失败文件后的文件列表:', this.files);
|
||||||
|
|
||||||
|
// 清除预览
|
||||||
|
this.clearPreview();
|
||||||
|
|
||||||
|
// 触发文件变化事件
|
||||||
|
this.$emit('file-change', this.getCurrentFiles());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新文件状态
|
||||||
|
updateFileStatus(fileUid, status, statusText, responseData = null, percentage = null) {
|
||||||
|
console.log('更新文件状态:', fileUid, status, statusText, '进度:', percentage);
|
||||||
|
console.log('更新前的文件列表:', this.files);
|
||||||
|
|
||||||
|
const fileIndex = this.files.findIndex(item => item.uid === fileUid);
|
||||||
|
if (fileIndex !== -1) {
|
||||||
|
const updatedFile = {
|
||||||
|
...this.files[fileIndex],
|
||||||
|
status: status
|
||||||
|
};
|
||||||
|
|
||||||
|
if (statusText) {
|
||||||
|
updatedFile.statusText = statusText;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保 percentage 是有效的数字(0-100)
|
||||||
|
if (percentage !== null && percentage >= 0 && percentage <= 100) {
|
||||||
|
updatedFile.percentage = percentage;
|
||||||
|
} else if (status === 'uploading') {
|
||||||
|
// 上传中状态默认设置进度为 0
|
||||||
|
updatedFile.percentage = 0;
|
||||||
|
} else if (status === 'success') {
|
||||||
|
// 成功状态设置进度为 100
|
||||||
|
updatedFile.percentage = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseData) {
|
||||||
|
// 保存服务器返回的文件信息
|
||||||
|
updatedFile.response = responseData;
|
||||||
|
updatedFile.response.businessType = this.fileUploadRule?.fileUploadType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 Vue.set 确保响应式更新
|
||||||
|
this.$set(this.files, fileIndex, updatedFile);
|
||||||
|
|
||||||
|
console.log('更新后的文件列表:', this.files);
|
||||||
|
} else {
|
||||||
|
console.warn('未找到要更新的文件:', fileUid);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取当前文件列表(确保是普通数组)
|
||||||
|
getCurrentFiles() {
|
||||||
|
const currentFiles = this.files.map(file => {
|
||||||
|
const fileObj = {
|
||||||
|
uid: file.uid,
|
||||||
|
name: file.name,
|
||||||
|
size: file.size,
|
||||||
|
type: file.type,
|
||||||
|
status: file.status
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确保 percentage 存在
|
||||||
|
if (file.percentage !== undefined) {
|
||||||
|
fileObj.percentage = file.percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留原始文件对象(如果存在)
|
||||||
|
if (file.raw) {
|
||||||
|
fileObj.raw = file.raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果文件已上传成功,添加服务器返回的信息
|
||||||
|
if (file.response) {
|
||||||
|
fileObj.response = file.response;
|
||||||
|
fileObj.response.businessType = this.fileUploadRule?.fileUploadType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileObj;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('getCurrentFiles 返回:', currentFiles);
|
||||||
|
return currentFiles;
|
||||||
|
},
|
||||||
|
|
||||||
// 处理文件超出限制
|
// 处理文件超出限制
|
||||||
handleExceed(files, fileList) {
|
handleExceed(files, fileList) {
|
||||||
|
console.log('文件超出限制处理');
|
||||||
// 当文件数量超出限制时,用新文件替换旧文件
|
// 当文件数量超出限制时,用新文件替换旧文件
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
// 清空原有文件列表
|
// 清空原有文件列表
|
||||||
|
|
@ -166,13 +317,15 @@ export default {
|
||||||
const newFile = files[0];
|
const newFile = files[0];
|
||||||
this.beforeUpload(newFile); // 先进行验证
|
this.beforeUpload(newFile); // 先进行验证
|
||||||
|
|
||||||
// 创建新的文件对象
|
// 创建新的文件对象,确保包含 percentage
|
||||||
const newFileObj = {
|
const newFileObj = {
|
||||||
name: newFile.name,
|
name: newFile.name,
|
||||||
size: newFile.size,
|
size: newFile.size,
|
||||||
type: newFile.type,
|
type: newFile.type,
|
||||||
raw: newFile,
|
raw: newFile,
|
||||||
uid: Date.now() // 生成新的uid
|
uid: Date.now(), // 生成新的uid
|
||||||
|
status: 'ready',
|
||||||
|
percentage: 0 // 添加默认进度
|
||||||
};
|
};
|
||||||
|
|
||||||
// 更新文件列表
|
// 更新文件列表
|
||||||
|
|
@ -185,13 +338,36 @@ export default {
|
||||||
this.generateDocumentPreview(newFile);
|
this.generateDocumentPreview(newFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('file-change', this.files);
|
console.log('handleExceed 后的文件列表:', this.files);
|
||||||
// this.$message.success('文件已替换');
|
|
||||||
|
// 传递当前文件信息给父组件
|
||||||
|
this.$emit('file-change', this.getCurrentFiles());
|
||||||
|
|
||||||
|
// 自动上传新文件
|
||||||
|
if (this.autoUpload && !this.isUploading) {
|
||||||
|
if (this.fileUploadRule.fields_json) {
|
||||||
|
this.uploadFile(newFileObj, '识别中');
|
||||||
|
} else {
|
||||||
|
this.uploadFile(newFileObj, '上传中');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 移除文件
|
// 移除文件
|
||||||
handleRemove(file, fileList) {
|
handleRemove(file, fileList) {
|
||||||
this.files = fileList;
|
console.log('移除文件:', file);
|
||||||
|
console.log('移除前的文件列表:', this.files);
|
||||||
|
|
||||||
|
// 如果正在上传中,阻止移除
|
||||||
|
if (this.isUploading) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用格式化方法而不是深拷贝
|
||||||
|
this.files = this.formatFileList(fileList);
|
||||||
|
|
||||||
|
console.log('移除后的文件列表:', this.files);
|
||||||
|
|
||||||
// 根据剩余文件重新生成预览
|
// 根据剩余文件重新生成预览
|
||||||
if (fileList.length === 0) {
|
if (fileList.length === 0) {
|
||||||
|
|
@ -206,8 +382,10 @@ export default {
|
||||||
this.clearPreview();
|
this.clearPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('file-change', fileList);
|
// 传递当前文件信息给父组件
|
||||||
|
this.$emit('file-change', this.getCurrentFiles());
|
||||||
},
|
},
|
||||||
|
|
||||||
// 判断是否为图片文件
|
// 判断是否为图片文件
|
||||||
isImageFile(file) {
|
isImageFile(file) {
|
||||||
return file && file.type && file.type.startsWith('image/');
|
return file && file.type && file.type.startsWith('image/');
|
||||||
|
|
@ -307,10 +485,6 @@ export default {
|
||||||
'png': 'image/png',
|
'png': 'image/png',
|
||||||
'jpg': 'image/jpeg',
|
'jpg': 'image/jpeg',
|
||||||
'jpeg': 'image/jpeg',
|
'jpeg': 'image/jpeg',
|
||||||
'gif': 'image/gif',
|
|
||||||
'bmp': 'image/bmp',
|
|
||||||
'webp': 'image/webp',
|
|
||||||
'svg': 'image/svg+xml',
|
|
||||||
'pdf': 'application/pdf',
|
'pdf': 'application/pdf',
|
||||||
'doc': 'application/msword',
|
'doc': 'application/msword',
|
||||||
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
|
@ -323,7 +497,9 @@ export default {
|
||||||
watch: {
|
watch: {
|
||||||
fileList: {
|
fileList: {
|
||||||
handler(newVal) {
|
handler(newVal) {
|
||||||
this.files = newVal;
|
// console.log('fileList 变化:', newVal);
|
||||||
|
// 使用格式化方法而不是深拷贝
|
||||||
|
this.files = this.formatFileList(newVal);
|
||||||
// 如果外部传入文件列表,也尝试生成预览
|
// 如果外部传入文件列表,也尝试生成预览
|
||||||
if (newVal.length === 1 && newVal[0] && newVal[0].raw) {
|
if (newVal.length === 1 && newVal[0] && newVal[0].raw) {
|
||||||
if (this.isImageFile(newVal[0].raw)) {
|
if (this.isImageFile(newVal[0].raw)) {
|
||||||
|
|
@ -340,7 +516,6 @@ export default {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.upload-container {
|
.upload-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<el-form :model="form" :rules="rules" ref="basicInfoForm" label-width="110px" label-position="top">
|
<el-form :model="form" :rules="rules" ref="basicInfoForm" label-width="110px" label-position="top">
|
||||||
<!-- 营业执照 -->
|
<!-- 营业执照 -->
|
||||||
<el-form-item label="营业执照" prop="fileList">
|
<el-form-item label="营业执照" prop="fileList">
|
||||||
<UploadFile :fileList="form.fileList" :fileUploadRule="fileUploadRule" />
|
<UploadFile :fileList="form.fileList" :fileUploadRule="fileUploadRule" @file-change="handleFileChange"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="企业名称" prop="enterpriseName">
|
<el-form-item label="企业名称" prop="enterpriseName">
|
||||||
<el-input v-model="form.enterpriseName" placeholder="自动提取"></el-input>
|
<el-input v-model="form.enterpriseName" placeholder="自动提取"></el-input>
|
||||||
|
|
@ -55,6 +55,14 @@ export default {
|
||||||
// ocrRuleList: ['business_license', 'face_id_card_portrait', 'national_emblem_id_card', 'account_opening_license'],
|
// ocrRuleList: ['business_license', 'face_id_card_portrait', 'national_emblem_id_card', 'account_opening_license'],
|
||||||
ocrRuleList: ['business_license'],
|
ocrRuleList: ['business_license'],
|
||||||
fileUploadList: [],
|
fileUploadList: [],
|
||||||
|
ocrResult: {
|
||||||
|
"企业名称": "enterpriseName",
|
||||||
|
"统一社会信用代码": "enterpriseCode",
|
||||||
|
"注册资本": "registeredCapital",
|
||||||
|
"营业期限": "businessTerm",
|
||||||
|
"住所": "residence",
|
||||||
|
"经营范围": "businessScope",
|
||||||
|
},
|
||||||
rules: {
|
rules: {
|
||||||
fileList: [
|
fileList: [
|
||||||
{ required: true, message: '请上传营业执照', trigger: 'blur' }
|
{ required: true, message: '请上传营业执照', trigger: 'blur' }
|
||||||
|
|
@ -105,7 +113,6 @@ export default {
|
||||||
fields_json: foundItem.raw.remark,
|
fields_json: foundItem.raw.remark,
|
||||||
suffix: 'mainDatabase'
|
suffix: 'mainDatabase'
|
||||||
} : null;
|
} : null;
|
||||||
console.log(item);
|
|
||||||
|
|
||||||
this.fileUploadList.push(item)
|
this.fileUploadList.push(item)
|
||||||
},
|
},
|
||||||
|
|
@ -115,6 +122,23 @@ export default {
|
||||||
this.ocrRule(item)
|
this.ocrRule(item)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// 文件变化
|
||||||
|
handleFileChange(file) {
|
||||||
|
this.form.fileList = file;
|
||||||
|
console.log(file[0].response);
|
||||||
|
if(file instanceof Array && file.length > 0){
|
||||||
|
// 文件上传成功
|
||||||
|
const response = file[0].response;
|
||||||
|
if(response.ocrResult){
|
||||||
|
// ocr识别成功
|
||||||
|
this.ocrResult.forEach(item => {
|
||||||
|
this.form[item.value] = response.ocrResult[item.label];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.$refs.basicInfoForm.validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
fileUploadRule() {
|
fileUploadRule() {
|
||||||
|
|
@ -126,7 +150,6 @@ export default {
|
||||||
'dict.type.identification_tag': {
|
'dict.type.identification_tag': {
|
||||||
handler(newVal) {
|
handler(newVal) {
|
||||||
if (newVal && newVal.length > 0) {
|
if (newVal && newVal.length > 0) {
|
||||||
console.log('字典数据加载完成:', newVal);
|
|
||||||
this.addOcrRule();
|
this.addOcrRule();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,6 @@ export default {
|
||||||
|
|
||||||
// 新增企业
|
// 新增企业
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
console.log('新增企业')
|
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'EnterpriseForm',
|
name: 'EnterpriseForm',
|
||||||
query: {
|
query: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue