|
@@ -1,706 +1,721 @@
|
|
-<template>
|
|
|
|
- <div :id="uploadId" class="fm-uplaod-container">
|
|
|
|
- <draggable
|
|
|
|
- v-model="fileList"
|
|
|
|
- class="drag-img-list"
|
|
|
|
- v-bind="{ group: uploadId, ghostClass: 'ghost', animation: 200 }"
|
|
|
|
- :no-transition-on-drag="true"
|
|
|
|
- >
|
|
|
|
- <div
|
|
|
|
- v-for="item in fileList"
|
|
|
|
- :id="item.key"
|
|
|
|
- :key="item.key"
|
|
|
|
- :style="{ width: width + 'px', height: height + 'px' }"
|
|
|
|
- :class="{
|
|
|
|
- uploading: item.status == 'uploading',
|
|
|
|
- 'is-success': item.status == 'success',
|
|
|
|
- 'is-diabled': disabled,
|
|
|
|
- }"
|
|
|
|
- class="upload-file"
|
|
|
|
- >
|
|
|
|
- <img :src="item.url" />
|
|
|
|
-
|
|
|
|
- <el-progress
|
|
|
|
- v-if="item.status == 'uploading'"
|
|
|
|
- :width="miniWidth * 0.9"
|
|
|
|
- class="upload-progress"
|
|
|
|
- type="circle"
|
|
|
|
- :percentage="item.percent"
|
|
|
|
- />
|
|
|
|
-
|
|
|
|
- <label v-if="item.status == 'success'" class="item-status">
|
|
|
|
- <i class="el-icon-upload-success el-icon-check" />
|
|
|
|
- </label>
|
|
|
|
-
|
|
|
|
- <div
|
|
|
|
- v-if="!disabled"
|
|
|
|
- class="uplaod-action"
|
|
|
|
- :style="{ height: miniWidth / 4 + 'px' }"
|
|
|
|
- >
|
|
|
|
- <i
|
|
|
|
- class="iconfont icon-tupianyulan"
|
|
|
|
- :title="'预览'"
|
|
|
|
- :style="{ 'font-size': miniWidth / 8 + 'px' }"
|
|
|
|
- @click="handlePreviewFile(item.key)"
|
|
|
|
- />
|
|
|
|
- <!-- <i
|
|
|
|
- v-if="isEdit"
|
|
|
|
- class="iconfont icon-sync1"
|
|
|
|
- :title="'替换'"
|
|
|
|
- :style="{ 'font-size': miniWidth / 8 + 'px' }"
|
|
|
|
- @click="handleEdit(item.key)"
|
|
|
|
- /> -->
|
|
|
|
- <i
|
|
|
|
- class="iconfont icon-delete"
|
|
|
|
- :title="'删除'"
|
|
|
|
- :style="{ 'font-size': miniWidth / 8 + 'px' }"
|
|
|
|
- @click="handleRemove(item.key)"
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </draggable>
|
|
|
|
- <!-- @click.self="handleAdd" -->
|
|
|
|
- <div
|
|
|
|
- v-if="!preview"
|
|
|
|
- v-show="(!isQiniu || (isQiniu && token)) && fileList.length < length"
|
|
|
|
- class="el-upload el-upload--picture-card"
|
|
|
|
- :class="{ 'is-disabled': disabled }"
|
|
|
|
- :style="{ width: width + 'px', height: height + 'px' }"
|
|
|
|
- >
|
|
|
|
- <el-upload
|
|
|
|
- :action="ossUploadUrl"
|
|
|
|
- :on-success="handleSuccess"
|
|
|
|
- :on-exceed="handleExceed"
|
|
|
|
- :before-upload="beforeUpload"
|
|
|
|
- :show-file-list="false"
|
|
|
|
- accept="image/*"
|
|
|
|
- :limit="5"
|
|
|
|
- :data="dataObj"
|
|
|
|
- style="width: 100%; height: 100%"
|
|
|
|
- >
|
|
|
|
- <i
|
|
|
|
- class="el-icon-plus"
|
|
|
|
- :style="{
|
|
|
|
- fontSize: miniWidth / 4 + 'px',
|
|
|
|
- marginTop: -miniWidth / 8 + 'px',
|
|
|
|
- marginLeft: -miniWidth / 8 + 'px',
|
|
|
|
- }"
|
|
|
|
- ></i>
|
|
|
|
- </el-upload>
|
|
|
|
- <!-- <i
|
|
|
|
- class="el-icon-plus"
|
|
|
|
- :style="{
|
|
|
|
- fontSize: miniWidth / 4 + 'px',
|
|
|
|
- marginTop: -miniWidth / 8 + 'px',
|
|
|
|
- marginLeft: -miniWidth / 8 + 'px'
|
|
|
|
- }"
|
|
|
|
- @click.self="handleAdd"
|
|
|
|
- />
|
|
|
|
- <input
|
|
|
|
- v-if="multiple"
|
|
|
|
- ref="uploadInput"
|
|
|
|
- accept="image/*"
|
|
|
|
- multiple
|
|
|
|
- type="file"
|
|
|
|
- :style="{ width: 0, height: 0 }"
|
|
|
|
- name="file"
|
|
|
|
- class="el-upload__input upload-input"
|
|
|
|
- @change="handleChange"
|
|
|
|
- />
|
|
|
|
- <input
|
|
|
|
- v-else
|
|
|
|
- ref="uploadInput"
|
|
|
|
- accept="image/*"
|
|
|
|
- type="file"
|
|
|
|
- :style="{ width: 0, height: 0 }"
|
|
|
|
- name="file"
|
|
|
|
- class="el-upload__input upload-input"
|
|
|
|
- @change="handleChange"
|
|
|
|
- /> -->
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
-</template>
|
|
|
|
-
|
|
|
|
-<script>
|
|
|
|
-import Vue from "vue";
|
|
|
|
-import Viewer from "viewerjs";
|
|
|
|
-import Draggable from "vuedraggable";
|
|
|
|
-import * as qiniu from "qiniu-js";
|
|
|
|
-require("viewerjs/dist/viewer.css");
|
|
|
|
-import { policy } from "@/api/user";
|
|
|
|
-import VueI18n from "vue-i18n";
|
|
|
|
-Vue.use(VueI18n);
|
|
|
|
-export default {
|
|
|
|
- components: {
|
|
|
|
- Draggable,
|
|
|
|
- },
|
|
|
|
- props: {
|
|
|
|
- value: {
|
|
|
|
- type: Array,
|
|
|
|
- default: () => [],
|
|
|
|
- },
|
|
|
|
- width: {
|
|
|
|
- type: Number,
|
|
|
|
- default: 100,
|
|
|
|
- },
|
|
|
|
- height: {
|
|
|
|
- type: Number,
|
|
|
|
- default: 100,
|
|
|
|
- },
|
|
|
|
- token: {
|
|
|
|
- type: String,
|
|
|
|
- default: "",
|
|
|
|
- },
|
|
|
|
- domain: {
|
|
|
|
- type: String,
|
|
|
|
- default: "",
|
|
|
|
- },
|
|
|
|
- multiple: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false,
|
|
|
|
- },
|
|
|
|
- length: {
|
|
|
|
- type: Number,
|
|
|
|
- default: 9,
|
|
|
|
- },
|
|
|
|
- isQiniu: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false,
|
|
|
|
- },
|
|
|
|
- isDelete: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: true,
|
|
|
|
- },
|
|
|
|
- min: {
|
|
|
|
- type: Number,
|
|
|
|
- default: 0,
|
|
|
|
- },
|
|
|
|
- meitu: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false,
|
|
|
|
- },
|
|
|
|
- isEdit: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false,
|
|
|
|
- },
|
|
|
|
- action: {
|
|
|
|
- type: String,
|
|
|
|
- default: "",
|
|
|
|
- },
|
|
|
|
- disabled: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false,
|
|
|
|
- },
|
|
|
|
- preview: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false,
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- data() {
|
|
|
|
- return {
|
|
|
|
- fileList: this.value.map((item) => {
|
|
|
|
- return {
|
|
|
|
- key: item.key
|
|
|
|
- ? item.key
|
|
|
|
- : new Date().getTime() + "_" + Math.ceil(Math.random() * 99999),
|
|
|
|
- url: item.url,
|
|
|
|
- percent: item.percent ? item.percent : 100,
|
|
|
|
- status: item.status ? item.status : "success",
|
|
|
|
- };
|
|
|
|
- }),
|
|
|
|
- viewer: null,
|
|
|
|
- uploadId: "upload_" + new Date().getTime(),
|
|
|
|
- editIndex: -1,
|
|
|
|
- meituIndex: -1,
|
|
|
|
- // ossUploadUrl: "https://ks3-cn-beijing.ksyuncs.com/daya",
|
|
|
|
- ossUploadUrl: "https://daya.ks3-cn-beijing.ksyuncs.com",
|
|
|
|
- dataObj: {
|
|
|
|
- policy: "",
|
|
|
|
- signature: "",
|
|
|
|
- key: "",
|
|
|
|
- KSSAccessKeyId: "",
|
|
|
|
- acl: "public-read",
|
|
|
|
- name: "",
|
|
|
|
- },
|
|
|
|
- };
|
|
|
|
- },
|
|
|
|
- computed: {
|
|
|
|
- miniWidth() {
|
|
|
|
- if (this.width > this.height) {
|
|
|
|
- return this.height;
|
|
|
|
- } else {
|
|
|
|
- return this.width;
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- watch: {
|
|
|
|
- fileList: {
|
|
|
|
- deep: true,
|
|
|
|
- handler(val) {
|
|
|
|
- // this.$emit('input', this.fileList)
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
- mounted() {
|
|
|
|
- this.$emit("input", this.fileList);
|
|
|
|
- },
|
|
|
|
- methods: {
|
|
|
|
- handleExceed(files, fileList) {
|
|
|
|
- this.$message.warning(`最多允许上传 5 张图片。`);
|
|
|
|
- },
|
|
|
|
- async beforeUpload(file) {
|
|
|
|
- const isLt2M = file.size / 1024 / 1024 < 5;
|
|
|
|
- if (!isLt2M) {
|
|
|
|
- this.$message.error("上传图片大小不能超过 5MB!");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- try {
|
|
|
|
- let filename = file.name.replaceAll(" ", "_");
|
|
|
|
- let key = new Date().getTime() + filename;
|
|
|
|
- let obj = {
|
|
|
|
- filename,
|
|
|
|
- bucketName: "daya",
|
|
|
|
- postData: {
|
|
|
|
- filename,
|
|
|
|
- acl: "public-read",
|
|
|
|
- key,
|
|
|
|
- unknowValueField: [],
|
|
|
|
- },
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- const res = await policy(obj);
|
|
|
|
- this.dataObj = {
|
|
|
|
- policy: res.data.policy,
|
|
|
|
- signature: res.data.signature,
|
|
|
|
- key,
|
|
|
|
- KSSAccessKeyId: res.data.kssAccessKeyId,
|
|
|
|
- acl: "public-read",
|
|
|
|
- name: filename,
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- return isLt2M;
|
|
|
|
- } catch {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- handleSuccess(response, file, fileList) {
|
|
|
|
- let url = this.ossUploadUrl + "/" + this.dataObj.key;
|
|
|
|
- this.fileList.push({
|
|
|
|
- uid: file.uid,
|
|
|
|
- name: file.name,
|
|
|
|
- url,
|
|
|
|
- percent: 100,
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- handleChange() {
|
|
|
|
- const files = this.$refs.uploadInput.files;
|
|
|
|
-
|
|
|
|
- for (let i = 0; i < files.length; i++) {
|
|
|
|
- const file = files[i];
|
|
|
|
- const reader = new FileReader();
|
|
|
|
- const key =
|
|
|
|
- new Date().getTime() + "_" + Math.ceil(Math.random() * 99999);
|
|
|
|
- reader.readAsDataURL(file);
|
|
|
|
- reader.onload = () => {
|
|
|
|
- if (this.editIndex >= 0) {
|
|
|
|
- this.$set(this.fileList, this.editIndex, {
|
|
|
|
- key,
|
|
|
|
- url: reader.result,
|
|
|
|
- percent: 0,
|
|
|
|
- status: "uploading",
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- this.editIndex = -1;
|
|
|
|
- } else {
|
|
|
|
- this.fileList.push({
|
|
|
|
- key,
|
|
|
|
- url: reader.result,
|
|
|
|
- percent: 0,
|
|
|
|
- status: "uploading",
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this.$nextTick(() => {
|
|
|
|
- this.uplaodAction(reader.result, file, key);
|
|
|
|
- // if (this.isQiniu) {
|
|
|
|
- // this.uplaodAction2(reader.result, file, key)
|
|
|
|
- // } else {
|
|
|
|
- // this.uplaodAction(reader.result, file, key)
|
|
|
|
- // }
|
|
|
|
- });
|
|
|
|
- };
|
|
|
|
- }
|
|
|
|
- this.$refs.uploadInput.value = [];
|
|
|
|
- },
|
|
|
|
- async uplaodAction(res, file, key) {
|
|
|
|
- try {
|
|
|
|
- let filename = file.name.replaceAll(" ", "_");
|
|
|
|
- let key = new Date().getTime() + filename;
|
|
|
|
- let obj = {
|
|
|
|
- filename,
|
|
|
|
- bucketName: "daya",
|
|
|
|
- postData: {
|
|
|
|
- filename,
|
|
|
|
- acl: "public-read",
|
|
|
|
- key,
|
|
|
|
- unknowValueField: [],
|
|
|
|
- },
|
|
|
|
- };
|
|
|
|
- const res = await policy(obj);
|
|
|
|
- this.dataObj = {
|
|
|
|
- policy: res.data.policy,
|
|
|
|
- signature: res.data.signature,
|
|
|
|
- key,
|
|
|
|
- KSSAccessKeyId: res.data.kssAccessKeyId,
|
|
|
|
- acl: "public-read",
|
|
|
|
- name: filename,
|
|
|
|
- };
|
|
|
|
- } catch {}
|
|
|
|
- // eslint-disable-next-line no-unused-vars
|
|
|
|
- const changeIndex = this.fileList.findIndex((item) => item.key === key);
|
|
|
|
- const xhr = new XMLHttpRequest();
|
|
|
|
-
|
|
|
|
- const url = this.ossUploadUrl;
|
|
|
|
- xhr.open("POST", url, true);
|
|
|
|
- // xhr.setRequestHeader('Content-Type', 'multipart/form-data')
|
|
|
|
-
|
|
|
|
- const formData = new FormData();
|
|
|
|
- formData.append(this.dataObj.name, file, this.dataObj.name);
|
|
|
|
- formData.append("policy", this.dataObj.policy);
|
|
|
|
- formData.append("signature", this.dataObj.signature);
|
|
|
|
- formData.append("key", this.dataObj.key);
|
|
|
|
- formData.append("KSSAccessKeyId", this.dataObj.KSSAccessKeyId);
|
|
|
|
- formData.append("acl", "public-read");
|
|
|
|
- formData.append("name", this.dataObj.name);
|
|
|
|
-
|
|
|
|
- xhr.send(formData);
|
|
|
|
- xhr.onreadystatechange = () => {
|
|
|
|
- if (xhr.readyState === 4) {
|
|
|
|
- console.log(xhr, "xhr");
|
|
|
|
- const tempData = JSON.parse(xhr.response);
|
|
|
|
- const resData = tempData.data;
|
|
|
|
- var uploadUrl = "";
|
|
|
|
- if (
|
|
|
|
- resData.url !== undefined &&
|
|
|
|
- resData.url !== null &&
|
|
|
|
- resData.url !== ""
|
|
|
|
- ) {
|
|
|
|
- uploadUrl = resData.url;
|
|
|
|
- } else if (
|
|
|
|
- resData.data !== undefined &&
|
|
|
|
- resData.data !== null &&
|
|
|
|
- resData.data !== ""
|
|
|
|
- ) {
|
|
|
|
- uploadUrl = resData.data;
|
|
|
|
- }
|
|
|
|
- if (resData && uploadUrl) {
|
|
|
|
- this.$set(
|
|
|
|
- this.fileList,
|
|
|
|
- this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- {
|
|
|
|
- ...this.fileList[
|
|
|
|
- this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- ],
|
|
|
|
- url: uploadUrl,
|
|
|
|
- percent: 100,
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- setTimeout(() => {
|
|
|
|
- this.$set(
|
|
|
|
- this.fileList,
|
|
|
|
- this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- {
|
|
|
|
- ...this.fileList[
|
|
|
|
- this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- ],
|
|
|
|
- status: "success",
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- this.$emit("input", this.fileList);
|
|
|
|
- }, 200);
|
|
|
|
- } else {
|
|
|
|
- this.$set(
|
|
|
|
- this.fileList,
|
|
|
|
- this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- {
|
|
|
|
- ...this.fileList[
|
|
|
|
- this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- ],
|
|
|
|
- status: "error",
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- this.fileList.splice(
|
|
|
|
- this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- 1
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- xhr.onprogress = (res) => {
|
|
|
|
- if (res.total && res.loaded) {
|
|
|
|
- this.$set(
|
|
|
|
- this.fileList[this.fileList.findIndex((item) => item.key === key)],
|
|
|
|
- "percent",
|
|
|
|
- (res.loaded / res.total) * 100
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- },
|
|
|
|
- uplaodAction2(res, file, key) {
|
|
|
|
- const _this = this;
|
|
|
|
- const observable = qiniu.upload(
|
|
|
|
- file,
|
|
|
|
- key,
|
|
|
|
- this.token,
|
|
|
|
- {
|
|
|
|
- fname: key,
|
|
|
|
- mimeType: [],
|
|
|
|
- },
|
|
|
|
- {
|
|
|
|
- useCdnDomain: true,
|
|
|
|
- region: qiniu.region.z2,
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- observable.subscribe({
|
|
|
|
- next(res) {
|
|
|
|
- _this.$set(
|
|
|
|
- _this.fileList[
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- ],
|
|
|
|
- "percent",
|
|
|
|
- parseInt(res.total.percent)
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- // eslint-disable-next-line handle-callback-err
|
|
|
|
- error(err) {
|
|
|
|
- _this.$set(
|
|
|
|
- _this.fileList,
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- {
|
|
|
|
- ..._this.fileList[
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- ],
|
|
|
|
- status: "error",
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- _this.fileList.splice(
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- 1
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- complete(res) {
|
|
|
|
- _this.$set(
|
|
|
|
- _this.fileList,
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- {
|
|
|
|
- ..._this.fileList[
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- ],
|
|
|
|
- url: _this.domain + res.key,
|
|
|
|
- percent: 100,
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- setTimeout(() => {
|
|
|
|
- _this.$set(
|
|
|
|
- _this.fileList,
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- {
|
|
|
|
- ..._this.fileList[
|
|
|
|
- _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- ],
|
|
|
|
- status: "success",
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- _this.$emit("input", _this.fileList);
|
|
|
|
- }, 200);
|
|
|
|
- },
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- handleRemove(key) {
|
|
|
|
- this.fileList.splice(
|
|
|
|
- this.fileList.findIndex((item) => item.key === key),
|
|
|
|
- 1
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- handleEdit(key) {
|
|
|
|
- this.editIndex = this.fileList.findIndex((item) => item.key === key);
|
|
|
|
-
|
|
|
|
- this.$refs.uploadInput.click();
|
|
|
|
- },
|
|
|
|
- handleMeitu(key) {
|
|
|
|
- this.$emit(
|
|
|
|
- "on-meitu",
|
|
|
|
- this.fileList.findIndex((item) => item.key === key)
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
- handleAdd() {
|
|
|
|
- if (!this.disabled) {
|
|
|
|
- this.editIndex = -1;
|
|
|
|
- this.$refs.uploadInput.click();
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- handlePreviewFile(key) {
|
|
|
|
- this.viewer && this.viewer.destroy();
|
|
|
|
- this.uploadId = "upload_" + new Date().getTime();
|
|
|
|
-
|
|
|
|
- this.$nextTick(() => {
|
|
|
|
- this.viewer = new Viewer(document.getElementById(this.uploadId));
|
|
|
|
- this.viewer.view(this.fileList.findIndex((item) => item.key === key));
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- },
|
|
|
|
-};
|
|
|
|
-</script>
|
|
|
|
-
|
|
|
|
-<style lang="scss">
|
|
|
|
-.fm-uplaod-container {
|
|
|
|
- .is-disabled {
|
|
|
|
- position: relative;
|
|
|
|
-
|
|
|
|
- &::after {
|
|
|
|
- position: absolute;
|
|
|
|
- top: 0;
|
|
|
|
- bottom: 0;
|
|
|
|
- left: 0;
|
|
|
|
- right: 0;
|
|
|
|
- // background: rgba(0,0,0,.1);
|
|
|
|
- content: "";
|
|
|
|
- display: block;
|
|
|
|
- cursor: not-allowed;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .upload-file {
|
|
|
|
- margin: 0 10px 10px 0;
|
|
|
|
- display: inline-flex;
|
|
|
|
- justify-content: center;
|
|
|
|
- align-items: center;
|
|
|
|
- // background: #fff;
|
|
|
|
- overflow: hidden;
|
|
|
|
- background-color: #fff;
|
|
|
|
- border: 1px solid #c0ccda;
|
|
|
|
- border-radius: 6px;
|
|
|
|
- box-sizing: border-box;
|
|
|
|
- position: relative;
|
|
|
|
- vertical-align: top;
|
|
|
|
- &:hover {
|
|
|
|
- .uplaod-action {
|
|
|
|
- display: flex;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- .uplaod-action {
|
|
|
|
- position: absolute;
|
|
|
|
- // top: 0;
|
|
|
|
- // height: 30px;
|
|
|
|
- bottom: 0;
|
|
|
|
- left: 0;
|
|
|
|
- right: 0;
|
|
|
|
- background: rgba(0, 0, 0, 0.6);
|
|
|
|
- display: none;
|
|
|
|
- justify-content: center;
|
|
|
|
- align-items: center;
|
|
|
|
- i {
|
|
|
|
- color: #fff;
|
|
|
|
- cursor: pointer;
|
|
|
|
- margin: 0 5px;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- &.is-success {
|
|
|
|
- .item-status {
|
|
|
|
- position: absolute;
|
|
|
|
- right: -15px;
|
|
|
|
- top: -6px;
|
|
|
|
- width: 40px;
|
|
|
|
- height: 24px;
|
|
|
|
- background: #13ce66;
|
|
|
|
- text-align: center;
|
|
|
|
- transform: rotate(45deg);
|
|
|
|
- box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
|
|
|
|
- & > i {
|
|
|
|
- font-size: 12px;
|
|
|
|
- margin-top: 11px;
|
|
|
|
- color: #fff;
|
|
|
|
- transform: rotate(-45deg);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- &.uploading {
|
|
|
|
- &:before {
|
|
|
|
- display: block;
|
|
|
|
- content: "";
|
|
|
|
- position: absolute;
|
|
|
|
- top: 0;
|
|
|
|
- left: 0;
|
|
|
|
- right: 0;
|
|
|
|
- bottom: 0;
|
|
|
|
- background: rgba(0, 0, 0, 0.3);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- .upload-progress {
|
|
|
|
- position: absolute;
|
|
|
|
- .el-progress__text {
|
|
|
|
- color: #fff;
|
|
|
|
- font-size: 16px !important;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- img {
|
|
|
|
- max-width: 100%;
|
|
|
|
- max-height: 100%;
|
|
|
|
- vertical-align: middle;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- .el-upload--picture-card {
|
|
|
|
- position: relative;
|
|
|
|
- overflow: hidden;
|
|
|
|
- .el-icon-plus {
|
|
|
|
- position: absolute;
|
|
|
|
- top: 50%;
|
|
|
|
- left: 50%;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- .upload-input {
|
|
|
|
- position: absolute;
|
|
|
|
- top: 0;
|
|
|
|
- left: 0;
|
|
|
|
- right: 0;
|
|
|
|
- bottom: 0;
|
|
|
|
- display: block;
|
|
|
|
- opacity: 0;
|
|
|
|
- cursor: pointer;
|
|
|
|
- }
|
|
|
|
- .el-upload--text {
|
|
|
|
- width: 100%;
|
|
|
|
- height: 100%;
|
|
|
|
- display: block;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .drag-img-list {
|
|
|
|
- display: inline;
|
|
|
|
-
|
|
|
|
- .ghost {
|
|
|
|
- position: relative;
|
|
|
|
- &::after {
|
|
|
|
- width: 100%;
|
|
|
|
- height: 100%;
|
|
|
|
- display: block;
|
|
|
|
- content: "";
|
|
|
|
- background: #fbfdff;
|
|
|
|
- position: absolute;
|
|
|
|
- top: 0;
|
|
|
|
- bottom: 0;
|
|
|
|
- left: 0;
|
|
|
|
- right: 0;
|
|
|
|
- border: 1px dashed #3bb3c2;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- & > div {
|
|
|
|
- cursor: move;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-.viewer-container {
|
|
|
|
- z-index: 9999 !important;
|
|
|
|
-}
|
|
|
|
-</style>
|
|
|
|
|
|
+<template>
|
|
|
|
+ <div :id="uploadId" class="fm-uplaod-container">
|
|
|
|
+ <draggable
|
|
|
|
+ v-model="fileList"
|
|
|
|
+ class="drag-img-list"
|
|
|
|
+ v-bind="{ group: uploadId, ghostClass: 'ghost', animation: 200 }"
|
|
|
|
+ :no-transition-on-drag="true"
|
|
|
|
+ >
|
|
|
|
+ <div
|
|
|
|
+ v-for="item in fileList"
|
|
|
|
+ :id="item.key"
|
|
|
|
+ :key="item.key"
|
|
|
|
+ :style="{ width: width + 'px', height: height + 'px' }"
|
|
|
|
+ :class="{
|
|
|
|
+ uploading: item.status == 'uploading',
|
|
|
|
+ 'is-success': item.status == 'success',
|
|
|
|
+ 'is-diabled': disabled,
|
|
|
|
+ }"
|
|
|
|
+ class="upload-file"
|
|
|
|
+ >
|
|
|
|
+ <img :src="item.url" />
|
|
|
|
+
|
|
|
|
+ <el-progress
|
|
|
|
+ v-if="item.status == 'uploading'"
|
|
|
|
+ :width="miniWidth * 0.9"
|
|
|
|
+ class="upload-progress"
|
|
|
|
+ type="circle"
|
|
|
|
+ :percentage="item.percent"
|
|
|
|
+ />
|
|
|
|
+
|
|
|
|
+ <label v-if="item.status == 'success'" class="item-status">
|
|
|
|
+ <i class="el-icon-upload-success el-icon-check" />
|
|
|
|
+ </label>
|
|
|
|
+
|
|
|
|
+ <div
|
|
|
|
+ v-if="!disabled"
|
|
|
|
+ class="uplaod-action"
|
|
|
|
+ :style="{ height: miniWidth / 4 + 'px' }"
|
|
|
|
+ >
|
|
|
|
+ <i
|
|
|
|
+ class="iconfont icon-tupianyulan"
|
|
|
|
+ :title="'预览'"
|
|
|
|
+ :style="{ 'font-size': miniWidth / 8 + 'px' }"
|
|
|
|
+ @click="handlePreviewFile(item.key)"
|
|
|
|
+ />
|
|
|
|
+ <!-- <i
|
|
|
|
+ v-if="isEdit"
|
|
|
|
+ class="iconfont icon-sync1"
|
|
|
|
+ :title="'替换'"
|
|
|
|
+ :style="{ 'font-size': miniWidth / 8 + 'px' }"
|
|
|
|
+ @click="handleEdit(item.key)"
|
|
|
|
+ /> -->
|
|
|
|
+ <i
|
|
|
|
+ class="iconfont icon-delete"
|
|
|
|
+ :title="'删除'"
|
|
|
|
+ :style="{ 'font-size': miniWidth / 8 + 'px' }"
|
|
|
|
+ @click="handleRemove(item.key)"
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </draggable>
|
|
|
|
+ <!-- @click.self="handleAdd" -->
|
|
|
|
+ <div
|
|
|
|
+ v-if="!preview"
|
|
|
|
+ v-show="(!isQiniu || (isQiniu && token)) && fileList.length < length"
|
|
|
|
+ class="el-upload el-upload--picture-card"
|
|
|
|
+ :class="{ 'is-disabled': disabled }"
|
|
|
|
+ :style="{ width: width + 'px', height: height + 'px' }"
|
|
|
|
+ >
|
|
|
|
+ <el-upload
|
|
|
|
+ :action="ossUploadUrl"
|
|
|
|
+ :http-request="handleSuccess"
|
|
|
|
+ :on-exceed="handleExceed"
|
|
|
|
+ :before-upload="beforeUpload"
|
|
|
|
+ :show-file-list="false"
|
|
|
|
+ accept="image/*"
|
|
|
|
+ :limit="5"
|
|
|
|
+ :data="dataObj"
|
|
|
|
+ style="width: 100%; height: 100%"
|
|
|
|
+ >
|
|
|
|
+ <i
|
|
|
|
+ class="el-icon-plus"
|
|
|
|
+ :style="{
|
|
|
|
+ fontSize: miniWidth / 4 + 'px',
|
|
|
|
+ marginTop: -miniWidth / 8 + 'px',
|
|
|
|
+ marginLeft: -miniWidth / 8 + 'px',
|
|
|
|
+ }"
|
|
|
|
+ ></i>
|
|
|
|
+ </el-upload>
|
|
|
|
+ <!-- <i
|
|
|
|
+ class="el-icon-plus"
|
|
|
|
+ :style="{
|
|
|
|
+ fontSize: miniWidth / 4 + 'px',
|
|
|
|
+ marginTop: -miniWidth / 8 + 'px',
|
|
|
|
+ marginLeft: -miniWidth / 8 + 'px'
|
|
|
|
+ }"
|
|
|
|
+ @click.self="handleAdd"
|
|
|
|
+ />
|
|
|
|
+ <input
|
|
|
|
+ v-if="multiple"
|
|
|
|
+ ref="uploadInput"
|
|
|
|
+ accept="image/*"
|
|
|
|
+ multiple
|
|
|
|
+ type="file"
|
|
|
|
+ :style="{ width: 0, height: 0 }"
|
|
|
|
+ name="file"
|
|
|
|
+ class="el-upload__input upload-input"
|
|
|
|
+ @change="handleChange"
|
|
|
|
+ />
|
|
|
|
+ <input
|
|
|
|
+ v-else
|
|
|
|
+ ref="uploadInput"
|
|
|
|
+ accept="image/*"
|
|
|
|
+ type="file"
|
|
|
|
+ :style="{ width: 0, height: 0 }"
|
|
|
|
+ name="file"
|
|
|
|
+ class="el-upload__input upload-input"
|
|
|
|
+ @change="handleChange"
|
|
|
|
+ /> -->
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import Vue from "vue";
|
|
|
|
+import Viewer from "viewerjs";
|
|
|
|
+import Draggable from "vuedraggable";
|
|
|
|
+import * as qiniu from "qiniu-js";
|
|
|
|
+require("viewerjs/dist/viewer.css");
|
|
|
|
+import { policy } from "@/api/user";
|
|
|
|
+import VueI18n from "vue-i18n";
|
|
|
|
+Vue.use(VueI18n);
|
|
|
|
+import { getUploadSign, onOnlyFileUpload } from "@/helpers/oss-file-upload";
|
|
|
|
+export default {
|
|
|
|
+ components: {
|
|
|
|
+ Draggable,
|
|
|
|
+ },
|
|
|
|
+ props: {
|
|
|
|
+ value: {
|
|
|
|
+ type: Array,
|
|
|
|
+ default: () => [],
|
|
|
|
+ },
|
|
|
|
+ width: {
|
|
|
|
+ type: Number,
|
|
|
|
+ default: 100,
|
|
|
|
+ },
|
|
|
|
+ height: {
|
|
|
|
+ type: Number,
|
|
|
|
+ default: 100,
|
|
|
|
+ },
|
|
|
|
+ token: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: "",
|
|
|
|
+ },
|
|
|
|
+ domain: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: "",
|
|
|
|
+ },
|
|
|
|
+ multiple: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false,
|
|
|
|
+ },
|
|
|
|
+ length: {
|
|
|
|
+ type: Number,
|
|
|
|
+ default: 9,
|
|
|
|
+ },
|
|
|
|
+ isQiniu: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false,
|
|
|
|
+ },
|
|
|
|
+ isDelete: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true,
|
|
|
|
+ },
|
|
|
|
+ min: {
|
|
|
|
+ type: Number,
|
|
|
|
+ default: 0,
|
|
|
|
+ },
|
|
|
|
+ meitu: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false,
|
|
|
|
+ },
|
|
|
|
+ isEdit: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false,
|
|
|
|
+ },
|
|
|
|
+ action: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: "",
|
|
|
|
+ },
|
|
|
|
+ disabled: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false,
|
|
|
|
+ },
|
|
|
|
+ preview: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ fileList: this.value.map((item) => {
|
|
|
|
+ return {
|
|
|
|
+ key: item.key
|
|
|
|
+ ? item.key
|
|
|
|
+ : new Date().getTime() + "_" + Math.ceil(Math.random() * 99999),
|
|
|
|
+ url: item.url,
|
|
|
|
+ percent: item.percent ? item.percent : 100,
|
|
|
|
+ status: item.status ? item.status : "success",
|
|
|
|
+ };
|
|
|
|
+ }),
|
|
|
|
+ viewer: null,
|
|
|
|
+ uploadId: "upload_" + new Date().getTime(),
|
|
|
|
+ editIndex: -1,
|
|
|
|
+ meituIndex: -1,
|
|
|
|
+ // ossUploadUrl: "https://ks3-cn-beijing.ksyuncs.com/daya",
|
|
|
|
+ ossUploadUrl: "https://daya.ks3-cn-beijing.ksyuncs.com",
|
|
|
|
+ dataObj: {
|
|
|
|
+ policy: "",
|
|
|
|
+ signature: "",
|
|
|
|
+ key: "",
|
|
|
|
+ KSSAccessKeyId: "",
|
|
|
|
+ acl: "public-read",
|
|
|
|
+ name: "",
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ miniWidth() {
|
|
|
|
+ if (this.width > this.height) {
|
|
|
|
+ return this.height;
|
|
|
|
+ } else {
|
|
|
|
+ return this.width;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ fileList: {
|
|
|
|
+ deep: true,
|
|
|
|
+ handler(val) {
|
|
|
|
+ // this.$emit('input', this.fileList)
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ mounted() {
|
|
|
|
+ this.$emit("input", this.fileList);
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ handleExceed(files, fileList) {
|
|
|
|
+ this.$message.warning(`最多允许上传 5 张图片。`);
|
|
|
|
+ },
|
|
|
|
+ async beforeUpload(file) {
|
|
|
|
+ const isLt2M = file.size / 1024 / 1024 < 5;
|
|
|
|
+ if (!isLt2M) {
|
|
|
|
+ this.$message.error("上传图片大小不能超过 5MB!");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ let filename = file.name.replaceAll(" ", "_");
|
|
|
|
+ let key = new Date().getTime() + filename;
|
|
|
|
+ let obj = {
|
|
|
|
+ filename,
|
|
|
|
+ bucketName: "daya",
|
|
|
|
+ postData: {
|
|
|
|
+ filename,
|
|
|
|
+ acl: "public-read",
|
|
|
|
+ key,
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // const res = await policy(obj);
|
|
|
|
+ const res = await getUploadSign(obj);
|
|
|
|
+ this.dataObj = {
|
|
|
|
+ policy: res.data.policy,
|
|
|
|
+ signature: res.data.signature,
|
|
|
|
+ key,
|
|
|
|
+ KSSAccessKeyId: res.data.kssAccessKeyId,
|
|
|
|
+ acl: "public-read",
|
|
|
|
+ name: filename,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return isLt2M;
|
|
|
|
+ } catch {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ async handleSuccess(info) {
|
|
|
|
+ try {
|
|
|
|
+ const obj = {
|
|
|
|
+ policy: info.data.policy,
|
|
|
|
+ signature: info.data.signature,
|
|
|
|
+ key: info.data.key,
|
|
|
|
+ KSSAccessKeyId: info.data.kssAccessKeyId,
|
|
|
|
+ acl: "public-read",
|
|
|
|
+ name: info.data.key,
|
|
|
|
+ file: info.file,
|
|
|
|
+ };
|
|
|
|
+ const url = await onOnlyFileUpload(this.ossUploadUrl, obj);
|
|
|
|
+ this.fileList.push({
|
|
|
|
+ uid: info.file.uid,
|
|
|
|
+ name: info.file.name,
|
|
|
|
+ url,
|
|
|
|
+ percent: 100,
|
|
|
|
+ });
|
|
|
|
+ } catch (e) {
|
|
|
|
+ //
|
|
|
|
+ console.log(e, "e.message");
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ handleChange() {
|
|
|
|
+ const files = this.$refs.uploadInput.files;
|
|
|
|
+
|
|
|
|
+ for (let i = 0; i < files.length; i++) {
|
|
|
|
+ const file = files[i];
|
|
|
|
+ const reader = new FileReader();
|
|
|
|
+ const key =
|
|
|
|
+ new Date().getTime() + "_" + Math.ceil(Math.random() * 99999);
|
|
|
|
+ reader.readAsDataURL(file);
|
|
|
|
+ reader.onload = () => {
|
|
|
|
+ if (this.editIndex >= 0) {
|
|
|
|
+ this.$set(this.fileList, this.editIndex, {
|
|
|
|
+ key,
|
|
|
|
+ url: reader.result,
|
|
|
|
+ percent: 0,
|
|
|
|
+ status: "uploading",
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.editIndex = -1;
|
|
|
|
+ } else {
|
|
|
|
+ this.fileList.push({
|
|
|
|
+ key,
|
|
|
|
+ url: reader.result,
|
|
|
|
+ percent: 0,
|
|
|
|
+ status: "uploading",
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.uplaodAction(reader.result, file, key);
|
|
|
|
+ // if (this.isQiniu) {
|
|
|
|
+ // this.uplaodAction2(reader.result, file, key)
|
|
|
|
+ // } else {
|
|
|
|
+ // this.uplaodAction(reader.result, file, key)
|
|
|
|
+ // }
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ this.$refs.uploadInput.value = [];
|
|
|
|
+ },
|
|
|
|
+ async uplaodAction(res, file, key) {
|
|
|
|
+ try {
|
|
|
|
+ let filename = file.name.replaceAll(" ", "_");
|
|
|
|
+ let key = new Date().getTime() + filename;
|
|
|
|
+ let obj = {
|
|
|
|
+ filename,
|
|
|
|
+ bucketName: "daya",
|
|
|
|
+ postData: {
|
|
|
|
+ filename,
|
|
|
|
+ acl: "public-read",
|
|
|
|
+ key,
|
|
|
|
+ unknowValueField: [],
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ const res = await policy(obj);
|
|
|
|
+ this.dataObj = {
|
|
|
|
+ policy: res.data.policy,
|
|
|
|
+ signature: res.data.signature,
|
|
|
|
+ key,
|
|
|
|
+ KSSAccessKeyId: res.data.kssAccessKeyId,
|
|
|
|
+ acl: "public-read",
|
|
|
|
+ name: filename,
|
|
|
|
+ };
|
|
|
|
+ } catch {}
|
|
|
|
+ // eslint-disable-next-line no-unused-vars
|
|
|
|
+ const changeIndex = this.fileList.findIndex((item) => item.key === key);
|
|
|
|
+ const xhr = new XMLHttpRequest();
|
|
|
|
+
|
|
|
|
+ const url = this.ossUploadUrl;
|
|
|
|
+ xhr.open("POST", url, true);
|
|
|
|
+ // xhr.setRequestHeader('Content-Type', 'multipart/form-data')
|
|
|
|
+
|
|
|
|
+ const formData = new FormData();
|
|
|
|
+ formData.append(this.dataObj.name, file, this.dataObj.name);
|
|
|
|
+ formData.append("policy", this.dataObj.policy);
|
|
|
|
+ formData.append("signature", this.dataObj.signature);
|
|
|
|
+ formData.append("key", this.dataObj.key);
|
|
|
|
+ formData.append("KSSAccessKeyId", this.dataObj.KSSAccessKeyId);
|
|
|
|
+ formData.append("acl", "public-read");
|
|
|
|
+ formData.append("name", this.dataObj.name);
|
|
|
|
+
|
|
|
|
+ xhr.send(formData);
|
|
|
|
+ xhr.onreadystatechange = () => {
|
|
|
|
+ if (xhr.readyState === 4) {
|
|
|
|
+ console.log(xhr, "xhr");
|
|
|
|
+ const tempData = JSON.parse(xhr.response);
|
|
|
|
+ const resData = tempData.data;
|
|
|
|
+ var uploadUrl = "";
|
|
|
|
+ if (
|
|
|
|
+ resData.url !== undefined &&
|
|
|
|
+ resData.url !== null &&
|
|
|
|
+ resData.url !== ""
|
|
|
|
+ ) {
|
|
|
|
+ uploadUrl = resData.url;
|
|
|
|
+ } else if (
|
|
|
|
+ resData.data !== undefined &&
|
|
|
|
+ resData.data !== null &&
|
|
|
|
+ resData.data !== ""
|
|
|
|
+ ) {
|
|
|
|
+ uploadUrl = resData.data;
|
|
|
|
+ }
|
|
|
|
+ if (resData && uploadUrl) {
|
|
|
|
+ this.$set(
|
|
|
|
+ this.fileList,
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ {
|
|
|
|
+ ...this.fileList[
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ ],
|
|
|
|
+ url: uploadUrl,
|
|
|
|
+ percent: 100,
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.$set(
|
|
|
|
+ this.fileList,
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ {
|
|
|
|
+ ...this.fileList[
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ ],
|
|
|
|
+ status: "success",
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ this.$emit("input", this.fileList);
|
|
|
|
+ }, 200);
|
|
|
|
+ } else {
|
|
|
|
+ this.$set(
|
|
|
|
+ this.fileList,
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ {
|
|
|
|
+ ...this.fileList[
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ ],
|
|
|
|
+ status: "error",
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ this.fileList.splice(
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ 1
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ xhr.onprogress = (res) => {
|
|
|
|
+ if (res.total && res.loaded) {
|
|
|
|
+ this.$set(
|
|
|
|
+ this.fileList[this.fileList.findIndex((item) => item.key === key)],
|
|
|
|
+ "percent",
|
|
|
|
+ (res.loaded / res.total) * 100
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ uplaodAction2(res, file, key) {
|
|
|
|
+ const _this = this;
|
|
|
|
+ const observable = qiniu.upload(
|
|
|
|
+ file,
|
|
|
|
+ key,
|
|
|
|
+ this.token,
|
|
|
|
+ {
|
|
|
|
+ fname: key,
|
|
|
|
+ mimeType: [],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ useCdnDomain: true,
|
|
|
|
+ region: qiniu.region.z2,
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ observable.subscribe({
|
|
|
|
+ next(res) {
|
|
|
|
+ _this.$set(
|
|
|
|
+ _this.fileList[
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ ],
|
|
|
|
+ "percent",
|
|
|
|
+ parseInt(res.total.percent)
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ // eslint-disable-next-line handle-callback-err
|
|
|
|
+ error(err) {
|
|
|
|
+ _this.$set(
|
|
|
|
+ _this.fileList,
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ {
|
|
|
|
+ ..._this.fileList[
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ ],
|
|
|
|
+ status: "error",
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ _this.fileList.splice(
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ 1
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ complete(res) {
|
|
|
|
+ _this.$set(
|
|
|
|
+ _this.fileList,
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ {
|
|
|
|
+ ..._this.fileList[
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ ],
|
|
|
|
+ url: _this.domain + res.key,
|
|
|
|
+ percent: 100,
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ _this.$set(
|
|
|
|
+ _this.fileList,
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ {
|
|
|
|
+ ..._this.fileList[
|
|
|
|
+ _this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ ],
|
|
|
|
+ status: "success",
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ _this.$emit("input", _this.fileList);
|
|
|
|
+ }, 200);
|
|
|
|
+ },
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ handleRemove(key) {
|
|
|
|
+ this.fileList.splice(
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key),
|
|
|
|
+ 1
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ handleEdit(key) {
|
|
|
|
+ this.editIndex = this.fileList.findIndex((item) => item.key === key);
|
|
|
|
+
|
|
|
|
+ this.$refs.uploadInput.click();
|
|
|
|
+ },
|
|
|
|
+ handleMeitu(key) {
|
|
|
|
+ this.$emit(
|
|
|
|
+ "on-meitu",
|
|
|
|
+ this.fileList.findIndex((item) => item.key === key)
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ handleAdd() {
|
|
|
|
+ if (!this.disabled) {
|
|
|
|
+ this.editIndex = -1;
|
|
|
|
+ this.$refs.uploadInput.click();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ handlePreviewFile(key) {
|
|
|
|
+ this.viewer && this.viewer.destroy();
|
|
|
|
+ this.uploadId = "upload_" + new Date().getTime();
|
|
|
|
+
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.viewer = new Viewer(document.getElementById(this.uploadId));
|
|
|
|
+ this.viewer.view(this.fileList.findIndex((item) => item.key === key));
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="scss">
|
|
|
|
+.fm-uplaod-container {
|
|
|
|
+ .is-disabled {
|
|
|
|
+ position: relative;
|
|
|
|
+
|
|
|
|
+ &::after {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ // background: rgba(0,0,0,.1);
|
|
|
|
+ content: "";
|
|
|
|
+ display: block;
|
|
|
|
+ cursor: not-allowed;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .upload-file {
|
|
|
|
+ margin: 0 10px 10px 0;
|
|
|
|
+ display: inline-flex;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ // background: #fff;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ border: 1px solid #c0ccda;
|
|
|
|
+ border-radius: 6px;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ position: relative;
|
|
|
|
+ vertical-align: top;
|
|
|
|
+ &:hover {
|
|
|
|
+ .uplaod-action {
|
|
|
|
+ display: flex;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .uplaod-action {
|
|
|
|
+ position: absolute;
|
|
|
|
+ // top: 0;
|
|
|
|
+ // height: 30px;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ background: rgba(0, 0, 0, 0.6);
|
|
|
|
+ display: none;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ i {
|
|
|
|
+ color: #fff;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ margin: 0 5px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ &.is-success {
|
|
|
|
+ .item-status {
|
|
|
|
+ position: absolute;
|
|
|
|
+ right: -15px;
|
|
|
|
+ top: -6px;
|
|
|
|
+ width: 40px;
|
|
|
|
+ height: 24px;
|
|
|
|
+ background: #13ce66;
|
|
|
|
+ text-align: center;
|
|
|
|
+ transform: rotate(45deg);
|
|
|
|
+ box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
|
|
|
|
+ & > i {
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ margin-top: 11px;
|
|
|
|
+ color: #fff;
|
|
|
|
+ transform: rotate(-45deg);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ &.uploading {
|
|
|
|
+ &:before {
|
|
|
|
+ display: block;
|
|
|
|
+ content: "";
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ background: rgba(0, 0, 0, 0.3);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .upload-progress {
|
|
|
|
+ position: absolute;
|
|
|
|
+ .el-progress__text {
|
|
|
|
+ color: #fff;
|
|
|
|
+ font-size: 16px !important;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ img {
|
|
|
|
+ max-width: 100%;
|
|
|
|
+ max-height: 100%;
|
|
|
|
+ vertical-align: middle;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .el-upload--picture-card {
|
|
|
|
+ position: relative;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ .el-icon-plus {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 50%;
|
|
|
|
+ left: 50%;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .upload-input {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ display: block;
|
|
|
|
+ opacity: 0;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+ .el-upload--text {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ display: block;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .drag-img-list {
|
|
|
|
+ display: inline;
|
|
|
|
+
|
|
|
|
+ .ghost {
|
|
|
|
+ position: relative;
|
|
|
|
+ &::after {
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ display: block;
|
|
|
|
+ content: "";
|
|
|
|
+ background: #fbfdff;
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ border: 1px dashed #3bb3c2;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ & > div {
|
|
|
|
+ cursor: move;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.viewer-container {
|
|
|
|
+ z-index: 9999 !important;
|
|
|
|
+}
|
|
|
|
+</style>
|