添加MD5组件,修改切片上传
This commit is contained in:
parent
0c97e64765
commit
61c286349c
|
@ -31,6 +31,7 @@
|
||||||
"md5": "^2.2.1",
|
"md5": "^2.2.1",
|
||||||
"npm": "^6.14.11",
|
"npm": "^6.14.11",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
"spark-md5": "^3.0.2",
|
||||||
"tinymce": "^5.3.2",
|
"tinymce": "^5.3.2",
|
||||||
"viser-vue": "^2.4.8",
|
"viser-vue": "^2.4.8",
|
||||||
"vue": "^2.6.10",
|
"vue": "^2.6.10",
|
||||||
|
@ -56,13 +57,13 @@
|
||||||
"@vue/cli-service": "^3.3.0",
|
"@vue/cli-service": "^3.3.0",
|
||||||
"@vue/eslint-config-standard": "^4.0.0",
|
"@vue/eslint-config-standard": "^4.0.0",
|
||||||
"babel-eslint": "7.2.3",
|
"babel-eslint": "7.2.3",
|
||||||
|
"compression-webpack-plugin": "^3.1.0",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
"eslint-plugin-vue": "^5.1.0",
|
"eslint-plugin-vue": "^5.1.0",
|
||||||
|
"html-webpack-plugin": "^4.2.0",
|
||||||
"less": "^3.9.0",
|
"less": "^3.9.0",
|
||||||
"less-loader": "^4.1.0",
|
"less-loader": "^4.1.0",
|
||||||
"vue-template-compiler": "^2.6.10",
|
"vue-template-compiler": "^2.6.10"
|
||||||
"html-webpack-plugin": "^4.2.0",
|
|
||||||
"compression-webpack-plugin": "^3.1.0"
|
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|
|
@ -2,11 +2,11 @@ import { getAction, deleteAction, putAction, postAction, httpAction,uploadAction
|
||||||
|
|
||||||
const getFileLinkInfo = (params)=>getAction("/fileDataLink/getFileLinkInfo",params);
|
const getFileLinkInfo = (params)=>getAction("/fileDataLink/getFileLinkInfo",params);
|
||||||
const processFile = (params)=>postAction("/fileDataLink/processFile",params);
|
const processFile = (params)=>postAction("/fileDataLink/processFile",params);
|
||||||
|
const fileDataLinkDelete = (params)=>deleteAction("/fileDataLink/delete",params);
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getFileLinkInfo,
|
getFileLinkInfo,
|
||||||
processFile
|
processFile,
|
||||||
|
fileDataLinkDelete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,35 @@ export function downloadFile(url, fileName, parameter) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
* @param url 文件路径
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @param parameter
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
export function downloadFile2 (fileName, parameter, downloadUrl) {
|
||||||
|
return downFile(downloadUrl || fileApi.FileDown, parameter).then((data) => {
|
||||||
|
if (!data || data.size === 0) {
|
||||||
|
message.error('文件不存在,请重新上传文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
||||||
|
window.navigator.msSaveBlob(new Blob([data]), fileName)
|
||||||
|
} else {
|
||||||
|
const url = window.URL.createObjectURL(new Blob([data]))
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.style.display = 'none'
|
||||||
|
link.href = url
|
||||||
|
link.setAttribute('download', fileName)
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link) // 下载完成移除元素
|
||||||
|
window.URL.revokeObjectURL(url) // 释放掉blob对象
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传 用于富文本上传图片
|
* 文件上传 用于富文本上传图片
|
||||||
* @param url
|
* @param url
|
||||||
|
|
440
src/views/datalink/modules/SliceUpload.vue
Normal file
440
src/views/datalink/modules/SliceUpload.vue
Normal file
|
@ -0,0 +1,440 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-row type="flex">
|
||||||
|
<a-col flex="auto">
|
||||||
|
<a-upload
|
||||||
|
class="upload-wrapper"
|
||||||
|
:showUploadList="false"
|
||||||
|
:disabled="maxFile && tableDate.length >= maxFile"
|
||||||
|
:accept="accept"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:customRequest="customRequestUpload"
|
||||||
|
:multiple="true"
|
||||||
|
@change="handleChange">
|
||||||
|
<!-- <a-input style="width:100%" :value="fileList.map(item=> item.name).join('、')" /> -->
|
||||||
|
<a-button :disabled="maxFile && tableDate.length >= maxFile">
|
||||||
|
<a-icon type="upload" /> 文档上传
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-col>
|
||||||
|
<a-col flex="100px" v-if="false" >
|
||||||
|
<a-button @click="customRequestUpload">
|
||||||
|
<a-icon type="upload" /> 文档上传
|
||||||
|
</a-button>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<div class="result-wrapper" :style="{minHeight: boxHeight + 'px'}" >
|
||||||
|
<div class="item" v-for="(file,idx) in tableDate" :key="file.uid">
|
||||||
|
<div class="content">
|
||||||
|
<div class="body">
|
||||||
|
<div class="fileName"> {{ file.fileName }}</div>
|
||||||
|
<div>
|
||||||
|
<a-space>
|
||||||
|
<a-button v-if="canDownload" type="link" style="padding: 0" @click="handleDownload(file)">下载</a-button>
|
||||||
|
<a-popconfirm
|
||||||
|
title="是否确认删除该文件?"
|
||||||
|
@confirm="handleDelete(file, idx)"
|
||||||
|
>
|
||||||
|
<a-icon style="margin-left:10px; cursor: pointer;" type="delete" />
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
class="progress"
|
||||||
|
v-if="autoUpload"
|
||||||
|
:percent="file.percentage"
|
||||||
|
:strokeWidth="3"
|
||||||
|
:showInfo="false" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<slot name="extra" :idx="idx" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SparkMD5 from 'spark-md5'
|
||||||
|
import { postAction,downloadFile2 } from '@/api/manage'
|
||||||
|
import { verifyFileExist } from '@/api/fileapi'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SliceUpload',
|
||||||
|
props: {
|
||||||
|
boxHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line vue/require-default-prop
|
||||||
|
maxFile: Number,
|
||||||
|
accept: {
|
||||||
|
type: String,
|
||||||
|
default: '.jpg,.png,.doc,.docx,.pdf,.txt,.jpeg'
|
||||||
|
},
|
||||||
|
autoUpload: { // 自动上传
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
canRepeat: { // 是否可上传重复的文件
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
canDownload: { // 是否显示下载按钮
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
dataLinkType: {
|
||||||
|
type: String,
|
||||||
|
default: '1'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
fileMD5: {},
|
||||||
|
isStop: false,
|
||||||
|
fileList: [],
|
||||||
|
tableDate: [],
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
stop (record) {
|
||||||
|
this.isStop = true
|
||||||
|
record.uploadStatus = 0
|
||||||
|
},
|
||||||
|
start (record, index) {
|
||||||
|
const file = this.fileList[index].originFileObj
|
||||||
|
const currentRow = this.tableDate.find((row) => row.uid === file.uid)
|
||||||
|
this.isStop = false
|
||||||
|
record.uploadStatus = 1
|
||||||
|
this.uploadByPieces({
|
||||||
|
file, // 文件信息
|
||||||
|
currentRow,
|
||||||
|
success: (data) => {
|
||||||
|
record.percentage = 100
|
||||||
|
},
|
||||||
|
error: (e) => {
|
||||||
|
record.percentage = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 从外部设置已有文件列表
|
||||||
|
setFileList (fileList) {
|
||||||
|
this.tableDate = fileList
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteFile () {
|
||||||
|
this.fileList = []
|
||||||
|
this.tableDate = []
|
||||||
|
},
|
||||||
|
getFileList () {
|
||||||
|
return this.tableDate
|
||||||
|
},
|
||||||
|
bytesToSize (bytes) {
|
||||||
|
if (bytes === 0) return '0 B'
|
||||||
|
const k = 1024
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
|
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]
|
||||||
|
},
|
||||||
|
handleDelete (file, idx) {
|
||||||
|
this.tableDate.splice(idx, 1)
|
||||||
|
delete this.fileMD5[file.uid]
|
||||||
|
},
|
||||||
|
async beforeUpload (file) {
|
||||||
|
if (!this.canRepeat) {
|
||||||
|
const md5 = await this.getMd5(file, file.size)
|
||||||
|
const find = Object.values(this.fileMD5).find(v => {
|
||||||
|
return v === md5
|
||||||
|
})
|
||||||
|
if (!this.canRepeat && find) {
|
||||||
|
this.$message.warning(`文件重复,重复的文件为:${file.name}`)
|
||||||
|
throw new Error('file repeat')
|
||||||
|
} else {
|
||||||
|
this.fileMD5[file.uid] = md5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fileList.push(file)
|
||||||
|
// uploadStatus 上传状态 1开始 0暂停 2完成
|
||||||
|
this.tableDate.push({
|
||||||
|
fileData: file,
|
||||||
|
uid: file.uid,
|
||||||
|
fileName: file.name,
|
||||||
|
size: file.size,
|
||||||
|
type: file.type,
|
||||||
|
percentage: 0,
|
||||||
|
uploadStatus: 1,
|
||||||
|
remarks: ''
|
||||||
|
})
|
||||||
|
if (!this.autoUpload) {
|
||||||
|
throw new Error('not auto upload')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 自定义上传事件
|
||||||
|
*/
|
||||||
|
customRequestUpload ({ file }) {
|
||||||
|
// 开始执行上传逻辑
|
||||||
|
const currentRow = this.tableDate.find((row) => row.uid === file.uid)
|
||||||
|
if (currentRow) {
|
||||||
|
// 当前上传进度归0
|
||||||
|
currentRow.percentage = 0
|
||||||
|
const _20M = 20 * 1024 * 1024
|
||||||
|
if (file.size > _20M) { // 20M 以上分片上传
|
||||||
|
this.uploadByPieces({ // 这里走分片上传逻辑
|
||||||
|
file, // 文件信息
|
||||||
|
currentRow,
|
||||||
|
success: (data) => {
|
||||||
|
currentRow.percentage = 100
|
||||||
|
},
|
||||||
|
error: (e) => {
|
||||||
|
currentRow.percentage = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else { // 20M 以下直接上传
|
||||||
|
this.uploadDirectly(currentRow, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getMd5 (file, chunkSize) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
|
||||||
|
const chunks = Math.ceil(file.size / chunkSize)
|
||||||
|
let currentChunk = 0
|
||||||
|
const spark = new SparkMD5.ArrayBuffer() // 追加数组缓冲区。
|
||||||
|
const fileReader = new FileReader() // 读取文件
|
||||||
|
fileReader.onload = function (e) {
|
||||||
|
spark.append(e.target.result)
|
||||||
|
currentChunk++
|
||||||
|
if (currentChunk < chunks) {
|
||||||
|
loadNext()
|
||||||
|
} else {
|
||||||
|
const md5 = spark.end() // 完成md5的计算,返回十六进制结果。
|
||||||
|
resolve(md5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileReader.onerror = function (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNext () {
|
||||||
|
const start = currentChunk * chunkSize
|
||||||
|
let end = start + chunkSize
|
||||||
|
end > file.size && (end = file.size)
|
||||||
|
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
|
||||||
|
}
|
||||||
|
loadNext()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
buildFileFormData (fileName, fileSize, md5Value, shareTotal, shareIndex, file, fileShare) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('fileName', fileName)
|
||||||
|
formData.append('fileSize', fileSize)
|
||||||
|
formData.append('fileExt', fileName.substring(fileName.lastIndexOf('.')))
|
||||||
|
formData.append('md5Value', md5Value)
|
||||||
|
formData.append('shareTotal', shareTotal)
|
||||||
|
formData.append('shareIndex', shareIndex)
|
||||||
|
formData.append('file', file)
|
||||||
|
formData.append('fileShare', fileShare)
|
||||||
|
formData.append("dataLinkType",this.dataLinkType);
|
||||||
|
return formData
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接上传
|
||||||
|
* @param {File} file file文件
|
||||||
|
*/
|
||||||
|
async uploadDirectly (currentRow, file) {
|
||||||
|
let fileMD5Value = this.fileMD5[file.uid]
|
||||||
|
if (!fileMD5Value) {
|
||||||
|
fileMD5Value = await this.getMd5(file, file.size)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await verifyFileExist({ fileMD5Value })
|
||||||
|
if (res.exist) { // 跳过文件验证逻辑
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = res
|
||||||
|
} else { // 未存在,走上传逻辑
|
||||||
|
const formData = this.buildFileFormData(file.name, file.size, fileMD5Value, 0, 0, file, false)
|
||||||
|
const url = '/fileDataLink/uploadFile'
|
||||||
|
try {
|
||||||
|
const res = await postAction(url, formData)
|
||||||
|
if (res) {
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = {
|
||||||
|
fileId: res.id
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentRow.percentage = 0
|
||||||
|
currentRow.uploadStatus = 1
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
this.$message.error('获取文件是否已上传状态失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 断点分片上传
|
||||||
|
uploadByPieces ({ file, currentRow, success, error }) {
|
||||||
|
// const that = this
|
||||||
|
// 上传过程中用到的变量
|
||||||
|
var slicingSize = null
|
||||||
|
if (file.size <= 20971520) {
|
||||||
|
// 20M以内,单个切片大小设置为2MB
|
||||||
|
slicingSize = 2 * 1024 * 1024 // 切片大小 单位MB
|
||||||
|
} else if (file.size <= 524288000) {
|
||||||
|
// 500M以内,单个切片大小设置为5MB
|
||||||
|
slicingSize = 5 * 1024 * 1024 // 切片大小 单位MB
|
||||||
|
} else {
|
||||||
|
// 500M以外,单个切片大小设置为10MB
|
||||||
|
slicingSize = 10 * 1024 * 1024 // 切片大小 单位MB
|
||||||
|
}
|
||||||
|
const sumSlicingCount = Math.ceil(file.size / slicingSize) // 总片数
|
||||||
|
|
||||||
|
currentRow.remarks = '正在获取hash值...'
|
||||||
|
this.getMd5(file, slicingSize)
|
||||||
|
.then((res) => {
|
||||||
|
this.fileMD5[file.uid] = res
|
||||||
|
|
||||||
|
currentRow.remarks = ''
|
||||||
|
this.readFileMD5(file, currentRow, slicingSize, sumSlicingCount, success, error)
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error('MD5计算错误', e)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 得到某一片的分片 file 总文件; currentIndex 当前切片数,按索引计算; slicingSize 切片大小
|
||||||
|
getSlicingInfo (file, currentIndex, slicingSize) {
|
||||||
|
const start = currentIndex * slicingSize
|
||||||
|
const end = Math.min(file.size, start + slicingSize)
|
||||||
|
const slicingInfo = file.slice(start, end)
|
||||||
|
return slicingInfo
|
||||||
|
},
|
||||||
|
// 开始执行切片上传
|
||||||
|
readFileMD5 (file, currentRow, slicingSize, sumSlicingCount, success, error) {
|
||||||
|
// 检查文件有没有上传过的状态
|
||||||
|
verifyFileExist({ fileMD5Value: this.fileMD5[file.uid] })
|
||||||
|
.then((res) => {
|
||||||
|
const { exist, shareTotal, shareIndex } = res
|
||||||
|
if (exist) {
|
||||||
|
if (shareIndex === (shareTotal - 1)) { // 相等说之前已经上传完整
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = res
|
||||||
|
} else { // 不相等说明之前上传中断了,接着再上传
|
||||||
|
const pross = (shareIndex + 1 / sumSlicingCount) * 100 // 计算之前上传的进度
|
||||||
|
currentRow.percentage = Number(pross.toFixed(2))
|
||||||
|
this.uploadSliceFile(file, currentRow, slicingSize, sumSlicingCount, shareIndex + 1, success, error)
|
||||||
|
}
|
||||||
|
} else { // 没有传过就从第0个分片开始上传
|
||||||
|
this.uploadSliceFile(file, currentRow, slicingSize, sumSlicingCount, 0, success, error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
error && error(e)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 对切片文件进行上传
|
||||||
|
* @param {File} file
|
||||||
|
*/
|
||||||
|
uploadSliceFile (file, currentRow, slicingSize, sumSlicingCount, currIndex, success, error) {
|
||||||
|
if (currIndex < sumSlicingCount && !this.isStop) {
|
||||||
|
// 得到当前需要上传的分片文件
|
||||||
|
const currentInfo = this.getSlicingInfo(file, currIndex, slicingSize)
|
||||||
|
const result = new File([currentInfo], currIndex, { type: file.type, lastModified: Date.now() })
|
||||||
|
const formData = this.buildFileFormData(file.name, file.size, this.fileMD5[file.uid], sumSlicingCount, currIndex, result, true)
|
||||||
|
|
||||||
|
// 开始上传
|
||||||
|
const url = '/fileDataLink/uploadFile'
|
||||||
|
postAction(url, formData).then((res) => {
|
||||||
|
const { completed, id } = res
|
||||||
|
if (completed) { // 已上传完毕
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = {
|
||||||
|
fileId: id
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 每上传一个就在进度条上加数据
|
||||||
|
const pross = ((currIndex + 1) / sumSlicingCount) * 100
|
||||||
|
currentRow.percentage = Number(pross.toFixed(2))
|
||||||
|
this.uploadSliceFile(file, currentRow, slicingSize, sumSlicingCount, currIndex + 1, success, error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleChange (info) {
|
||||||
|
this.fileList = [...info.fileList]
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*/
|
||||||
|
handleDownload ({ fileName: filterWordName, filePath: filterWordPath }) {
|
||||||
|
downloadFile2(filterWordName, { filterWordName, filterWordPath }, '/file/verifyFileExist')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.upload-wrapper{
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(100% - 10px);
|
||||||
|
/deep/.ant-upload{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-wrapper {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border: 1px solid #D9DADB;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #666666;
|
||||||
|
line-height: 36px;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
.body {
|
||||||
|
position: relative;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.fileName {
|
||||||
|
max-width: 400px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -10,19 +10,14 @@
|
||||||
cancelText="关闭">
|
cancelText="关闭">
|
||||||
|
|
||||||
<a-spin :spinning="confirmLoading">
|
<a-spin :spinning="confirmLoading">
|
||||||
<a-upload
|
<SliceUpload
|
||||||
directory
|
ref="technicalUpload"
|
||||||
v-model:fileList="fileList"
|
:box-height="50"
|
||||||
:customRequest="customRequest"
|
:max-file="9999"
|
||||||
:beforeUpload="beforeUpload"
|
:can-download="false"
|
||||||
@change="handleChange"
|
accept=".csv,.txt"
|
||||||
:multiple="true"
|
:dataLinkType='dataLinkType'
|
||||||
>
|
/>
|
||||||
<a-button>
|
|
||||||
<upload-outlined></upload-outlined>
|
|
||||||
选择文件夹上传(仅.txt/.csv)
|
|
||||||
</a-button>
|
|
||||||
</a-upload>
|
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
@ -31,96 +26,32 @@
|
||||||
import moment from "moment"
|
import moment from "moment"
|
||||||
import JCron from "@/components/jeecg/JCron";
|
import JCron from "@/components/jeecg/JCron";
|
||||||
import JSelectMultiple from '@/components/jeecg/JSelectMultiple'
|
import JSelectMultiple from '@/components/jeecg/JSelectMultiple'
|
||||||
import pick from 'lodash.pick'
|
import SliceUpload from './SliceUpload'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "fileDataLinkModal",
|
name: "uploadModal",
|
||||||
components: {
|
components: {
|
||||||
JCron,
|
JCron,
|
||||||
JSelectMultiple
|
JSelectMultiple,
|
||||||
|
SliceUpload
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
title:"操作",
|
title:"操作",
|
||||||
buttonStyle: 'solid',
|
buttonStyle: 'solid',
|
||||||
visible: false,
|
visible: false,
|
||||||
dateFormat:'YYYY-MM-DD HH:mm',
|
|
||||||
status:'',
|
|
||||||
model: {},
|
|
||||||
confirmLoading: false,
|
confirmLoading: false,
|
||||||
form: this.$form.createForm(this),
|
|
||||||
strategys:[],
|
strategys:[],
|
||||||
dataStrategySelected:'',
|
dataLinkType:''
|
||||||
idcDataStrategyId:"",
|
|
||||||
shipMode:{},
|
|
||||||
shipNum:{},
|
|
||||||
rangeTime:[],
|
|
||||||
queryParam: {
|
|
||||||
pageNum :1,
|
|
||||||
pageSize:20
|
|
||||||
},
|
|
||||||
labelCol: {
|
|
||||||
xs: { span: 24 },
|
|
||||||
sm: { span: 5 },
|
|
||||||
},
|
|
||||||
wrapperCol: {
|
|
||||||
xs: { span: 24 },
|
|
||||||
sm: { span: 16 },
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
this.loadData();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadData() {
|
|
||||||
shipModelPageList(this.queryParam).then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
this.shipMode = res.result.rows
|
|
||||||
} else {
|
|
||||||
this.$message.warning(res.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
shipNumPageList(this.queryParam).then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
this.shipNum = res.result.rows
|
|
||||||
} else {
|
|
||||||
this.$message.warning(res.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
filterOption(input, option) {
|
|
||||||
return (
|
|
||||||
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
|
||||||
);
|
|
||||||
},
|
|
||||||
selectModel(value){
|
|
||||||
shipNumQueryByModelId({modelId:value}).then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
this.shipNum = res.result
|
|
||||||
} else {
|
|
||||||
this.$message.warning(res.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
add () {
|
add () {
|
||||||
this.rangeTime=[];
|
|
||||||
this.edit({});
|
|
||||||
},
|
|
||||||
edit (record) {
|
|
||||||
this.visible =true;
|
this.visible =true;
|
||||||
let that = this;
|
|
||||||
that.form.resetFields();
|
|
||||||
this.model = Object.assign({},record);
|
|
||||||
this.rangeTime.push(moment(this.model.startTime),moment(this.model.endTime))
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.form.setFieldsValue(pick(this.model,'name','describe','shipModelId','shipNumId'));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onChange(value, dateString) {
|
|
||||||
this.model.startDate = dateString[0];
|
|
||||||
this.model.endDate = dateString[1];
|
|
||||||
},
|
},
|
||||||
onOk(value) {
|
onOk(value) {
|
||||||
this.model.startDate = moment(value[0],dateFormat);
|
this.model.startDate = moment(value[0],dateFormat);
|
||||||
|
@ -131,45 +62,7 @@ import pick from 'lodash.pick'
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
},
|
},
|
||||||
handleOk () {
|
handleOk () {
|
||||||
const that = this;
|
this.close();
|
||||||
// 触发表单验证
|
|
||||||
this.form.validateFields((err, values) => {
|
|
||||||
console.log('values',values)
|
|
||||||
if (!err) {
|
|
||||||
that.confirmLoading = true;
|
|
||||||
if(!this.model.id){
|
|
||||||
this.model.name = values.name;
|
|
||||||
this.model.shipModelId = values.shipModelId;
|
|
||||||
this.model.shipNumId = values.shipNumId;
|
|
||||||
this.model.describe = values.describe;
|
|
||||||
taskCreate(this.model).then((res)=>{
|
|
||||||
if(res.success){
|
|
||||||
that.$message.success(res.message);
|
|
||||||
that.$emit('ok');
|
|
||||||
}else{
|
|
||||||
that.$message.warning(res.message);
|
|
||||||
}
|
|
||||||
}).finally(() => {
|
|
||||||
that.confirmLoading = false;
|
|
||||||
that.close();
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
taskUpdateById({id:this.model.id,name:values.name,describe:values.describe,shipModelId:values.shipModelId,shipNumId:values.shipNumId,
|
|
||||||
startTime:this.model.startTime,endTime:this.model.endTime
|
|
||||||
}).then((res)=>{
|
|
||||||
if(res.success){
|
|
||||||
that.$message.success(res.message);
|
|
||||||
that.$emit('ok');
|
|
||||||
}else{
|
|
||||||
that.$message.warning(res.message);
|
|
||||||
}
|
|
||||||
}).finally(() => {
|
|
||||||
that.confirmLoading = false;
|
|
||||||
that.close();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
handleCancel () {
|
handleCancel () {
|
||||||
this.close()
|
this.close()
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<a-col :md="6" :sm="24" >
|
<a-col :md="6" :sm="24" >
|
||||||
<a-button type="primary" style="left: 10px" @click="loadData" icon="search">查询</a-button>
|
<a-button type="primary" style="left: 10px" @click="loadData" icon="search">查询</a-button>
|
||||||
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px;left: 10px">重置</a-button>
|
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px;left: 10px">重置</a-button>
|
||||||
<a-button type="primary" style="left: 10px" @click="handleAdd" icon="upload">上传</a-button>
|
<a-button type="primary" @click="handleAdd" icon="upload" style="margin-left: 8px;left: 10px">上传</a-button>
|
||||||
</a-col>
|
</a-col>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
@ -60,19 +60,18 @@
|
||||||
<!-- table区域-end -->
|
<!-- table区域-end -->
|
||||||
|
|
||||||
<!-- 表单区域 -->
|
<!-- 表单区域 -->
|
||||||
<uploadModal ref="modalForm" @ok="modalFormOk"></uploadModal>
|
<uploadModal ref="modalForm"></uploadModal>
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import uploadModal from './modules/uploadModal'
|
import uploadModal from './modules/uploadModal'
|
||||||
import { getFileLinkInfo,
|
import { getFileLinkInfo,processFile,fileDataLinkDelete } from '@/api/fileDataLink'
|
||||||
processFile } from '@/api/fileDataLink'
|
|
||||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||||
import JEllipsis from "@/components/jeecg/JEllipsis";
|
import JEllipsis from "@/components/jeecg/JEllipsis";
|
||||||
|
import {deleteAction, postAction} from '@/api/manage'
|
||||||
export default {
|
export default {
|
||||||
name: "filelink",
|
name: "waterDocuments",
|
||||||
mixins:[JeecgListMixin],
|
mixins:[JeecgListMixin],
|
||||||
components: {
|
components: {
|
||||||
uploadModal,
|
uploadModal,
|
||||||
|
@ -159,7 +158,7 @@
|
||||||
loadData() {
|
loadData() {
|
||||||
getFileLinkInfo(this.queryParam).then((res) => {
|
getFileLinkInfo(this.queryParam).then((res) => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
this.dataSource = res.result.rows||res.result;
|
this.dataSource = res.result;
|
||||||
if(res.result.total)
|
if(res.result.total)
|
||||||
{
|
{
|
||||||
this.ipagination.total = res.result.total;
|
this.ipagination.total = res.result.total;
|
||||||
|
@ -171,13 +170,13 @@
|
||||||
},
|
},
|
||||||
handleDelete: function (id) {
|
handleDelete: function (id) {
|
||||||
var that = this;
|
var that = this;
|
||||||
taskDeleteById({id: id}).then((res) => {
|
deleteAction("/fileDataLink/delete?id="+id,{}).then((res) => {
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
that.$message.success(res.message);
|
this.$message.success(res.message);
|
||||||
that.loadData();
|
that.loadData();
|
||||||
} else {
|
} else {
|
||||||
that.$message.warning(res.message);
|
this.$message.warning(res.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
processFile: function (record) {
|
processFile: function (record) {
|
||||||
|
@ -191,20 +190,10 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleDistribute:function (id) {
|
|
||||||
var that = this;
|
|
||||||
taskDistributeTask({id: id}).then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
that.$message.success(res.message);
|
|
||||||
that.loadData();
|
|
||||||
} else {
|
|
||||||
that.$message.warning(res.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
this.$refs.modalForm.add();
|
this.$refs.modalForm.add();
|
||||||
this.$refs.modalForm.title = "文件上传";
|
this.$refs.modalForm.title = "文件上传";
|
||||||
|
this.$refs.modalForm.dataLinkType=this.queryParam.dataLinkType;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,14 +108,10 @@
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12" style="text-align: right;">
|
<a-col :span="12" style="text-align: right;">
|
||||||
<input
|
<a-button type="primary" style="margin-left: 8px" @click="clickfile">
|
||||||
type="file"
|
<a-icon type="upload"/>
|
||||||
@change="getUpFileData" style="display:none;" id="file">
|
文件上传
|
||||||
<a-button type="primary" style="margin-left: 8px" @click="clickfile">
|
</a-button>
|
||||||
<a-icon type="upload"/>
|
|
||||||
文件上传
|
|
||||||
</a-button>
|
|
||||||
</input>
|
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
|
@ -134,14 +130,19 @@
|
||||||
<a-modal v-model:open="isopen" :title="modalTitle" ok-text="确认" cancel-text="取消" @ok="hideModal">
|
<a-modal v-model:open="isopen" :title="modalTitle" ok-text="确认" cancel-text="取消" @ok="hideModal">
|
||||||
<a-input placeholder="请输入" v-model="dirName" style="color: #000000 !important"></a-input>
|
<a-input placeholder="请输入" v-model="dirName" style="color: #000000 !important"></a-input>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
<uploadModal ref="modalForm"></uploadModal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import uploadModal from './modules/uploadModal'
|
||||||
import guaz from '@assets/guaz.png'
|
import guaz from '@assets/guaz.png'
|
||||||
import {createDir,logicDelDir,renameDir,dirtreeList} from '@/api/dirapi'
|
import {createDir,logicDelDir,renameDir,dirtreeList} from '@/api/dirapi'
|
||||||
import {downloadFile,filePreview,logicDeleteFile,pageList,uoloadFile} from '@/api/fileapi'
|
import {downloadFile,filePreview,logicDeleteFile,pageList,uoloadFile} from '@/api/fileapi'
|
||||||
export default {
|
export default {
|
||||||
name: "fileManage",
|
name: "fileManage",
|
||||||
|
components: {
|
||||||
|
uploadModal
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dirName:"",
|
dirName:"",
|
||||||
|
@ -230,37 +231,17 @@ export default {
|
||||||
this.getDirList();
|
this.getDirList();
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
uploadAction() {
|
|
||||||
return window._CONFIG['domianURL'] + "/file/uoloadFile";
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clickfile(){
|
clickfile(){
|
||||||
document.getElementById("file").click();
|
|
||||||
},
|
|
||||||
getUpFileData(e){
|
|
||||||
if(this.selectId == "0"){
|
if(this.selectId == "0"){
|
||||||
this.$message.warning("必须选择查询目录");
|
this.$message.warning("必须选择文件上传目录");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let formData = new FormData()
|
this.$refs.modalForm.add();
|
||||||
const file = e.target.files[0];
|
this.$refs.modalForm.title = "文件上传";
|
||||||
formData.append('dirId', this.selectId);
|
this.$refs.modalForm.dirId = this.searchFile.dirId;
|
||||||
formData.append('fileShare', false);
|
|
||||||
formData.append("fileName",document.getElementById("file").files[0].name);
|
|
||||||
formData.append("fileSuffix",'.'+(document.getElementById("file").files[0].name.split('.').slice(-1)[0]));
|
|
||||||
formData.append("fileSize",(document.getElementById("file").files[0].size/1024).toFixed(2));
|
|
||||||
formData.append("md5Value",Date.now());
|
|
||||||
formData.append("shareTotal","0");
|
|
||||||
formData.append("shareIndex","0");
|
|
||||||
formData.append("currShareM5","0");
|
|
||||||
formData.append("file",e.target.files[0]);
|
|
||||||
uoloadFile(formData).then((res) => {
|
|
||||||
if (res.success) {
|
|
||||||
this.searchgetFileList();
|
|
||||||
}
|
|
||||||
this.$message.warning(res.message);
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
download(item){
|
download(item){
|
||||||
let apiBaseUrl = window._CONFIG['domianURL'] || "/jeecg-boot";
|
let apiBaseUrl = window._CONFIG['domianURL'] || "/jeecg-boot";
|
||||||
|
|
440
src/views/fileManage/modules/SliceUpload.vue
Normal file
440
src/views/fileManage/modules/SliceUpload.vue
Normal file
|
@ -0,0 +1,440 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-row type="flex">
|
||||||
|
<a-col flex="auto">
|
||||||
|
<a-upload
|
||||||
|
class="upload-wrapper"
|
||||||
|
:showUploadList="false"
|
||||||
|
:disabled="maxFile && tableDate.length >= maxFile"
|
||||||
|
:accept="accept"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:customRequest="customRequestUpload"
|
||||||
|
:multiple="true"
|
||||||
|
@change="handleChange">
|
||||||
|
<!-- <a-input style="width:100%" :value="fileList.map(item=> item.name).join('、')" /> -->
|
||||||
|
<a-button :disabled="maxFile && tableDate.length >= maxFile">
|
||||||
|
<a-icon type="upload" /> 文档上传
|
||||||
|
</a-button>
|
||||||
|
</a-upload>
|
||||||
|
</a-col>
|
||||||
|
<a-col flex="100px" v-if="false" >
|
||||||
|
<a-button @click="customRequestUpload">
|
||||||
|
<a-icon type="upload" /> 文档上传
|
||||||
|
</a-button>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<div class="result-wrapper" :style="{minHeight: boxHeight + 'px'}" >
|
||||||
|
<div class="item" v-for="(file,idx) in tableDate" :key="file.uid">
|
||||||
|
<div class="content">
|
||||||
|
<div class="body">
|
||||||
|
<div class="fileName"> {{ file.fileName }}</div>
|
||||||
|
<div>
|
||||||
|
<a-space>
|
||||||
|
<a-button v-if="canDownload" type="link" style="padding: 0" @click="handleDownload(file)">下载</a-button>
|
||||||
|
<a-popconfirm
|
||||||
|
title="是否确认删除该文件?"
|
||||||
|
@confirm="handleDelete(file, idx)"
|
||||||
|
>
|
||||||
|
<a-icon style="margin-left:10px; cursor: pointer;" type="delete" />
|
||||||
|
</a-popconfirm>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
|
<a-progress
|
||||||
|
class="progress"
|
||||||
|
v-if="autoUpload"
|
||||||
|
:percent="file.percentage"
|
||||||
|
:strokeWidth="3"
|
||||||
|
:showInfo="false" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<slot name="extra" :idx="idx" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import SparkMD5 from 'spark-md5'
|
||||||
|
import { postAction,downloadFile2 } from '@/api/manage'
|
||||||
|
import { verifyFileExist } from '@/api/fileapi'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SliceUpload',
|
||||||
|
props: {
|
||||||
|
boxHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line vue/require-default-prop
|
||||||
|
maxFile: Number,
|
||||||
|
accept: {
|
||||||
|
type: String,
|
||||||
|
default: '.jpg,.png,.doc,.docx,.pdf,.txt,.jpeg'
|
||||||
|
},
|
||||||
|
autoUpload: { // 自动上传
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
canRepeat: { // 是否可上传重复的文件
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
canDownload: { // 是否显示下载按钮
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
dirId: { // 是否显示下载按钮
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
fileMD5: {},
|
||||||
|
isStop: false,
|
||||||
|
fileList: [],
|
||||||
|
tableDate: [],
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
stop (record) {
|
||||||
|
this.isStop = true
|
||||||
|
record.uploadStatus = 0
|
||||||
|
},
|
||||||
|
start (record, index) {
|
||||||
|
const file = this.fileList[index].originFileObj
|
||||||
|
const currentRow = this.tableDate.find((row) => row.uid === file.uid)
|
||||||
|
this.isStop = false
|
||||||
|
record.uploadStatus = 1
|
||||||
|
this.uploadByPieces({
|
||||||
|
file, // 文件信息
|
||||||
|
currentRow,
|
||||||
|
success: (data) => {
|
||||||
|
record.percentage = 100
|
||||||
|
},
|
||||||
|
error: (e) => {
|
||||||
|
record.percentage = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 从外部设置已有文件列表
|
||||||
|
setFileList (fileList) {
|
||||||
|
this.tableDate = fileList
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteFile () {
|
||||||
|
this.fileList = []
|
||||||
|
this.tableDate = []
|
||||||
|
},
|
||||||
|
getFileList () {
|
||||||
|
return this.tableDate
|
||||||
|
},
|
||||||
|
bytesToSize (bytes) {
|
||||||
|
if (bytes === 0) return '0 B'
|
||||||
|
const k = 1024
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
|
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]
|
||||||
|
},
|
||||||
|
handleDelete (file, idx) {
|
||||||
|
this.tableDate.splice(idx, 1)
|
||||||
|
delete this.fileMD5[file.uid]
|
||||||
|
},
|
||||||
|
async beforeUpload (file) {
|
||||||
|
if (!this.canRepeat) {
|
||||||
|
const md5 = await this.getMd5(file, file.size)
|
||||||
|
const find = Object.values(this.fileMD5).find(v => {
|
||||||
|
return v === md5
|
||||||
|
})
|
||||||
|
if (!this.canRepeat && find) {
|
||||||
|
this.$message.warning(`文件重复,重复的文件为:${file.name}`)
|
||||||
|
throw new Error('file repeat')
|
||||||
|
} else {
|
||||||
|
this.fileMD5[file.uid] = md5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fileList.push(file)
|
||||||
|
// uploadStatus 上传状态 1开始 0暂停 2完成
|
||||||
|
this.tableDate.push({
|
||||||
|
fileData: file,
|
||||||
|
uid: file.uid,
|
||||||
|
fileName: file.name,
|
||||||
|
size: file.size,
|
||||||
|
type: file.type,
|
||||||
|
percentage: 0,
|
||||||
|
uploadStatus: 1,
|
||||||
|
remarks: ''
|
||||||
|
})
|
||||||
|
if (!this.autoUpload) {
|
||||||
|
throw new Error('not auto upload')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 自定义上传事件
|
||||||
|
*/
|
||||||
|
customRequestUpload ({ file }) {
|
||||||
|
// 开始执行上传逻辑
|
||||||
|
const currentRow = this.tableDate.find((row) => row.uid === file.uid)
|
||||||
|
if (currentRow) {
|
||||||
|
// 当前上传进度归0
|
||||||
|
currentRow.percentage = 0
|
||||||
|
const _20M = 20 * 1024 * 1024
|
||||||
|
if (file.size > _20M) { // 20M 以上分片上传
|
||||||
|
this.uploadByPieces({ // 这里走分片上传逻辑
|
||||||
|
file, // 文件信息
|
||||||
|
currentRow,
|
||||||
|
success: (data) => {
|
||||||
|
currentRow.percentage = 100
|
||||||
|
},
|
||||||
|
error: (e) => {
|
||||||
|
currentRow.percentage = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else { // 20M 以下直接上传
|
||||||
|
this.uploadDirectly(currentRow, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getMd5 (file, chunkSize) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
|
||||||
|
const chunks = Math.ceil(file.size / chunkSize)
|
||||||
|
let currentChunk = 0
|
||||||
|
const spark = new SparkMD5.ArrayBuffer() // 追加数组缓冲区。
|
||||||
|
const fileReader = new FileReader() // 读取文件
|
||||||
|
fileReader.onload = function (e) {
|
||||||
|
spark.append(e.target.result)
|
||||||
|
currentChunk++
|
||||||
|
if (currentChunk < chunks) {
|
||||||
|
loadNext()
|
||||||
|
} else {
|
||||||
|
const md5 = spark.end() // 完成md5的计算,返回十六进制结果。
|
||||||
|
resolve(md5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileReader.onerror = function (e) {
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNext () {
|
||||||
|
const start = currentChunk * chunkSize
|
||||||
|
let end = start + chunkSize
|
||||||
|
end > file.size && (end = file.size)
|
||||||
|
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
|
||||||
|
}
|
||||||
|
loadNext()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
buildFileFormData (fileName, fileSize, md5Value, shareTotal, shareIndex, file, fileShare) {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('fileName', fileName)
|
||||||
|
formData.append('fileSize', fileSize)
|
||||||
|
formData.append('fileExt', fileName.substring(fileName.lastIndexOf('.')))
|
||||||
|
formData.append('md5Value', md5Value)
|
||||||
|
formData.append('shareTotal', shareTotal)
|
||||||
|
formData.append('shareIndex', shareIndex)
|
||||||
|
formData.append('file', file)
|
||||||
|
formData.append('fileShare', fileShare)
|
||||||
|
formData.append('dirId', this.dirId)
|
||||||
|
return formData
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接上传
|
||||||
|
* @param {File} file file文件
|
||||||
|
*/
|
||||||
|
async uploadDirectly (currentRow, file) {
|
||||||
|
let fileMD5Value = this.fileMD5[file.uid]
|
||||||
|
if (!fileMD5Value) {
|
||||||
|
fileMD5Value = await this.getMd5(file, file.size)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await verifyFileExist({ fileMD5Value })
|
||||||
|
if (res.exist) { // 跳过文件验证逻辑
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = res
|
||||||
|
} else { // 未存在,走上传逻辑
|
||||||
|
const formData = this.buildFileFormData(file.name, file.size, fileMD5Value, 0, 0, file, false)
|
||||||
|
const url = '/file/uoloadFile'
|
||||||
|
try {
|
||||||
|
const res = await postAction(url, formData)
|
||||||
|
if (res) {
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = {
|
||||||
|
fileId: res.id
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentRow.percentage = 0
|
||||||
|
currentRow.uploadStatus = 1
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
this.$message.error('获取文件是否已上传状态失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 断点分片上传
|
||||||
|
uploadByPieces ({ file, currentRow, success, error }) {
|
||||||
|
// const that = this
|
||||||
|
// 上传过程中用到的变量
|
||||||
|
var slicingSize = null
|
||||||
|
if (file.size <= 20971520) {
|
||||||
|
// 20M以内,单个切片大小设置为2MB
|
||||||
|
slicingSize = 2 * 1024 * 1024 // 切片大小 单位MB
|
||||||
|
} else if (file.size <= 524288000) {
|
||||||
|
// 500M以内,单个切片大小设置为5MB
|
||||||
|
slicingSize = 5 * 1024 * 1024 // 切片大小 单位MB
|
||||||
|
} else {
|
||||||
|
// 500M以外,单个切片大小设置为10MB
|
||||||
|
slicingSize = 10 * 1024 * 1024 // 切片大小 单位MB
|
||||||
|
}
|
||||||
|
const sumSlicingCount = Math.ceil(file.size / slicingSize) // 总片数
|
||||||
|
|
||||||
|
currentRow.remarks = '正在获取hash值...'
|
||||||
|
this.getMd5(file, slicingSize)
|
||||||
|
.then((res) => {
|
||||||
|
this.fileMD5[file.uid] = res
|
||||||
|
|
||||||
|
currentRow.remarks = ''
|
||||||
|
this.readFileMD5(file, currentRow, slicingSize, sumSlicingCount, success, error)
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.error('MD5计算错误', e)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 得到某一片的分片 file 总文件; currentIndex 当前切片数,按索引计算; slicingSize 切片大小
|
||||||
|
getSlicingInfo (file, currentIndex, slicingSize) {
|
||||||
|
const start = currentIndex * slicingSize
|
||||||
|
const end = Math.min(file.size, start + slicingSize)
|
||||||
|
const slicingInfo = file.slice(start, end)
|
||||||
|
return slicingInfo
|
||||||
|
},
|
||||||
|
// 开始执行切片上传
|
||||||
|
readFileMD5 (file, currentRow, slicingSize, sumSlicingCount, success, error) {
|
||||||
|
// 检查文件有没有上传过的状态
|
||||||
|
verifyFileExist({ fileMD5Value: this.fileMD5[file.uid] })
|
||||||
|
.then((res) => {
|
||||||
|
const { exist, shareTotal, shareIndex } = res
|
||||||
|
if (exist) {
|
||||||
|
if (shareIndex === (shareTotal - 1)) { // 相等说之前已经上传完整
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = res
|
||||||
|
} else { // 不相等说明之前上传中断了,接着再上传
|
||||||
|
const pross = (shareIndex + 1 / sumSlicingCount) * 100 // 计算之前上传的进度
|
||||||
|
currentRow.percentage = Number(pross.toFixed(2))
|
||||||
|
this.uploadSliceFile(file, currentRow, slicingSize, sumSlicingCount, shareIndex + 1, success, error)
|
||||||
|
}
|
||||||
|
} else { // 没有传过就从第0个分片开始上传
|
||||||
|
this.uploadSliceFile(file, currentRow, slicingSize, sumSlicingCount, 0, success, error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
error && error(e)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 对切片文件进行上传
|
||||||
|
* @param {File} file
|
||||||
|
*/
|
||||||
|
uploadSliceFile (file, currentRow, slicingSize, sumSlicingCount, currIndex, success, error) {
|
||||||
|
if (currIndex < sumSlicingCount && !this.isStop) {
|
||||||
|
// 得到当前需要上传的分片文件
|
||||||
|
const currentInfo = this.getSlicingInfo(file, currIndex, slicingSize)
|
||||||
|
const result = new File([currentInfo], currIndex, { type: file.type, lastModified: Date.now() })
|
||||||
|
const formData = this.buildFileFormData(file.name, file.size, this.fileMD5[file.uid], sumSlicingCount, currIndex, result, true)
|
||||||
|
|
||||||
|
// 开始上传
|
||||||
|
const url = '/file/uoloadFile'
|
||||||
|
postAction(url, formData).then((res) => {
|
||||||
|
const { completed, id } = res
|
||||||
|
if (completed) { // 已上传完毕
|
||||||
|
currentRow.percentage = 100
|
||||||
|
currentRow.uploadStatus = 2
|
||||||
|
currentRow.result = {
|
||||||
|
fileId: id
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 每上传一个就在进度条上加数据
|
||||||
|
const pross = ((currIndex + 1) / sumSlicingCount) * 100
|
||||||
|
currentRow.percentage = Number(pross.toFixed(2))
|
||||||
|
this.uploadSliceFile(file, currentRow, slicingSize, sumSlicingCount, currIndex + 1, success, error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleChange (info) {
|
||||||
|
this.fileList = [...info.fileList]
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*/
|
||||||
|
handleDownload ({ fileName: filterWordName, filePath: filterWordPath }) {
|
||||||
|
downloadFile2(filterWordName, { filterWordName, filterWordPath }, '/file/verifyFileExist')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.upload-wrapper{
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(100% - 10px);
|
||||||
|
/deep/.ant-upload{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-wrapper {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border: 1px solid #D9DADB;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #666666;
|
||||||
|
line-height: 36px;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
.body {
|
||||||
|
position: relative;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.fileName {
|
||||||
|
max-width: 400px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
76
src/views/fileManage/modules/uploadModal.vue
Normal file
76
src/views/fileManage/modules/uploadModal.vue
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<template>
|
||||||
|
<a-modal wrap
|
||||||
|
:title="title"
|
||||||
|
:width="800"
|
||||||
|
:visible="visible"
|
||||||
|
:confirmLoading="confirmLoading"
|
||||||
|
@ok="handleOk"
|
||||||
|
okText="保存">
|
||||||
|
|
||||||
|
<a-spin :spinning="confirmLoading">
|
||||||
|
<SliceUpload
|
||||||
|
ref="technicalUpload"
|
||||||
|
:box-height="50"
|
||||||
|
:max-file="9999"
|
||||||
|
:can-download="false"
|
||||||
|
accept=".docx,.doc,.png,jpg,.pdf,.mp4"
|
||||||
|
:dirId="dirId"
|
||||||
|
/>
|
||||||
|
</a-spin>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import moment from "moment"
|
||||||
|
import JCron from "@/components/jeecg/JCron";
|
||||||
|
import JSelectMultiple from '@/components/jeecg/JSelectMultiple'
|
||||||
|
import SliceUpload from './SliceUpload'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "uploadModal",
|
||||||
|
components: {
|
||||||
|
JCron,
|
||||||
|
JSelectMultiple,
|
||||||
|
SliceUpload
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title:"操作",
|
||||||
|
buttonStyle: 'solid',
|
||||||
|
visible: false,
|
||||||
|
confirmLoading: false,
|
||||||
|
strategys:[],
|
||||||
|
dirId:""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
add () {
|
||||||
|
this.visible =true;
|
||||||
|
},
|
||||||
|
onOk(value) {
|
||||||
|
this.model.startDate = moment(value[0],dateFormat);
|
||||||
|
this.model.endDate = moment(value[1],dateFormat);
|
||||||
|
},
|
||||||
|
close () {
|
||||||
|
this.$emit('close');
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
handleOk () {
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
handleCancel () {
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.disabled{
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
32
yarn.lock
32
yarn.lock
|
@ -4489,7 +4489,7 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms "2.1.2"
|
ms "2.1.2"
|
||||||
|
|
||||||
debuglog@*, debuglog@^1.0.1:
|
debuglog@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||||
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
|
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
|
||||||
|
@ -6818,7 +6818,7 @@ import-local@^2.0.0:
|
||||||
pkg-dir "^3.0.0"
|
pkg-dir "^3.0.0"
|
||||||
resolve-cwd "^2.0.0"
|
resolve-cwd "^2.0.0"
|
||||||
|
|
||||||
imurmurhash@*, imurmurhash@^0.1.4:
|
imurmurhash@^0.1.4:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||||
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
||||||
|
@ -7956,11 +7956,6 @@ lodash._basecopy@^3.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
|
resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
|
||||||
integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=
|
integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=
|
||||||
|
|
||||||
lodash._baseindexof@*:
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
|
|
||||||
integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=
|
|
||||||
|
|
||||||
lodash._baseuniq@~4.6.0:
|
lodash._baseuniq@~4.6.0:
|
||||||
version "4.6.0"
|
version "4.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
||||||
|
@ -7969,16 +7964,11 @@ lodash._baseuniq@~4.6.0:
|
||||||
lodash._createset "~4.0.0"
|
lodash._createset "~4.0.0"
|
||||||
lodash._root "~3.0.0"
|
lodash._root "~3.0.0"
|
||||||
|
|
||||||
lodash._bindcallback@*, lodash._bindcallback@^3.0.0:
|
lodash._bindcallback@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
|
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
|
||||||
integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4=
|
integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4=
|
||||||
|
|
||||||
lodash._cacheindexof@*:
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
|
|
||||||
integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=
|
|
||||||
|
|
||||||
lodash._createassigner@^3.0.0:
|
lodash._createassigner@^3.0.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11"
|
resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11"
|
||||||
|
@ -7988,19 +7978,12 @@ lodash._createassigner@^3.0.0:
|
||||||
lodash._isiterateecall "^3.0.0"
|
lodash._isiterateecall "^3.0.0"
|
||||||
lodash.restparam "^3.0.0"
|
lodash.restparam "^3.0.0"
|
||||||
|
|
||||||
lodash._createcache@*:
|
|
||||||
version "3.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
|
|
||||||
integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=
|
|
||||||
dependencies:
|
|
||||||
lodash._getnative "^3.0.0"
|
|
||||||
|
|
||||||
lodash._createset@~4.0.0:
|
lodash._createset@~4.0.0:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
|
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
|
||||||
integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=
|
integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=
|
||||||
|
|
||||||
lodash._getnative@*, lodash._getnative@^3.0.0:
|
lodash._getnative@^3.0.0:
|
||||||
version "3.9.1"
|
version "3.9.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
|
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
|
||||||
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
|
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
|
||||||
|
@ -8111,7 +8094,7 @@ lodash.pick@^4.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||||
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
|
integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
|
||||||
|
|
||||||
lodash.restparam@*, lodash.restparam@^3.0.0:
|
lodash.restparam@^3.0.0:
|
||||||
version "3.6.1"
|
version "3.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
|
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
|
||||||
integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=
|
integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=
|
||||||
|
@ -11734,6 +11717,11 @@ source-map@^0.7.3:
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
||||||
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
|
||||||
|
|
||||||
|
spark-md5@^3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.2.tgz#7952c4a30784347abcee73268e473b9c0167e3fc"
|
||||||
|
integrity sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==
|
||||||
|
|
||||||
spdx-correct@^3.0.0:
|
spdx-correct@^3.0.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user