123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /**
- * 文件上传处理函数
- */
- import { computed, ref, watch } from 'vue'
- import { useCipConfig } from '../../../hooks/use-cip-config'
- import CipMessage from '../../../cip-message'
- import { useFormInput } from '../../../hooks/form-input'
- import { isString } from '@cip/utils/util'
- import { useFormInject } from '../../../hooks/use-form'
- export const fileTypeList = ['png', 'jpg', 'jpeg', 'jpe', 'gif', 'doc', 'docx', 'ppt', 'pptx', 'pdf', 'xls', 'xlsx', 'zip', '7z', 'rar']
- export const uploadProps = (props, context) => {
- const { proxyValue, securityConfig } = useFormInput(props, context)
- const cipForm = useFormInject()
- const cipConfig = useCipConfig()
- const useStringValue = computed(() => {
- return securityConfig.value.stringValue
- })
- const objectValue = computed(() => { // 返回的数据是一个对象
- return securityConfig.value.objectValue
- })
- const uploadFileFn = computed(() => {
- // BROKEN: 默认的文件上传方法由cip-config-porvide提供
- return securityConfig.value.uploadFn || cipConfig.fileUpload
- })
- const fileSplitKey = computed(() => {
- return securityConfig.value.splitKey ?? ','
- })
- const fileList = ref([])
- watch(() => props.modelValue, () => {
- if (props.modelValue) {
- if (!useStringValue.value) {
- // 兼容未配置stringValue但存储结果为string的modelValue
- if (isString(props.modelValue)) {
- fileList.value = props.modelValue.split(fileSplitKey.value).map(v => ({ url: v }))
- } else if (objectValue.value) {
- fileList.value = [props.modelValue]
- } else {
- fileList.value = props.modelValue
- }
- } else {
- fileList.value = props.modelValue.split(fileSplitKey.value).map(v => ({ url: v }))
- }
- } else {
- fileList.value = []
- }
- }, { immediate: true })
- // 文件上传
- const uploadFile = (info) => {
- let file = info.file
- const uid = info.file.uid
- if (securityConfig.value.getFileName) {
- // 重新命名文件
- file = new window.File([file], securityConfig.value.getFileName(file.name, props.dependOnValues, securityConfig.value))
- }
- // 保持uid
- file.uid = uid
- const fileObject = {
- name: file.name,
- uid: file.uid,
- percentage: 0,
- status: 'ready'
- }
- const fileXhr = uploadFileFn.value({
- file: file,
- dependOnValues: props.dependOnValues,
- config: {
- // 挂载监听钩子
- onUploadProgress: progress => {
- fileUploadProgress(info, { total: progress.total, loaded: progress.loaded, percentage: Math.floor(progress.loaded / progress.total * 100) })
- }
- },
- fieldConfig: securityConfig.value
- })
- fileObject.abort = fileXhr.abort
- fileList.value.push(fileObject)
- // 限制表单提交
- cipForm.uploadQueue[uid] = true
- fileXhr.send().then((res) => {
- fileUploadProgress(info, { [props.config.urlKey || 'url']: res.data, status: 'success' })
- if (props.config.autoNotify) CipMessage.success(res.message)
- updateValue()
- }).catch(e => {
- fileUploadProgress(info, { status: 'exception' })
- setTimeout(() => {
- fileList.value.splice(fileList.value.findIndex(v => v.uid === info.file.uid), 1)
- }, 500)
- }).finally(() => {
- cipForm.uploadQueue[uid] = false
- })
- }
- // 单例模式加载message
- let messageInstance = null
- const mainMessage = (through, message) => {
- if (!through) {
- if (messageInstance) {
- CipMessage.closeAll()
- }
- messageInstance = CipMessage.warning(message)
- return true
- }
- }
- // 文件数量限制
- const countLimit = (file) => {
- // 加上正在上传的数量
- return fileList.value.length + 1 <= (securityConfig.value.limit ?? Infinity)
- }
- // 文件类型限制
- const typeLimit = (file) => {
- if (props.config.ignoreFileType) { // 完全不限制类型
- return true
- }
- const fileType = props.config.fileType && securityConfig.value.fileType.length !== 0 ? securityConfig.value.fileType : fileTypeList
- const obj = file.name?.split('.') ?? ''
- return fileType.includes(obj[obj.length - 1].toLowerCase())
- }
- // 文件大小限制
- const sizeLimit = (file) => {
- return file.size <= (securityConfig.value.size ?? Infinity) * 1024 * 1024
- }
- // 修改文件列表某文件的状态
- const fileUploadProgress = (info, writeObj) => {
- return fileList.value.map(i => {
- if (i.uid === info.file.uid) {
- // eslint-disable-next-line
- for (const item in writeObj) {
- i[item] = writeObj[item]
- }
- }
- return i
- })
- }
- // 文件列表删除
- const removeFile = (file, list) => {
- const fileIndex = fileList.value.findIndex(v => v.uid === file.uid)
- fileList.value.splice(fileIndex, 1)
- updateValue()
- }
- const updateValue = () => {
- let modelValue = fileList.value
- if (useStringValue.value) {
- modelValue = fileList.value?.map(v => v.url).join(fileSplitKey.value)
- } else if (objectValue.value) {
- modelValue = fileList.value[0]
- }
- proxyValue.value = modelValue
- }
- const uploadDisabled = computed(() => props.disabled || securityConfig.value.limit <= fileList.value.length)
- return {
- uploadFile,
- removeFile,
- fileList,
- mainMessage,
- countLimit,
- typeLimit,
- sizeLimit,
- uploadDisabled
- }
- }
- export const download = (file) => {
- file.percentage = ''
- const download = document.createElement('a')
- download.setAttribute('href', file.url + '?response-content-type=application/octet-stream')
- download.setAttribute('download', file.name)
- download.click()
- }
|