Browse Source

文件上传整合

master
xuhuajiao 3 months ago
parent
commit
19ee1cfd3d
  1. 13
      src/utils/upload.js
  2. 16
      src/views/collectReorganizi/batchConnection/index.vue
  3. 71
      src/views/collectReorganizi/batchConnection/module/form.vue
  4. 7
      src/views/collectReorganizi/collectionLibrary/module/collectHeader.vue
  5. 58
      src/views/collectReorganizi/collectionLibrary/module/uploadOriginal/bigUpload.vue
  6. 2
      src/views/collectReorganizi/collectionLibrary/module/uploadOriginal/index.vue
  7. 37
      src/views/components/category/PreviewForm.vue
  8. 549
      src/views/components/category/preUpload.vue
  9. 22
      src/views/prearchiveLibrary/index.vue

13
src/utils/upload.js

@ -47,7 +47,8 @@ export function archivesUpload(api, file, categoryId, archivesId, fileJsonString
// 收集库 - 目录上传 // 收集库 - 目录上传
export function catalogUpload(api, file, fondsId) { export function catalogUpload(api, file, fondsId) {
var data = new FormData() var data = new FormData()
data.append('file', file)
// data.append('file', file)
data.append('upfilePath', file)
data.append('fondsId', fondsId) data.append('fondsId', fondsId)
const config = { const config = {
headers: { 'Authorization': getToken() } headers: { 'Authorization': getToken() }
@ -78,17 +79,19 @@ export function modelUpload(api, file, name) {
} }
// 收集库 - 批量挂接 // 收集库 - 批量挂接
export function batchMountUpload(api, file, params) {
// export function batchMountUpload(api, file, params) {
export function batchMountUpload(api, params) {
var data = new FormData() var data = new FormData()
for (const item in file) { // 现在
data.append('file', file[item])
}
// for (const item in file) { // 现在
// data.append('file', file[item])
// }
data.append('categoryId', params.categoryId) data.append('categoryId', params.categoryId)
data.append('mountType', params.mountType) data.append('mountType', params.mountType)
data.append('checkRepeatType', params.checkRepeatType) data.append('checkRepeatType', params.checkRepeatType)
data.append('matchingMode', params.matchingMode) data.append('matchingMode', params.matchingMode)
data.append('fields', params.fields) data.append('fields', params.fields)
data.append('fondsId', params.fondsId) data.append('fondsId', params.fondsId)
data.append('upfilePath', params.upfilePath)
const config = { const config = {
headers: { headers: {
'Authorization': getToken() 'Authorization': getToken()

16
src/views/collectReorganizi/batchConnection/index.vue

@ -2,9 +2,9 @@
<div class="app-container archives-container"> <div class="app-container archives-container">
<div class="container-main" style="justify-content: flex-start;"> <div class="container-main" style="justify-content: flex-start;">
<CategoryTree ref="categoryTree" is-move-file="false" @nodeClick="handleNodeClick" /> <CategoryTree ref="categoryTree" is-move-file="false" @nodeClick="handleNodeClick" />
<div v-if="currentCategory && currentCategory.isType === 2" class="elect-cont-right">
<div v-if="selectedCategory && selectedCategory.isType === 2" class="elect-cont-right">
<div class="connection-header collect-header"> <div class="connection-header collect-header">
<h4 class="is-anjuan">{{ currentCategory && currentCategory.cnName }} </h4>
<h4 class="is-anjuan">{{ selectedCategory && selectedCategory.cnName }} </h4>
<div class="head-search"> <div class="head-search">
<date-range-picker v-model="blurryTime" class="date-item" /> <date-range-picker v-model="blurryTime" class="date-item" />
<rrOperation /> <rrOperation />
@ -61,7 +61,7 @@
<pagination v-if="crud.data.length !== 0" /> <pagination v-if="crud.data.length !== 0" />
</div> </div>
</div> </div>
<LocalForm ref="localForm" :current-category="currentCategory" />
<LocalForm ref="localForm" :selected-category="selectedCategory" />
<HitchDetail ref="mDetail" /> <HitchDetail ref="mDetail" />
</div> </div>
</template> </template>
@ -104,7 +104,7 @@ export default {
}, },
data() { data() {
return { return {
currentCategory: null,
selectedCategory: null,
blurryTime: null, blurryTime: null,
formVisible: false formVisible: false
} }
@ -114,11 +114,11 @@ export default {
'baseApi' 'baseApi'
]), ]),
collectLevel() { collectLevel() {
if (this.currentCategory.arrangeType === 1) {
if (this.selectedCategory.arrangeType === 1) {
return 3 return 3
} else if (this.currentCategory.arrangeType === 2) {
} else if (this.selectedCategory.arrangeType === 2) {
return 2 return 2
} else if (this.currentCategory.arrangeType === 3) {
} else if (this.selectedCategory.arrangeType === 3) {
return 1 return 1
} }
return null return null
@ -153,7 +153,7 @@ export default {
this.crud.refresh() this.crud.refresh()
}, },
handleNodeClick(data) { handleNodeClick(data) {
this.currentCategory = data
this.selectedCategory = data
if (data) { if (data) {
this.crud.query.categoryId = data.id this.crud.query.categoryId = data.id
this.crud.query.fondsId = data.fondsId this.crud.query.fondsId = data.fondsId

71
src/views/collectReorganizi/batchConnection/module/form.vue

@ -40,20 +40,22 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-if="!connectionType" label="上传附件" prop="file">
<div class="upload-bgColor">
<el-form-item v-if="!connectionType" label="上传附件" prop="file" class="upload-wm">
<!-- <div class="upload-bgColor">
<input class="upload-input" type="file" accept=".zip" style="width: 110px; height: 32px;" @change="handleFile"> <input class="upload-input" type="file" accept=".zip" style="width: 110px; height: 32px;" @change="handleFile">
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />点击上传</el-button> <el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />点击上传</el-button>
</div>
<!-- <div class="file-list">
<i class="iconfont icon-xiaowenjian" />
{{ form.file && form.file.name }}
</div> --> </div> -->
<div v-for="item in fileList" :key="item.name" class="file-list"> <div v-for="item in fileList" :key="item.name" class="file-list">
<i class="iconfont icon-xiaowenjian" /> <i class="iconfont icon-xiaowenjian" />
{{ item.name }}
{{ item.file_name }}
</div> </div>
<el-input v-show="false" v-model="form.file" /> <el-input v-show="false" v-model="form.file" />
<!-- 大文件上传 -->
<PreUpload ref="uploadBigRef" is-batch-mount="true" :selected-category="selectedCategory" @onUploadSuccess="handleSuccessResource" @onUploadError="handleErrorResource" />
<!-- <div class="file-list">
<i class="iconfont icon-xiaowenjian" />
{{ form.file && form.file.name }}
</div> -->
</el-form-item> </el-form-item>
<el-form-item v-if="connectionType" label="挂接类型" prop="protocol"> <el-form-item v-if="connectionType" label="挂接类型" prop="protocol">
<el-select v-model="form.protocol" placeholder="请选择" style="width: 400px;" @change="changeProtocol"> <el-select v-model="form.protocol" placeholder="请选择" style="width: 400px;" @change="changeProtocol">
@ -107,12 +109,14 @@ import { FetchInitCategoryInputFieldByPid } from '@/api/system/category/category
import { FetchFindDetailsByProtocol, FetchFileByRemoteConnection } from '@/api/system/remoteConnection' import { FetchFindDetailsByProtocol, FetchFileByRemoteConnection } from '@/api/system/remoteConnection'
import { batchMountUpload, remoteConnectiontUpload } from '@/utils/upload' import { batchMountUpload, remoteConnectiontUpload } from '@/utils/upload'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import PreUpload from '../../../components/category/preUpload.vue'
export default { export default {
name: 'LocalHitch', name: 'LocalHitch',
components: { },
components: { PreUpload },
mixins: [crud()], mixins: [crud()],
props: { props: {
currentCategory: {
selectedCategory: {
type: Object, type: Object,
default: function() { default: function() {
return {} return {}
@ -136,6 +140,7 @@ export default {
filePath: null, filePath: null,
fileRemote: null fileRemote: null
}, },
upfilePath: null,
fileList: [], fileList: [],
typeOptions: [ typeOptions: [
{ {
@ -213,11 +218,11 @@ export default {
'baseApi' 'baseApi'
]), ]),
collectLevel() { collectLevel() {
if (this.currentCategory.arrangeType === 1) {
if (this.selectedCategory.arrangeType === 1) {
return 3 return 3
} else if (this.currentCategory.arrangeType === 2) {
} else if (this.selectedCategory.arrangeType === 2) {
return 2 return 2
} else if (this.currentCategory.arrangeType === 3) {
} else if (this.selectedCategory.arrangeType === 3) {
return 1 return 1
} }
return null return null
@ -231,6 +236,22 @@ export default {
opened() { opened() {
this.getFieldCommon() this.getFieldCommon()
}, },
handleSuccessResource(res, fileName, jsonArrayToSend) {
console.log('handleSuccessResource', res[0])
console.log('handleSuccessResource', fileName)
console.log('handleSuccessResource', jsonArrayToSend)
console.log('handleSuccessResource', jsonArrayToSend[0].fileJsonString)
const fileJson = JSON.parse(jsonArrayToSend[0].fileJsonString)
fileJson[0].file_path = res[0]
fileJson[0].is_quote = null
fileJson[0].last_modified = jsonArrayToSend[0].last_modified
this.fileList = fileJson
this.upfilePath = res[0]
},
handleErrorResource(res) {
console.log('handleErrorResource', res)
},
handleFile(event) { handleFile(event) {
const files = event.target.files const files = event.target.files
for (let i = 0; i < files.length; i++) { for (let i = 0; i < files.length; i++) {
@ -253,23 +274,23 @@ export default {
} }
this.btnLoading = true this.btnLoading = true
this.$refs['form'].validate((valid) => { this.$refs['form'].validate((valid) => {
console.log('this.currentCategory', this.currentCategory)
console.log('this.selectedCategory', this.selectedCategory)
if (valid) { if (valid) {
let newhitchRemark = this.hitchRemarkArray.map(item => item.replace(/^\$|\$$|\*$/g, '')) let newhitchRemark = this.hitchRemarkArray.map(item => item.replace(/^\$|\$$|\*$/g, ''))
newhitchRemark = newhitchRemark.filter(item => item !== '') newhitchRemark = newhitchRemark.filter(item => item !== '')
if (!this.connectionType) { if (!this.connectionType) {
const params = { const params = {
'categoryId': this.currentCategory.id,
'categoryId': this.selectedCategory.id,
'mountType': 1, // 1. 2. 3. 1 'mountType': 1, // 1. 2. 3. 1
'checkRepeatType': this.form.checkRepeatType, 'checkRepeatType': this.form.checkRepeatType,
'matchingMode': this.form.matchingMode, 'matchingMode': this.form.matchingMode,
'fields': newhitchRemark, 'fields': newhitchRemark,
'fondsId': this.currentCategory.fondsId
'fondsId': this.selectedCategory.fondsId,
'upfilePath': this.upfilePath
} }
console.log(params) console.log(params)
batchMountUpload(this.baseApi + '/api/collect/batchMount', batchMountUpload(this.baseApi + '/api/collect/batchMount',
this.fileList,
params params
).then(res => { ).then(res => {
if (res.data.code === 200) { if (res.data.code === 200) {
@ -287,8 +308,8 @@ export default {
'cAddress': this.form.filePath.caddress, 'cAddress': this.form.filePath.caddress,
'cPassword': this.form.filePath.cpassword, 'cPassword': this.form.filePath.cpassword,
'cPort': this.form.filePath.cport, 'cPort': this.form.filePath.cport,
'categoryId': this.currentCategory.id,
'fondsId': this.currentCategory.fondsId,
'categoryId': this.selectedCategory.id,
'fondsId': this.selectedCategory.fondsId,
'checkRepeatType': this.form.checkRepeatType, 'checkRepeatType': this.form.checkRepeatType,
'matchingMode': this.form.matchingMode, 'matchingMode': this.form.matchingMode,
'fields': newhitchRemark, 'fields': newhitchRemark,
@ -317,7 +338,7 @@ export default {
}, },
getFieldCommon() { getFieldCommon() {
const params = { const params = {
'categoryId': this.currentCategory.id,
'categoryId': this.selectedCategory.id,
'categoryLevel': this.collectLevel 'categoryLevel': this.collectLevel
} }
FetchInitCategoryInputFieldByPid(params).then(data => { FetchInitCategoryInputFieldByPid(params).then(data => {
@ -461,5 +482,17 @@ export default {
} }
} }
} }
.upload-wm{
height: 100px;
}
::v-deep .uploader-big{
margin-left: 0 !important;
}
::v-deep .upload_process_box{
right: 0 !important;
left: 120px !important;
top: 0 !important;
width: 300px !important;
}
</style> </style>

7
src/views/collectReorganizi/collectionLibrary/module/collectHeader.vue

@ -1017,10 +1017,13 @@ export default {
this.$refs.uploadOriginalRef.uploadVisible = true this.$refs.uploadOriginalRef.uploadVisible = true
} else if (uploadType === 1) { } else if (uploadType === 1) {
this.$refs.uploadBigRef.uploadBigVisible = true this.$refs.uploadBigRef.uploadBigVisible = true
this.isCatalogUpload = false
this.$refs.uploadBigRef.fileList = [] this.$refs.uploadBigRef.fileList = []
} else if (uploadType === 2) { } else if (uploadType === 2) {
this.$refs.uploadOriginalRef.uploadTitle = '原文目录上传'
this.$refs.uploadOriginalRef.uploadVisible = true
this.$refs.uploadBigRef.uploadTitle = '原文目录上传'
this.$refs.uploadBigRef.uploadBigVisible = true
this.isCatalogUpload = true
this.$refs.uploadBigRef.fileList = []
} }
if (this.$refs.uploadOriginalRef.uploadVisible) { if (this.$refs.uploadOriginalRef.uploadVisible) {
this.$refs.uploadOriginalRef.uploadType = uploadType this.$refs.uploadOriginalRef.uploadType = uploadType

58
src/views/collectReorganizi/collectionLibrary/module/uploadOriginal/bigUpload.vue

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--上传组件--> <!--上传组件-->
<el-dialog class="big-file" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="uploadBigVisible" :before-close="handleCloseDialog">
<el-dialog class="big-file" :close-on-click-modal="false" :modal-append-to-body="false" append-to-body :visible.sync="uploadBigVisible" :before-close="handleCloseDialog" @opened="opened">
<template #title> <template #title>
{{ uploadTitle }} {{ uploadTitle }}
<span style="color: red;font-size: 12px; ">单个文件不可超过10GB</span> <span style="color: red;font-size: 12px; ">单个文件不可超过10GB</span>
@ -21,7 +21,7 @@
<uploader-unsupport /> <uploader-unsupport />
<uploader-drop> <uploader-drop>
<p>将文件拖到此处或点击上传</p> <p>将文件拖到此处或点击上传</p>
<uploader-btn>
<uploader-btn :attrs="attrs">
<slot> <slot>
<i class="iconfont icon-tianjiawenjian upload-icon" /> <i class="iconfont icon-tianjiawenjian upload-icon" />
</slot> </slot>
@ -78,6 +78,7 @@ import axios from 'axios'
import SparkMD5 from 'spark-md5' import SparkMD5 from 'spark-md5'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { getCurrentTime } from '@/utils/index' import { getCurrentTime } from '@/utils/index'
import { catalogUpload } from '@/utils/upload'
// https://juejin.cn/post/7040817922540830728 // https://juejin.cn/post/7040817922540830728
export default { export default {
props: { props: {
@ -96,6 +97,7 @@ export default {
}, },
data() { data() {
return { return {
isCatalogUpload: false,
uploadTitle: '文件上传', uploadTitle: '文件上传',
btnLoading: false, btnLoading: false,
uploadBigVisible: false, uploadBigVisible: false,
@ -106,7 +108,6 @@ export default {
testChunks: true, // testChunks: true, //
singleFile: false, // singleFile: false, //
uploadMethod: 'post', // 使 HTTP , POST uploadMethod: 'post', // 使 HTTP , POST
allowDuplicateUploads: false, //
parseTimeRemaining: function(timeRemaining, parsedTimeRemaining) { parseTimeRemaining: function(timeRemaining, parsedTimeRemaining) {
return parsedTimeRemaining return parsedTimeRemaining
.replace(/\syears?/, '年') .replace(/\syears?/, '年')
@ -129,7 +130,7 @@ export default {
} }
}, },
attrs: { attrs: {
accept: 'image/*'
accept: ''
}, },
// //
statusText: { statusText: {
@ -158,6 +159,21 @@ export default {
this.options.target = this.baseApi + '/api/collect/upload' this.options.target = this.baseApi + '/api/collect/upload'
}, },
methods: { methods: {
opened() {
this.updateUploadOptions()
},
updateUploadOptions() {
if (this.isCatalogUpload) {
// 使 Object.assign
this.attrs = Object.assign({}, this.attrs, { accept: '.zip' })
this.options.singleFile = true
} else {
// 使
this.attrs = { ...this.attrs, accept: '' }
this.options.singleFile = false
}
console.log('this.attrs.accept', this.attrs.accept)
},
// //
getFileList() { getFileList() {
const params = { const params = {
@ -202,6 +218,7 @@ export default {
} }
this.nowDate = getCurrentTime() this.nowDate = getCurrentTime()
const jsonArrayToSend = [] const jsonArrayToSend = []
console.log('this.$refs.uploader.fileList', this.$refs.uploader.fileList)
// 使 Promise.all // 使 Promise.all
Promise.all(this.$refs.uploader.fileList.map(async(item) => { Promise.all(this.$refs.uploader.fileList.map(async(item) => {
@ -250,19 +267,29 @@ export default {
} }
}).then((res) => { }).then((res) => {
console.log(res) console.log(res)
if (res.data.code === 200 && res.data.data !== '') {
this.$message({ message: '所有文件上传成功', type: 'success', offset: 8 })
if (res.data.code === 200 && res.data.data[0] !== '') {
if (this.isCatalogUpload) {
catalogUpload(this.baseApi + '/api/collect/catalogUpload',
res.data.data[0],
this.selectedCategory.fondsId
).then(res => {
if (res.data.code === 200) {
this.$message({ message: '操作成功', type: 'success', offset: 8 })
} else {
this.$message({ message: '操作失败', type: 'error', offset: 8 })
}
this.$emit('close-dialog')
this.handleCloseDialog()
})
} else {
this.$message({ message: '所有文件上传成功', type: 'success', offset: 8 })
this.$emit('close-dialog')
this.handleCloseDialog()
}
} else { } else {
this.$message({ message: '部分或全部文件上传失败', type: 'error', offset: 8 }) this.$message({ message: '部分或全部文件上传失败', type: 'error', offset: 8 })
this.handleCloseDialog()
} }
this.$emit('close-dialog')
this.uploadBigVisible = false
this.fileList = []
this.btnLoading = false
this.$refs.uploader.files = []
this.$refs.uploader.fileList = []
this.$refs.uploader.uploader.fileList = []
this.$refs.uploader.uploader.files = []
}) })
} else { } else {
this.submitted = false this.submitted = false
@ -369,6 +396,7 @@ export default {
file.size file.size
} 用时${new Date().getTime() - time} ms` } 用时${new Date().getTime() - time} ms`
) )
console.log('md5', md5)
spark.destroy() // spark.destroy() //
file.uniqueIdentifier = md5 // md5 file.uniqueIdentifier = md5 // md5
file.cmd5 = false // md5 file.cmd5 = false // md5
@ -403,6 +431,7 @@ export default {
}) })
}, },
handleCloseDialog(done) { handleCloseDialog(done) {
this.btnLoading = false
this.uploadBigVisible = false this.uploadBigVisible = false
const uploaderInstance = this.$refs.uploader.uploader const uploaderInstance = this.$refs.uploader.uploader
console.log('uploaderInstance.fileList', uploaderInstance.fileList) console.log('uploaderInstance.fileList', uploaderInstance.fileList)
@ -412,6 +441,7 @@ export default {
this.fileList = [] this.fileList = []
this.$refs.uploader.files = [] this.$refs.uploader.files = []
this.$refs.uploader.fileList = [] this.$refs.uploader.fileList = []
this.attrs = { ...this.attrs, accept: '' }
} }
} }
} }

2
src/views/collectReorganizi/collectionLibrary/module/uploadOriginal/index.vue

@ -20,7 +20,7 @@
<input ref="fileInput" :key="key" type="file" :multiple="isMultiple" :accept="uploadType === 2 ? '.zip' :''" @change="handleFileChange"> <input ref="fileInput" :key="key" type="file" :multiple="isMultiple" :accept="uploadType === 2 ? '.zip' :''" @change="handleFileChange">
<div class="upload-zip"><i class="iconfont icon-shangchuan2" />点击上传</div> <div class="upload-zip"><i class="iconfont icon-shangchuan2" />点击上传</div>
</div> </div>
<BigUpload v-else-if="uploadType === 1" :selected-category="selectedCategory" :arc-id="arcId" />
<!-- <BigUpload v-else-if="uploadType === 1" :selected-category="selectedCategory" :arc-id="arcId" /> -->
<div v-if="uploadType === 2" class="el-upload__tip">上传限制文件类型zip</div> <div v-if="uploadType === 2" class="el-upload__tip">上传限制文件类型zip</div>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">

37
src/views/components/category/PreviewForm.vue

@ -2,7 +2,7 @@
<!-- :style="`padding: ${isDesFormType === 'arcives' ? '20px 0 100px 0 !important' : ''};` --> <!-- :style="`padding: ${isDesFormType === 'arcives' ? '20px 0 100px 0 !important' : ''};` -->
<div class="preview-content right-preview"> <div class="preview-content right-preview">
<el-form ref="addOrUpdateForm" :model="addOrUpdateForm" :rules="rules" :validate-on-rule-change="false" label-width="125px"> <el-form ref="addOrUpdateForm" :model="addOrUpdateForm" :rules="rules" :validate-on-rule-change="false" label-width="125px">
<el-row :gutter="4" style="padding:0 20px">
<el-row :gutter="4" style="padding:0 20px" :class="isDesFormType === 'prearchiveLibrary' ? 'library-form' :''">
<draggable v-bind="{draggable:'.drag-item',animation:500}" :disabled="!isDraggable" @update="datadragEnd"> <draggable v-bind="{draggable:'.drag-item',animation:500}" :disabled="!isDraggable" @update="datadragEnd">
<el-col <el-col
v-for="(item,index) in formPreviewData" v-for="(item,index) in formPreviewData"
@ -83,7 +83,7 @@
<input id="upFile" type="file" name="upFile" @change="changeFile($event)"> <input id="upFile" type="file" name="upFile" @change="changeFile($event)">
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button> <el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button>
</div> --> </div> -->
<PreUpload :selected-document="selectedDocument" />
<PreUpload :selected-document="selectedDocument" :arc-id="arcId" @onUploadSuccess="handleSuccessResource" @onUploadError="handleErrorResource" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -284,6 +284,22 @@ export default {
mounted() { mounted() {
}, },
methods: { methods: {
handleSuccessResource(res, fileName, jsonArrayToSend) {
console.log('handleSuccessResource', res[0])
console.log('handleSuccessResource', fileName)
console.log('handleSuccessResource', jsonArrayToSend)
console.log('handleSuccessResource', jsonArrayToSend[0].fileJsonString)
this.fileOriginal = fileName
const fileJson = JSON.parse(jsonArrayToSend[0].fileJsonString)
fileJson[0].file_path = '/' + res[0]
fileJson[0].is_quote = null
fileJson[0].last_modified = jsonArrayToSend[0].last_modified
this.fileJsonString = JSON.stringify(fileJson)
},
handleErrorResource(res) {
console.log('handleErrorResource', res)
},
checkboxT(row, rowIndex) { checkboxT(row, rowIndex) {
return row.level ? row.level === 3 : true return row.level ? row.level === 3 : true
}, },
@ -1033,12 +1049,13 @@ export default {
// //
if (this.isDesFormType === 'prearchiveLibrary') { if (this.isDesFormType === 'prearchiveLibrary') {
if (this.fileOriginal === null) { if (this.fileOriginal === null) {
this.$message({ message: '请上传电子原件', type: 'error', offset: 8 })
this.$emit('formLoadingShow', false) this.$emit('formLoadingShow', false)
return false return false
} }
// delete this.addOrUpdateForm.fileOriginal // delete this.addOrUpdateForm.fileOriginal
const params = { const params = {
'id': this.arcId,
'id': this.archivesType === 'edit' ? this.arcId : null,
'ids': null, 'ids': null,
'documentId': categoryId, 'documentId': categoryId,
'delMan': null, 'delMan': null,
@ -1047,6 +1064,7 @@ export default {
'fondsAffiliation': this.selectedDocument.fondsId 'fondsAffiliation': this.selectedDocument.fondsId
} }
console.log('params', params) console.log('params', params)
console.log('archivesType', this.archivesType)
prearchEdit(params).then(res => { prearchEdit(params).then(res => {
if (res) { if (res) {
this.$message({ message: res.message, type: 'success', offset: 8 }) this.$message({ message: res.message, type: 'success', offset: 8 })
@ -1402,12 +1420,17 @@ export default {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.input-style{ .input-style{
width: 539px;
width: 560px;
height: 34px; height: 34px;
line-height: 34px; line-height: 34px;
padding: 0 20px; padding: 0 20px;
border: 1px solid #e6e8ed; border: 1px solid #e6e8ed;
border-radius: 3px; border-radius: 3px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
&.error-box{ &.error-box{
border-color: #ed4a41; border-color: #ed4a41;
} }
@ -1451,4 +1474,10 @@ export default {
height: auto; height: auto;
overflow: hidden; overflow: hidden;
} }
.library-form{
height: calc(100vh - 473px) !important;
overflow: hidden;
overflow-y: scroll;
}
</style> </style>

549
src/views/components/category/preUpload.vue

@ -0,0 +1,549 @@
<template>
<div class="uploader-big">
<uploader
ref="uploader"
:options="initOptions"
:file-status-text="fileStatusText"
:auto-start="false"
class="uploader-app"
@file-added="onFileAdded"
@file-success="onUploadSuccess"
@file-progress="onFileProgress"
@file-error="onFileError"
>
<uploader-unsupport />
<!-- @click="clickUploader" -->
<uploader-drop class="custom_uploader_drop" element-loading-text="正在读取中">
<uploader-btn ref="uploadBtn" :attrs="attrs">
<slot>
<i class="iconfont icon-shangchuan" />
上传
</slot>
</uploader-btn>
</uploader-drop>
<div v-if="isUpload" class="upload_process_box">
<div>文件名{{ fileName }}</div>
<el-progress :percentage="uploadProcessNum" />
<div v-if="isMd5Upload">
正在读取文件中 - {{ md5ProgressText }}
</div>
<div v-if="!isSyncUpload&&!isMd5Upload">
上传至服务器 - <span>{{ uploadSpeed }} M/s</span>
</div>
<div v-if="isSyncUpload">
上传中请稍后
</div>
</div>
</uploader>
</div>
</template>
<script>
import SparkMD5 from 'spark-md5'
import { mapGetters } from 'vuex'
import axios from 'axios'
import { getToken } from '@/utils/auth'
import { getCurrentTime } from '@/utils/index'
export default {
props: {
selectedDocument: {
type: Object,
default: function() {
return {}
}
},
arcId: {
type: String,
default: function() {
return ''
}
},
selectedCategory: {
type: Object,
default: function() {
return {}
}
},
isBatchMount: {
type: String,
default: function() {
return ''
}
}
},
data() {
return {
initOptions: {
target: null,
headers: {
Authorization: getToken()
},
singleFile: true, //
uploadMethod: 'post', // 使 HTTP , POST
maxChunkRetries: 3, //
testChunks: true, //
parseTimeRemaining: function(timeRemaining, parsedTimeRemaining) {
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
},
checkChunkUploadedByResponse: (chunk, message) => {
const result = JSON.parse(message)
if (result.data.skipUpload) {
this.skip = true
return true
}
return (result.data.uploaded || []).indexOf(chunk.offset + 1) >= 0
}
},
attrs: {
accept: ''
},
fileStatusText: {
success: '上传成功',
error: '上传失败',
uploading: '上传中',
paused: '已暂停',
waiting: '等待上传'
},
isStartUpload: false, //
md5ProgressText: 0,
isMd5Upload: false, // md5
isUpload: false, //
uploadProcessNum: 0, //
uploadSpeed: 0, //
fileName: '', //
isSyncUpload: false, //
syncUploadProcessNum: 0, //
response: null, //
queryTimer: null, //
socket: null
}
},
computed: {
...mapGetters([
'baseApi'
]),
// Uploader
uploader() {
return this.$refs.uploader.uploader
}
},
created() {
this.initOptions.target = this.baseApi + '/api/collect/upload'
if (this.isBatchMount === 'true') {
this.attrs.accept = '.zip'
} else {
this.attrs.accept = ''
}
},
beforeDestroy() {
clearInterval(this.queryTimer)
},
methods: {
clickUploader(e) {
this.$refs.uploadBtn.$el.click()
},
//
onFileAdded(file) {
this.uploadProcessNum = 0
// MD5
this.computeMD5(file).then((result) => this.startUpload(result))
},
/**
* 计算md5值以实现断点续传及秒传
*/
computeMD5(file) {
const maxMessage = '上传文件大小不能超过 10GB!'
const maxSize = 10 * 1024 * 1024 * 1024
if (file && file.size > maxSize) {
this.$message.warning(maxMessage)
return false
}
const fileReader = new FileReader()
const time = new Date().getTime()
const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
let currentChunk = 0
// const chunkSize = this.initOptions.chunkSize
const chunkSize = 10 * 1024 * 1024
// 使 Math.ceil
const chunksWithCeil = Math.ceil(file.size / chunkSize)
console.log('使用 Math.ceil 得到的 chunks 数量:', chunksWithCeil)
//
let chunks = Math.floor(file.size / chunkSize)
if (file.size % chunkSize !== 0) {
chunks++
}
console.log('chunksManual', chunks)
const spark = new SparkMD5.ArrayBuffer()
this.fileName = file.name
// "MD5"
this.isMd5Upload = true
this.isUpload = true
file.pause()
loadNext()
return new Promise((resolve, reject) => {
fileReader.onload = (e) => {
spark.append(e.target.result)
if (currentChunk < chunks) {
currentChunk++
loadNext()
// MD5
this.$nextTick(() => {
this.md5ProgressText = ((currentChunk / chunks) * 100).toFixed(0) + '%'
})
} else {
console.log('spark', spark)
const md5 = spark.end()
console.log('md5', md5)
// md5
resolve({ md5, file })
console.log(file)
console.log(
`MD5计算完毕:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${
new Date().getTime() - time
} ms`
)
}
}
fileReader.onerror = function() {
this.$message({ message: `文件${file.name}读取出错,请检查该文件`, type: 'error', offset: 8 })
file.cancel()
reject()
}
})
function loadNext() {
const start = currentChunk * chunkSize
const end = start + chunkSize >= file.size ? file.size : start + chunkSize
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end))
}
},
// md5
startUpload({ md5, file }) {
file.uniqueIdentifier = md5
file.resume()
this.isMd5Upload = false
this.isStartUpload = true
},
//
onFileProgress(rootFile, file, chunk) {
const uploader = this.$refs.uploader.uploader
this.uploadProcessNum = Math.floor(uploader.progress() * 100)
// this.emit('onUploadProcess', uploader.progress())
const averageSpeed = uploader.averageSpeed
const speed = averageSpeed / 1000 / 10
this.uploadSpeed = speed.toFixed(2)
},
//
onUploadSuccess(rootFile, file, response, chunk) {
const res1 = JSON.parse(response)
if (res1.code === 200) {
// merge
console.log('rootFile.uniqueIdentifier', rootFile.uniqueIdentifier)
const body = {
totalChunks: rootFile.chunks.length,
md5File: rootFile.uniqueIdentifier,
fileName: rootFile.name
}
console.log('body', body)
console.log(file)
this.handleUploadConfirm()
} else {
this.$message({ message: '上传失败!', type: 'error', offset: 8 })
this.$emit('onUploadError', res1)
}
if (this.skip) {
this.skip = false
}
},
handleUploadConfirm() {
if (this.$refs.uploader.fileList.length === 0) {
this.$message({ message: '请选择要上传的文件!', type: 'error', offset: 8 })
return false
}
this.nowDate = getCurrentTime()
const jsonArrayToSend = []
this.isSyncUpload = true
// 使 Promise.all
Promise.all(this.$refs.uploader.fileList.map(async(item) => {
console.log('item', item)
const json = {}
const jsonArray = []
const jsonString = {}
if (item.file.type.substring(0, item.file.type.indexOf('/')) === 'image') {
const fileBase64 = await this.getBase64(item.file)
const imgRes = await this.getImgPx(fileBase64)
item.file.px = imgRes.width + 'px*' + imgRes.height + 'px'
} else {
item.file.px = ''
}
jsonString.file_name = item.file.name
jsonString.file_size = item.file.size
jsonString.file_type = item.file.name.substring(item.name.lastIndexOf('.') + 1, item.file.name.length)
json.last_modified = item.file.lastModified
jsonString.file_path = ''
jsonString.sequence = null
jsonString.archive_id = this.arcId
jsonString.file_dpi = item.file.px
jsonString.file_thumbnail = ''
jsonString.create_time = this.nowDate
jsonString.id = null
jsonArray.push(jsonString)
console.log('isBatchMount', this.isBatchMount)
console.log('isBatchMount', typeof this.isBatchMount)
if (this.isBatchMount === 'true') {
json.categoryId = this.selectedCategory.id
} else {
json.documentId = this.selectedDocument.id
}
json.archivesId = this.arcId
json.identifier = item.uniqueIdentifier
json.filename = item.name
json.totalChunks = item.chunks.length - 1
json.totalSize = item.size
json.fileJsonString = JSON.stringify(jsonArray)
jsonArrayToSend.push(json)
})).then(() => {
console.log('jsonArrayToSend', jsonArrayToSend)
if (this.$refs.uploader.fileList.every(item => item.completed) && this.isUpload) {
if (this.isBatchMount === 'true') {
axios.post(this.baseApi + '/api/collect/merge', jsonArrayToSend, {
headers: {
'Authorization': getToken()
}
}).then((res) => {
console.log(res)
if (res.data.code === 200 && res.data.data[0] !== '') {
this.$message({ message: '文件上传成功', type: 'success', offset: 8 })
this.$emit('onUploadSuccess', res.data.data, this.fileName, jsonArrayToSend)
} else {
this.$message({ message: '文件上传失败', type: 'error', offset: 8 })
}
this.isSyncUpload = false
setTimeout(() => {
this.isUpload = false
}, 2000)
}).catch(err => {
this.isSyncUpload = false
setTimeout(() => {
this.isUpload = false
}, 2000)
this.$emit('onUploadError', err)
this.$message({ message: '上传服务器失败', type: 'error', offset: 8 })
clearInterval(this.queryTimer)
})
} else {
axios.post(this.baseApi + '/api/re-document/merge', jsonArrayToSend, {
headers: {
'Authorization': getToken()
}
}).then((res) => {
console.log(res)
if (res.data.code === 200 && res.data.data !== '') {
this.$message({ message: '文件上传成功', type: 'success', offset: 8 })
this.$emit('onUploadSuccess', res.data.data, this.fileName, jsonArrayToSend)
} else {
this.$message({ message: '文件上传失败', type: 'error', offset: 8 })
}
this.isSyncUpload = false
}).catch(err => {
this.isSyncUpload = false
setTimeout(() => {
this.isUpload = false
}, 2000)
this.$emit('onUploadError', err)
this.$message({ message: '上传服务器失败', type: 'error', offset: 8 })
clearInterval(this.queryTimer)
})
}
} else {
this.isSyncUpload = false
setTimeout(() => {
this.isUpload = false
}, 2000)
this.$message({ message: '请耐心等待文件上传完成后再保存!', type: 'error', offset: 8 })
}
})
},
//
onFileError(rootFile, file, response, chunk) {
this.$message({ message: '上传失败', type: 'error', offset: 8 })
this.$emit('onUploadError', response)
this.isUpload = false
},
// base64
getBase64(file) {
const reader = new FileReader()
reader.readAsDataURL(file)
return new Promise((resolve) => {
reader.onload = () => {
resolve(reader.result)
}
})
},
//
getImgPx(img) {
const image = new Image()
image.src = img
return new Promise((resolve) => {
image.onload = () => {
const width = image.width
const height = image.height
resolve({ width, height })
}
})
}
}
}
</script>
<style lang="scss" scoped>
.uploader-big{
position: relative;
// width: 100%;
margin-left: 10px;
.uploader{
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
text-align: center;
margin-bottom: 8px;
.uploader-drop{
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
width: 100px;
height: 34px;
padding: 0;
border: 1px solid #0348f3;
background-color: transparent;
border-radius: 4px;
.uploader-btn{
width: 100%;
margin: 0;
padding: 0;
border: none;
color: #0348f3;
line-height: 36px;
i{
font-size: 20px;
color: #1F55EB;
}
&:hover{
background-color: transparent;
}
}
.el-upload__tip{
font-size: 12px;
color: #A6ADB6;
}
}
}
}
.upload_process_box{
position: absolute;
right: 0;
top: 44px;
width: 540px;
border-radius: 5px;
border: 1px dashed #409eff;
padding: 10px 0;
}
.uploader-file[status="success"] .uploader-file-remove {
display:block
}
::v-deep .uploader-list{
max-height: 344px;
overflow-y: scroll;
.uploader-file-size{
text-align: right !important;
}
.uploader-file-icon:before{
content: "";
}
.uploader-file-name{
text-align: left !important;
}
.uploader-file{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/attachment.png") no-repeat;
background-size: 100% 100%;
}
&.icon-image{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/image.png") no-repeat;
background-size: 100% 100%;
}
}
&.icon-excel,&.icon-xlsx,&.icon-xls{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/excel.png") no-repeat;
background-size: 100% 100%;
}
}
&.icon-pdf{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/pdf.png") no-repeat;
background-size: 100% 100%;
}
}
&.icon-ppt, &.icon-pptx{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/ppt.png") no-repeat;
background-size: 100% 100%;
}
}
&.icon-word,&.icon-docx,&.icon-doc{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/word.png") no-repeat;
background-size: 100% 100%;
}
}
&.icon-zip,&.icon-rar{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/zip.png") no-repeat;
background-size: 100% 100%;
}
}
&.icon-txt{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/txt.png") no-repeat;
background-size: 100% 100%;
}
}
&.icon-ofd{
.uploader-file-icon:before{
background: url("~@/assets/images/fileIcon/OFD.png") no-repeat;
background-size: 100% 100%;
}
}
}
}
</style>

22
src/views/prearchiveLibrary/index.vue

@ -120,7 +120,7 @@
@close-dialog="closeDialog" @close-dialog="closeDialog"
@formLoadingShow="formLoadingShow" @formLoadingShow="formLoadingShow"
/> />
<div slot="footer" class="dialog-footer" style="margin-top: 85px !important;">
<div slot="footer" class="dialog-footer" style="margin-top: 20px !important;">
<el-button type="text" @click="closeDialog">取消</el-button> <el-button type="text" @click="closeDialog">取消</el-button>
<el-button :loading="archivesBtnLoading" type="primary" @click="handlerArchivesSubmit">确定</el-button> <el-button :loading="archivesBtnLoading" type="primary" @click="handlerArchivesSubmit">确定</el-button>
</div> </div>
@ -271,6 +271,7 @@ export default {
}, },
getFormInfo(params, type) { getFormInfo(params, type) {
PrearchiveCrud.FetchDoeditDocument(params).then(data => { PrearchiveCrud.FetchDoeditDocument(params).then(data => {
console.log('data', data)
const showFiledAll = data.showFiled.filter(item => item.isSequence).sort((a, b) => a.isSequence - b.isSequence) const showFiledAll = data.showFiled.filter(item => item.isSequence).sort((a, b) => a.isSequence - b.isSequence)
this.$nextTick(() => { this.$nextTick(() => {
this.formPreviewData = showFiledAll this.formPreviewData = showFiledAll
@ -281,11 +282,16 @@ export default {
if (type === 'edit') { if (type === 'edit') {
this.$refs.previewForm.archivesType = 'edit' this.$refs.previewForm.archivesType = 'edit'
this.$refs.previewForm.addOrUpdateForm = data.echo this.$refs.previewForm.addOrUpdateForm = data.echo
const fileecho = []
fileecho.push(data.fileecho)
// this.$refs.previewForm.addOrUpdateForm.fileOriginal = fileecho[0].file_name
this.$refs.previewForm.fileOriginal = fileecho[0].file_name
this.$refs.previewForm.fileJsonString = JSON.stringify(fileecho)
if (data.fileecho) {
const fileecho = []
fileecho.push(data.fileecho)
// this.$refs.previewForm.addOrUpdateForm.fileOriginal = fileecho[0].file_name
this.$refs.previewForm.fileOriginal = fileecho[0].file_name
this.$refs.previewForm.fileJsonString = JSON.stringify(fileecho)
} else {
this.$refs.previewForm.fileOriginal = ''
this.$refs.previewForm.fileJsonString = ''
}
} else { } else {
this.$refs.previewForm.archivesType = 'add' this.$refs.previewForm.archivesType = 'add'
} }
@ -442,6 +448,8 @@ export default {
<style lang='scss' scoped> <style lang='scss' scoped>
.preview-dialog .el-dialog .preview-content { .preview-dialog .el-dialog .preview-content {
// height: calc(100vh - 290px) !important;
height: calc(100vh - 290px) !important;
} }
</style> </style>
Loading…
Cancel
Save