Files
dvcp_v2_wechat_app/src/components/AiUploader/AiUploader.vue
aixianling 41c05f2eb0 BUG 27911
2022-03-02 18:12:37 +08:00

271 lines
6.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="ai-uploader">
<div class="imgList" v-if="type == 'image'">
<div class="item" v-for="(item, i) in fileList" :key="i">
<ai-image :src="item.url" :preview="preview"/>
<u-icon class="delBtn" color="#f46" name="close-circle-fill" size="40" @click="remove(i)"/>
</div>
<div v-if="!disabled&&(fileList.length == 0 || (fileList.length < limit))" class="default" @click="upload">
<u-icon name="photo" size="64" :label="placeholder" label-pos="bottom" label-color="#89b"/>
</div>
</div>
<div class="fileList" v-else>
<div class="item" v-for="(item, i) in fileList" :key="i">
<ai-image :preview="preview" :file="item"/>
<div class="info">
<span>{{ item.name }} </span>
<i>{{ item.fileSizeStr }}</i>
</div>
<template v-if="!disabled">
<div class="btn" @tap="handleReUpload(i)">
重新上传
</div>
<div class="btn" @tap="remove(i)">
删除
</div>
</template>
</div>
<div v-if="!disabled&&(fileList.length == 0 || (multiple && fileList.length < limit))" class="default"
@click="upload">
<u-icon name="photo" size="64" :label="placeholder" label-pos="bottom" label-color="#89b"/>
</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
import AiImage from '../AiImage/AiImage'
export default {
name: 'AiUploader',
components: {AiImage},
props: {
limit: {default: 1}, //数量
placeholder: {default: '添加图片'}, // 文字提示
type: {default: 'image'}, // 文件类型image还是file
multiple: {
type: Boolean,
default: false,
},
fileId: String,
mediaId: String,
def: {default: () => []},
action: {default: '/admin/file/add'},
preview: Boolean,
size: {default: 10 * 1024 * 1024},
disabled: Boolean,
},
computed: {
...mapState(['token']),
errorImage() {
return this.$cdn + 'file.png'
},
},
watch: {
def: {
handler(v) {
if (!!v?.toString()) {
if (this.multiple) {
this.fileList = v
} else if (v?.url) {
this.fileList = [v]
}
}
},
immediate: true,
},
},
data() {
return {
fileList: [],
}
},
methods: {
remove(index) {
this.fileList.splice(index, 1)
this.$emit('list', this.fileList)
},
upload(wait) {
let params = {
count: this.limit,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
let count = this.fileList?.length + (res.tempFiles?.length || res.tempFile ? 1 : 0)
if (count > this.limit && this.limit !== 1) {
return this.$u.toast(`不能超过${this.limit}`)
}
if (res.tempFiles) {
res.tempFiles?.map((item) => {
this.uploadFile(item)
})
} else if (res?.tempFile) {
this.uploadFile(res.tempFile)
}
},
}
typeof wait == 'function' && wait()
if (this.type == 'image') {
uni.chooseImage(params)
} else if (this.type == 'video') {
uni.chooseVideo(params)
} else {
uni.chooseFile(params)
}
},
uploadFile(img) {
if (this.size > 0 && img.size > this.size) {
return this.$u.toast(`不能超过${Math.ceil(this.size / 1024 / 1024)}MB`)
}
uni.showLoading({title: '上传中'})
if (this.manual) {
this.$emit('manual', img)
uni.hideLoading()
} else {
uni.uploadFile({
url: this.$instance.config.baseURL + this.action,
filePath: img.path,
name: 'file',
header: {
'Content-Type': 'multipart/form-data',
Authorization: uni.getStorageSync('token'),
},
success: response => {
uni.hideLoading()
const res = JSON.parse(response.data)
if (res?.data) {
this.$emit('data', res.data)
this.$u.toast('上传成功!')
if (this.action.endsWith('/file/add')) {
this.fileList.push({url: res.data?.[0]?.split(";")?.[0], id: res.data?.[0]?.split(";")?.[1]})
this.$emit('input', [...this.fileList])
this.$emit('change', [...this.fileList])
} else if (this.action == '/admin/file/add2') {
let info = res.data
this.$emit('update:fileId', info?.id)
this.fileList.push(res.data)
} else if (this.action == '/admin/file/add-portrait') {
this.fileList.push({url: res.data?.split(";")?.[0], id: res.data?.split(";")?.[1]})
}
this.$emit("update:def", this.fileList)
this.$emit("list", this.fileList)
} else {
this.$u.toast(res.msg)
}
},
fail: err => {
console.log(err)
uni.hideLoading()
}
})
}
},
handleReUpload(i) {
this.upload(() => this.remove(i))
},
},
}
</script>
<style lang="scss" scoped>
.ai-uploader {
width: 100%;
line-height: normal;
margin-bottom: 16px;
::v-deep.imgList {
display: flex;
flex-wrap: wrap;
.item {
position: relative;
.delBtn {
position: absolute;
right: -8px;
top: -8px;
z-index: 2;
border-radius: 50%;
overflow: hidden;
background-color: #fff;
}
}
image {
width: 30vw;
height: 30vw;
margin: 0 2px 2px 0;
}
}
.fileList {
.item {
display: flex;
align-items: center;
margin-bottom: 10px;
image {
width: 160px;
height: 160px;
}
i {
font-style: normal;
color: #9b9b9b;
}
.info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
overflow: hidden;
text-overflow: ellipsis;
& > span {
flex: 1;
min-width: 0;
}
}
div.btn {
color: $uni-color-primary;
margin-right: 16px;
}
div:nth-child(4) {
color: #f72c27;
}
& > * + * {
margin-left: 20px;
}
}
}
.default {
width: 30vw;
height: 30vw;
box-sizing: border-box;
border-radius: 8px;
background: #f3f4f7;
color: #89b;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.iconfont-iconAdd {
font-size: 64px;
}
}
}
</style>