123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- import {
- getUploadToken
- } from '@/api/webApi/common.js'
- import consts from '@/common/mx-const'
- import cacheMixin from './Cache/mx-cache-mixin'
- export default {
- mixins: [cacheMixin],
- model: {
- prop: 'value',
- event: 'input'
- },
- props: {
- // 值
- value: [String, Object, Array],
- // 大小限制(MB)
- fileSize: {
- type: Number,
- default: 1024
- },
- // 是否显示提示
- isShowTip: {
- type: Boolean,
- default: true
- },
- // upload type // 不同的类型将分放到不同目录
- type: {
- type: Number,
- default: consts.enum.uploadType.personalResource
- }
- },
- data() {
- return {
- // 改为OSS上传
- // uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
- // headers: {
- // Authorization: "Bearer " + getToken(),
- // },
- // 上传个数限制
- limit: 0,
- // 文件类型, 例如['png', 'jpg', 'jpeg']
- fileType: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'png', 'jpg', 'jpeg'], // 逻辑判断用
- uploading: false,
- uploadPercent: 0,
- ossRegion: 'oss-cn-beijing',
- ossBucket: 'mingxuejingbang',
- uploadFileTypes: this.mxGlobal.uploadFileTypes, // 打开窗口用,是标准化的文件类型名称,比较长不适合逻辑展示
- uploadTypes: [],
- fileList: []
- }
- },
- computed: {
- // 是否显示提示
- showTip() {
- return this.isShowTip && (this.fileType || this.fileSize)
- },
- // 列表
- list() {
- let temp = 1
- if (this.value) {
- // 首先将值转为数组
- const list = Array.isArray(this.value) ? this.value : [this.value]
- // 然后将数组转为对象数组
- return list.map((item) => {
- if (typeof item === 'string') {
- item = { name: item, url: item }
- }
- item.uid = item.uid || new Date().getTime() + temp++
- return item
- })
- } else {
- this.fileList = []
- return []
- }
- }
- },
- methods: {
- // 上传前校检格式和大小
- handleBeforeUpload(file) {
- // 校检文件类型
- if (this.fileType) {
- let fileExtension = ''
- if (file.name.lastIndexOf('.') > -1) {
- fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
- }
- const isTypeOk = this.fileType.some((type) => {
- if (file.type.indexOf(type) > -1) return true
- if (fileExtension && fileExtension.indexOf(type) > -1) return true
- return false
- })
- if (!isTypeOk) {
- this.$message.error(`文件格式不正确, 请上传${this.fileType.join('/')}格式文件!`)
- return false
- }
- }
- // 校检文件大小
- if (this.fileSize) {
- const isLt = file.size / 1024 / 1024 < this.fileSize
- if (!isLt) {
- this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`)
- return false
- }
- }
- // 校验存储目录
- if (!this.getSaveDir()) {
- this.$message.error(`上传文件存储路径未配置,请联系管理员!`)
- return false
- }
- return true
- },
- // 文件个数超出
- handleExceed() {
- this.$message.error(`只允许上传 ${this.limit} 个文件`)
- },
- // 上传失败
- handleUploadError(err) {
- this.$message.error('上传失败, 请重试')
- },
- // 上传成功回调
- handleUploadSuccess(res, file) {
- this.fileList.push(res)
- this.handleNotify()
- this.$message.success('上传成功')
- },
- // 删除文件
- handleDelete(file, fileList) {
- this.fileList = fileList
- this.handleNotify()
- },
- handleNotify() {
- this.$emit('input', this.fileList)
- },
- handleUpload(param) {
- getUploadToken().then(res => {
- // https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/mingxueMainImgs/skld.png
- const OSS = require('ali-oss')
- const client = new OSS({
- // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
- // 从STS服务获取的安全令牌(SecurityToken)。
- accessKeyId: res.data.credentials.accessKeyId,
- accessKeySecret: res.data.credentials.accessKeySecret,
- stsToken: res.data.credentials.securityToken,
- secure: true,
- // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
- // 填写Bucket名称,例如examplebucket。
- region: this.ossRegion,
- bucket: this.ossBucket
- })
- const file = param.file
- const lastIndexOfDot = file.name.lastIndexOf('.')
- const pureName = file.name.substring(0, lastIndexOfDot)
- const fileNameSuffix = file.name.substring(lastIndexOfDot)
- const ticket = new Date().getTime() // 防重名覆盖
- const storeAs = this.getSaveDir() + pureName + '.' + ticket + fileNameSuffix
- console.log('oss-client', client, param)
- this.uploading = true
- this.uploadPercent = 0
- this.$emit('uploadBegin')
- client.multipartUpload(storeAs, file, {
- progress: p => {
- const displayPercent = Math.ceil(p * 100)
- this.uploadPercent = displayPercent
- }
- }).then(result => {
- const standardResult = {
- name: pureName,
- url: `https://${this.ossBucket}.${this.ossRegion}.aliyuncs.com/${result.name}`,
- fileSize: file.size / 1024 / 1024, // 转MB
- isImage: file.type === 'image/jpeg' || file.type === 'image/jpg' || file.type === 'image/png'
- }
- param.onSuccess(standardResult)
- }).catch(err => {
- param.onError(err)
- }).finally(() => {
- setTimeout(_ => {
- this.uploading = false
- this.$emit('uploadEnd')
- }, 2000)
- })
- })
- },
- // 获取文件名称
- getFileName(name) {
- if (name.lastIndexOf('/') > -1) {
- return name.slice(name.lastIndexOf('/') + 1).toLowerCase()
- } else {
- return ''
- }
- },
- getSaveDir() {
- if (!this.uploadTypes.length) return ''
- let path = this.uploadTypes.find(t => t.value == this.type)?.label || ''
- if (path && !path.endsWith('/')) path += '/'
- return path
- }
- },
- async created() {
- this.fileList = this.list
- this.uploadTypes = await this.getFileUploadTypeListByCache()
- }
- }
|