index.vue
3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
<template>
<view class="file-upload">
<view class="btn" @click="selectFile">{{ innerName ? '重新上传' : '上传附件' }}</view>
<view v-if="innerName" class="file-name">{{ innerName }}</view>
</view>
</template>
<script>
import { uploadFileApi } from '@/api/base.js'
import upload from '@/utils/upload'
export default {
name: 'FileUpload',
props: {
value: { type: Object, default: () => ({ id: '', name: '' }) },
showName: { type: Boolean, default: false }
},
data() {
return { innerId: this.value && this.value.id ? String(this.value.id) : '', innerName: this.value && this.value.name ? String(this.value.name) : '' }
},
watch: {
value(v) {
const id = v && v.id != null ? String(v.id) : ''
const name = v && v.name != null ? String(v.name) : ''
this.innerId = id
this.innerName = name
}
},
methods: {
async uploadByFormData(fd, name) {
console.log('uploadByFormData__fd', fd)
return uploadFileApi(fd).then(d => {
const data = d && d.data ? d.data : d
const id = (data && (data.id || data.fileId || (data.data && (data.data.id || data.data.fileId)))) ? String(data.id || data.fileId || data.data.id || data.data.fileId) : ''
this.applyResult(id, name)
})
},
selectFile() {
if (typeof uni !== 'undefined' && typeof uni.chooseMessageFile === 'function') {
uni.chooseMessageFile({ count: 1, type: 'all', success: async (res) => {
try {
const f = (res && res.tempFiles && res.tempFiles[0]) ? res.tempFiles[0] : null
if (!f) return
const name = f.name || 'file'
if (f.path) {
const r = await upload({ url: '/sw/filebox/uploadFile', filePath: f.path, name: 'file' })
const d = r && r.data ? r.data : r
const id = (d && (d.id || d.fileId || (d.data && (d.data.id || d.data.fileId)))) ? String(d.id || d.fileId || d.data.id || d.data.fileId) : ''
this.applyResult(id, name)
} else if (f.file) {
const fd = new FormData()
fd.append('file', f.file, name)
await this.uploadByFormData(fd, name)
}
} catch (e) {
uni.showToast({ title: '上传失败', icon: 'none' })
}
}, fail: () => { uni.showToast({ title: '未选择文件', icon: 'none' }) } })
return
}
// H5 兜底:动态创建原生 input
try {
const input = document.createElement('input')
input.type = 'file'
input.style.position = 'fixed'
input.style.left = '-9999px'
document.body.appendChild(input)
input.addEventListener('change', this.onFileChange)
input.click()
setTimeout(() => { document.body.removeChild(input) }, 1000)
} catch (e) {
uni.showToast({ title: '无法打开文件选择', icon: 'none' })
}
},
async onFileChange(e) {
const files = e && e.target && e.target.files ? e.target.files : []
const file = files && files[0] ? files[0] : null
if (!file) return
const name = file.name || ''
const fd = new FormData()
fd.append('file', file, name)
try {
await this.uploadByFormData(fd, name)
} catch (e2) {
uni.showToast({ title: '上传失败', icon: 'none' })
} finally {
if (e && e.target) e.target.value = ''
}
},
applyResult(id, name) {
this.innerId = id
this.innerName = name
const payload = { id, name }
this.$emit('input', payload)
this.$emit('update:value', payload)
this.$emit('change', payload)
}
}
}
</script>
<style scoped>
.file-upload {
display: flex;
position: relative;
top: 6rpx;
}
.btn {
color: #3D48A3; font-size: 28rpx; margin-right: 20rpx; cursor: pointer;
flex-shrink: 0;
}
.file-name {
font-size: 28rpx; color: rgba(0,0,0,0.9);
line-height: 40rpx;
}
</style>