|
@@ -0,0 +1,293 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="cl-upload">
|
|
|
|
|
+ <el-input type="hidden" v-model="value"></el-input>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- :on-success="
|
|
|
|
|
+ (res, file) => {
|
|
|
|
|
+ onSuccess(res, file, item);
|
|
|
|
|
+ }
|
|
|
|
|
+ "-->
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ v-for="(item, index) in list"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ accept="image/*"
|
|
|
|
|
+ v-bind="props"
|
|
|
|
|
+ :headers="{
|
|
|
|
|
+ token: token
|
|
|
|
|
+ }"
|
|
|
|
|
+ name="content"
|
|
|
|
|
+ :on-change="getFile"
|
|
|
|
|
+ :auto-upload="false"
|
|
|
|
|
+ :action="action"
|
|
|
|
|
+ :show-file-list="false"
|
|
|
|
|
+ :on-error="onError"
|
|
|
|
|
+ :before-upload="
|
|
|
|
|
+ e => {
|
|
|
|
|
+ beforeUpload(e, item, index);
|
|
|
|
|
+ }
|
|
|
|
|
+ "
|
|
|
|
|
+ >
|
|
|
|
|
+ <slot name="content">
|
|
|
|
|
+ <div class="upload-wrap" v-loading="item.loading">
|
|
|
|
|
+ <img :src="item.url | check_prefix" alt v-if="item.url" />
|
|
|
|
|
+ <i class="el-icon-plus avatar-uploader-icon" v-else></i>
|
|
|
|
|
+
|
|
|
|
|
+ <i class="el-icon-close" v-if="item.url" @click.stop="removeFile(index)"></i>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </slot>
|
|
|
|
|
+ </el-upload>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import { mapGetters } from 'vuex';
|
|
|
|
|
+import { baseUrl } from '@/config/env';
|
|
|
|
|
+import { imgHostUrl } from '@/config/env';
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ props: {
|
|
|
|
|
+ props: {
|
|
|
|
|
+ type: Object,
|
|
|
|
|
+ default: () => {
|
|
|
|
|
+ return {};
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ value: [Array, String],
|
|
|
|
|
+ hostUrl: {
|
|
|
|
|
+ default: ''
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ data() {
|
|
|
|
|
+ const upload = this.$service.common.upload();
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ imgHostUrl: imgHostUrl,
|
|
|
|
|
+ action: upload.url,
|
|
|
|
|
+ list: [],
|
|
|
|
|
+ index: 0
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ filters: {
|
|
|
|
|
+ check_prefix(v) {
|
|
|
|
|
+ if (v.includes('http')) {
|
|
|
|
|
+ return v;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return imgHostUrl + v;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ ...mapGetters(['token'])
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ watch: {
|
|
|
|
|
+ value() {
|
|
|
|
|
+ this.render();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ mounted() {
|
|
|
|
|
+ this.render();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ render() {
|
|
|
|
|
+ const { multiple } = this.props;
|
|
|
|
|
+
|
|
|
|
|
+ let val = this.value;
|
|
|
|
|
+
|
|
|
|
|
+ if (multiple) {
|
|
|
|
|
+ let list = [];
|
|
|
|
|
+
|
|
|
|
|
+ if (val instanceof Array) {
|
|
|
|
|
+ list = val;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ list = (val || '').split(',');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.list = list.filter(Boolean).map(e => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ url: e,
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.ajSize();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.list = [
|
|
|
|
|
+ {
|
|
|
|
|
+ url: val,
|
|
|
|
|
+ loading: false
|
|
|
|
|
+ }
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ callback() {
|
|
|
|
|
+ this.ajSize();
|
|
|
|
|
+
|
|
|
|
|
+ this.$emit(
|
|
|
|
|
+ 'input',
|
|
|
|
|
+ this.list
|
|
|
|
|
+ .filter(e => e.url)
|
|
|
|
|
+ .map(e => e.url)
|
|
|
|
|
+ .join(',')
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ ajSize() {
|
|
|
|
|
+ const { 'multiple-limit': multipleLimit = 1 } = this.props;
|
|
|
|
|
+
|
|
|
|
|
+ if (this.list.length < multipleLimit) {
|
|
|
|
|
+ this.list.unshift({});
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ beforeUpload(file, item, index) {
|
|
|
|
|
+ this.index = index;
|
|
|
|
|
+ if (this.props && this.props['before-upload']) {
|
|
|
|
|
+ this.props['before-upload'](file);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ item.loading = true;
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onSuccess(res, file) {
|
|
|
|
|
+ let item = this.list[this.index];
|
|
|
|
|
+ const { url, smallUrl, shortUrl } = res;
|
|
|
|
|
+ const { multiple } = this.props;
|
|
|
|
|
+
|
|
|
|
|
+ item.loading = false;
|
|
|
|
|
+
|
|
|
|
|
+ if (multiple) {
|
|
|
|
|
+ if (item.url) {
|
|
|
|
|
+ item.url = shortUrl;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // item.url = smallUrl;
|
|
|
|
|
+ this.list.push({
|
|
|
|
|
+ url: shortUrl
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.list = [
|
|
|
|
|
+ {
|
|
|
|
|
+ url: shortUrl
|
|
|
|
|
+ }
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.callback();
|
|
|
|
|
+
|
|
|
|
|
+ console.log('this.props', this.props);
|
|
|
|
|
+ if (this.props && this.props['on-success']) {
|
|
|
|
|
+ this.props['on-success'](res, file);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onError(err, file, fileList) {
|
|
|
|
|
+ console.error('upload error', err);
|
|
|
|
|
+ this.$message.error('图片上传失败');
|
|
|
|
|
+ this.loading = false;
|
|
|
|
|
+
|
|
|
|
|
+ if (this.props && this.props['on-error']) {
|
|
|
|
|
+ this.props['on-error'](err, file, fileList);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ removeFile(i) {
|
|
|
|
|
+ this.list.splice(i, 1);
|
|
|
|
|
+ this.callback();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ //
|
|
|
|
|
+ getFile(file, fileList) {
|
|
|
|
|
+ this.getBase64(file.raw).then(res => {
|
|
|
|
|
+ // this.list = res;
|
|
|
|
|
+ let host = null;
|
|
|
|
|
+ if (this.hostUrl) {
|
|
|
|
|
+ host = () => {
|
|
|
|
|
+ return this.$service.common[this.hostUrl]({ content: res });
|
|
|
|
|
+ };
|
|
|
|
|
+ } else {
|
|
|
|
|
+ host = () => {
|
|
|
|
|
+ return this.$service.common.uploadImg({ content: res });
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ host().then(subRes => {
|
|
|
|
|
+ console.log('subRes', subRes);
|
|
|
|
|
+ this.onSuccess(subRes);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ getBase64(file) {
|
|
|
|
|
+ return new Promise(function(resolve, reject) {
|
|
|
|
|
+ let reader = new FileReader();
|
|
|
|
|
+ let imgResult = '';
|
|
|
|
|
+ reader.readAsDataURL(file);
|
|
|
|
|
+ reader.onload = function() {
|
|
|
|
|
+ imgResult = reader.result;
|
|
|
|
|
+ };
|
|
|
|
|
+ reader.onerror = function(error) {
|
|
|
|
|
+ reject(error);
|
|
|
|
|
+ };
|
|
|
|
|
+ reader.onloadend = function() {
|
|
|
|
|
+ resolve(imgResult);
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="stylus" scoped>
|
|
|
|
|
+.cl-upload {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
|
+
|
|
|
|
|
+ .upload-wrap {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ height: 120px;
|
|
|
|
|
+ width: 120px;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ border: 1px dashed #d9d9d9;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ margin-right: 10px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ .el-icon-plus {
|
|
|
|
|
+ font-size: 28px;
|
|
|
|
|
+ color: #8c939d;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .el-icon-close {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ right: 5px;
|
|
|
|
|
+ top: 5px;
|
|
|
|
|
+ color: red;
|
|
|
|
|
+ background-color: #F56C6C;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ border-radius: 100%;
|
|
|
|
|
+ padding: 2px;
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ background-color: red;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ img {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ border-radius: 6px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &:hover {
|
|
|
|
|
+ border: 1px dashed #409EFF;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|