同步组件

This commit is contained in:
aixianling
2022-02-25 08:55:53 +08:00
parent a3dfe91a05
commit b5d0a0a02c

View File

@@ -1,149 +1,162 @@
<template> <template>
<div class="ai-uploader"> <div class="ai-uploader">
<div class="imgs flex-align"> <div class="fileList">
<div class="img" v-for="(item, index) in fileList" :key="index"> <div class="item" v-for="(item, i) in fileList" :key="i">
<image :src="item.url" hover-class="text-hover" @click="prev(index)" class="image" /> <template v-if="type == 'image'">
<!-- <i class="iconfont" @click="remove(index)">&#xe6b3;</i> --> <ai-image :src="item.url" :preview="preview"/>
<img src="https://cdn.cunwuyun.cn/dvcp/upload/del-icon.png" alt="" class="del-icon" @click="remove(index)"/> <div class="info">
<i>{{ item.fileSizeStr }}</i>
</div>
</template>
<template v-else>
<ai-image :preview="preview" :file="item"/>
<div class="info">
<span>{{ item.name }} </span>
<i>{{ item.fileSizeStr }}</i>
</div>
</template>
<template v-if="!disabled">
<div btn @tap="handleReUpload(i)">
重新上传
</div>
<div btn @tap="remove(i)">
删除
</div>
</template>
</div> </div>
<div class="upload" @click="upload" v-if="fileList.length < limit"> <div v-if="!disabled&&(fileList.length == 0 || (multiple && fileList.length < limit))" class="default"
<!-- <i class="iconfont">&#xe6b2;</i> --> @click="upload">
<img src="https://cdn.cunwuyun.cn/dvcp/upload/add-icon.png" alt="" class="add-icon"/> <i class="iconfont iconfont-iconAdd"/>
<span>添加照片</span> <span>{{ placeholder }}</span>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import axios from '@/utils/axios.js' import {mapState} from 'vuex'
import AiImage from '../AiImage/AiImage'
export default { export default {
name: 'AiUploader', name: 'AiUploader',
components: {AiImage},
model: {
event: 'input',
prop: 'value',
},
props: { props: {
limit: { limit: {default: 1}, //数量
type: Number, placeholder: {default: '添加图片'}, // 文字提示
default: 1, type: {default: 'image'}, // 文件类型image还是file
multiple: {
type: Boolean,
default: false,
}, },
fileId: String,
type: { mediaId: String,
type: 'img', def: {default: () => []},
}, action: {default: '/app/wxcp/upload/uploadFile'},
preview: Boolean,
value: { size: {default: 10 * 1024 * 1024},
type: Array, disabled: Boolean,
default: () => [], },
computed: {
...mapState(['token']),
errorImage() {
return this.$cdn + 'file.png'
}, },
}, },
watch: { watch: {
value: { def: {
handler(val) { handler(v) {
if (val) { if (!!v?.toString()) {
this.fileList = [...val] if (this.multiple) {
this.fileList = v
} else if (v?.url) {
this.fileList = [v]
}
} }
}, },
immediate: true, immediate: true,
deep: true,
}, },
}, },
data() { data() {
return { return {
fileList: [], fileList: [],
hideStatus: false,
} }
}, },
methods: { methods: {
remove(index) { remove(index) {
this.fileList.splice(index, 1) this.fileList.splice(index, 1)
this.$emit('list', this.fileList)
this.$nextTick(() => {
this.$emit('input', [...this.fileList])
this.$emit('change', [...this.fileList])
})
}, },
upload(wait) {
prev(index) { let params = {
uni.previewImage({
current: this.fileList[index].url,
urls: this.fileList.map((v) => v.url),
})
},
upload() {
uni.chooseImage({
count: this.limit, count: this.limit,
sizeType: ['compressed'], sizeType: ['compressed'],
sourceType: ['album', 'camera'], sourceType: ['album', 'camera'],
success: (res) => { success: (res) => {
if (this.fileList.length + res.tempFilePaths.length > this.limit && this.limit !== 1) { let count = this.fileList?.length + (res.tempFiles?.length || res.tempFile ? 1 : 0)
this.$toast(`图片不能超过${this.limit}`) if (count > this.limit && this.limit !== 1) {
return this.$u.toast(`不能超过${this.limit}`)
return false
} }
if (res.tempFiles) {
this.$loading('上传中') res.tempFiles?.map((item) => {
res.tempFilePaths.forEach((item, index) => { this.uploadFile(item)
if (index === res.tempFilePaths.length - 1) {
this.hideStatus = true
}
console.log(item)
this.uploadFile(item)
})
},
})
},
uploadFile(img) {
uni.uploadFile({
url: axios.baseURL + '/admin/file/add',
filePath: img,
name: 'file',
header: {
'Content-Type': 'multipart/form-data',
Authorization: uni.getStorageSync('token'),
},
success: (res) => {
const data = JSON.parse(res.data)
if (data.code === 0) {
if (this.limit === 1) {
this.fileList = [
{
id: data.data[0].split(';')[1],
url: data.data[0].split(';')[0],
},
]
} else {
this.fileList.push({
id: data.data[0].split(';')[1],
url: data.data[0].split(';')[0],
})
}
this.$nextTick(() => {
this.$emit('input', [...this.fileList])
this.$emit('change', [...this.fileList])
}) })
} 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: '上传中'})
let formData = new FormData()
formData.append('file', img)
if (this.manual) {
this.$emit('manual', img)
uni.hideLoading()
} else {
this.$http.post(this.action, formData, {
params: {type: this.type},
}).then((res) => {
uni.hideLoading()
if (res?.data) {
this.$emit('data', res.data)
this.$u.toast('上传成功!')
if (this.action == '/app/wxcp/upload/uploadFile') {
this.$emit('update:mediaId', res.data?.media?.mediaId)
this.$emit('update:fileId', res.data.file.id)
this.fileList.push(res.data.file)
} 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 { } else {
this.$toast(data.msg) this.$u.toast(res.msg)
} }
}, }).catch(err => {
complete: () => { this.$u.toast(err)
if (this.hideStatus) { uni.hideLoading()
this.$hideLoading() })
this.hideStatus = false }
}
}, },
}) handleReUpload(i) {
this.upload(() => this.remove(i))
}, },
}, },
} }
@@ -151,74 +164,74 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.ai-uploader { .ai-uploader {
.del-icon { width: 100%;
position: absolute; line-height: normal;
right: 0; margin-bottom: 16px;
top: 0;
z-index: 11;
width: 32px;
height: 32px;
-webkit-transform: translate(50%, -50%);
transform: translate(50%, -50%);
}
.imgs { .fileList {
flex-wrap: wrap; .item {
display: flex;
align-items: center;
margin-bottom: 10px;
div { image {
position: relative; width: 160px;
width: 220px; height: 160px;
height: 220px;
margin-right: 8px;
margin-bottom: 8px;
&:nth-of-type(3n) {
margin-right: 0;
} }
.image {
width: 220px;
height: 220px;
}
}
.img {
i { i {
position: absolute; font-style: normal;
right: 0; color: #9b9b9b;
top: 0; }
z-index: 11;
font-size: 28px; .info {
opacity: 0.8; 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;
}
div:nth-child(4) {
color: #f72c27; color: #f72c27;
transform: translate(50%, -50%); }
& > * + * {
margin-left: 20px;
} }
} }
.upload { .default {
width: 224px; width: 240px;
height: 224px; height: 240px;
text-align: center;
border: 1px solid #dddddd;
box-sizing: border-box; box-sizing: border-box;
border-radius: 8px;
background: #f3f4f7;
color: #89b;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
i { .iconfont-iconAdd {
padding: 42px 0 16px;
color: #ddd;
font-size: 64px; font-size: 64px;
} }
.add-icon {
margin: 50px 0 16px;
width: 64px;
height: 64px;
}
span { span {
display: block; display: block;
text-align: center; text-align: center;
color: #dddddd; font-size: 28px;
font-size: 24px;
} }
} }
} }