Files
dvcp_v2_wechat_app/src/components/AiUploader/AiUploader.vue

272 lines
6.6 KiB
Vue
Raw Normal View History

2022-02-14 17:25:54 +08:00
<template>
<div class="ai-uploader">
2022-02-28 17:43:37 +08:00
<div class="imgList" v-if="type == 'image'">
2022-02-25 08:55:53 +08:00
<div class="item" v-for="(item, i) in fileList" :key="i">
2022-02-28 17:43:37 +08:00
<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 || (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 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>
2022-02-25 08:55:53 +08:00
<template v-if="!disabled">
2022-02-25 15:34:20 +08:00
<div class="btn" @tap="handleReUpload(i)">
2022-02-25 08:55:53 +08:00
重新上传
</div>
2022-02-25 15:34:20 +08:00
<div class="btn" @tap="remove(i)">
2022-02-25 08:55:53 +08:00
删除
</div>
</template>
2022-02-14 17:25:54 +08:00
</div>
2022-02-25 08:55:53 +08:00
<div v-if="!disabled&&(fileList.length == 0 || (multiple && fileList.length < limit))" class="default"
@click="upload">
2022-02-28 17:43:37 +08:00
<u-icon name="photo" size="64" :label="placeholder" label-pos="bottom" label-color="#89b"/>
2022-02-14 17:25:54 +08:00
</div>
</div>
</div>
</template>
<script>
2022-02-25 08:55:53 +08:00
import {mapState} from 'vuex'
import AiImage from '../AiImage/AiImage'
2022-02-14 17:25:54 +08:00
export default {
name: 'AiUploader',
2022-02-25 08:55:53 +08:00
components: {AiImage},
2022-02-14 17:25:54 +08:00
props: {
2022-02-25 08:55:53 +08:00
limit: {default: 1}, //数量
placeholder: {default: '添加图片'}, // 文字提示
type: {default: 'image'}, // 文件类型image还是file
multiple: {
type: Boolean,
default: false,
2022-02-14 17:25:54 +08:00
},
2022-02-25 08:55:53 +08:00
fileId: String,
mediaId: String,
def: {default: () => []},
2022-02-25 11:15:38 +08:00
action: {default: '/admin/file/add'},
2022-02-25 08:55:53 +08:00
preview: Boolean,
size: {default: 10 * 1024 * 1024},
disabled: Boolean,
},
computed: {
...mapState(['token']),
errorImage() {
return this.$cdn + 'file.png'
2022-02-14 17:25:54 +08:00
},
},
watch: {
2022-02-25 08:55:53 +08:00
def: {
handler(v) {
if (!!v?.toString()) {
if (this.multiple) {
this.fileList = v
} else if (v?.url) {
this.fileList = [v]
}
2022-02-14 17:25:54 +08:00
}
},
immediate: true,
},
},
data() {
return {
fileList: [],
}
},
methods: {
remove(index) {
this.fileList.splice(index, 1)
2022-02-25 08:55:53 +08:00
this.$emit('list', this.fileList)
2022-02-14 17:25:54 +08:00
},
2022-02-25 08:55:53 +08:00
upload(wait) {
let params = {
2022-02-14 17:25:54 +08:00
count: this.limit,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
2022-02-25 08:55:53 +08:00
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)
2022-02-14 17:25:54 +08:00
}
},
2022-02-25 08:55:53 +08:00
}
typeof wait == 'function' && wait()
if (this.type == 'image') {
uni.chooseImage(params)
} else if (this.type == 'video') {
uni.chooseVideo(params)
} else {
uni.chooseFile(params)
}
2022-02-14 17:25:54 +08:00
},
uploadFile(img) {
2022-02-25 08:55:53 +08:00
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 {
2022-02-25 11:12:41 +08:00
uni.uploadFile({
2022-02-25 15:34:20 +08:00
url: this.$instance.config.baseURL + this.action,
filePath: img.path,
2022-02-25 11:12:41 +08:00
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('上传成功!')
2022-02-25 17:21:21 +08:00
if (this.action.endsWith('/file/add')) {
2022-02-25 15:34:20 +08:00
this.fileList.push({url: res.data?.[0]?.split(";")?.[0], id: res.data?.[0]?.split(";")?.[1]})
2022-02-25 11:15:38 +08:00
this.$emit('input', [...this.fileList])
this.$emit('change', [...this.fileList])
2022-02-25 11:12:41 +08:00
} 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)
2022-02-14 17:25:54 +08:00
}
2022-02-25 15:34:20 +08:00
},
fail: err => {
console.log(err)
uni.hideLoading()
2022-02-14 17:25:54 +08:00
}
2022-02-25 08:55:53 +08:00
})
}
},
handleReUpload(i) {
this.upload(() => this.remove(i))
2022-02-14 17:25:54 +08:00
},
},
}
</script>
<style lang="scss" scoped>
.ai-uploader {
2022-02-25 08:55:53 +08:00
width: 100%;
line-height: normal;
margin-bottom: 16px;
2022-02-28 17:43:37 +08:00
::v-deep.imgList {
display: flex;
flex-wrap: wrap;
.item {
position: relative;
.delBtn {
position: absolute;
right: -8px;
top: -8px;
z-index: 999;
border-radius: 50%;
overflow: hidden;
background-color: #fff;
}
}
image {
width: 30vw;
height: 30vw;
margin: 0 2px 2px 0;
}
}
2022-02-25 08:55:53 +08:00
.fileList {
.item {
display: flex;
align-items: center;
margin-bottom: 10px;
image {
width: 160px;
height: 160px;
}
2022-02-14 17:25:54 +08:00
2022-02-25 08:55:53 +08:00
i {
font-style: normal;
color: #9b9b9b;
}
2022-02-14 17:25:54 +08:00
2022-02-25 08:55:53 +08:00
.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;
}
2022-02-14 17:25:54 +08:00
}
2022-02-25 15:34:20 +08:00
div.btn {
2022-02-25 08:55:53 +08:00
color: $uni-color-primary;
2022-02-25 15:34:20 +08:00
margin-right: 16px;
2022-02-14 17:25:54 +08:00
}
2022-02-25 08:55:53 +08:00
div:nth-child(4) {
2022-02-14 17:25:54 +08:00
color: #f72c27;
2022-02-25 08:55:53 +08:00
}
& > * + * {
margin-left: 20px;
2022-02-14 17:25:54 +08:00
}
}
2022-02-25 08:55:53 +08:00
2022-02-28 17:43:37 +08:00
}
2022-02-14 17:25:54 +08:00
2022-02-28 17:43:37 +08:00
.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;
2022-02-14 17:25:54 +08:00
}
}
}
</style>