|
@@ -1,51 +1,86 @@
|
|
<template>
|
|
<template>
|
|
- <el-dialog :visible.sync="visible" :title="options.title" append-to-body :close-on-click-modal="false" width="800px" @close="cancelHandel">
|
|
|
|
- <el-row>
|
|
|
|
- <el-col :xs="24" :md="12" :style="{ height: '350px', width: '350px' }">
|
|
|
|
- <vue-cropper ref="cropper" :img="options.img" :info="true" :autoCrop="options.autoCrop" :autoCropWidth="options.autoCropWidth" :full="options.full" :outputType="options.outputType" :autoCropHeight="options.autoCropHeight" :fixedBox="options.fixedBox" :enlarge="options.enlarge" @realTime="realTime">
|
|
|
|
- </vue-cropper>
|
|
|
|
|
|
+ <el-dialog
|
|
|
|
+ :visible.sync="visible"
|
|
|
|
+ :title="options.title"
|
|
|
|
+ append-to-body
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
+ width="800px"
|
|
|
|
+ @close="cancelHandel"
|
|
|
|
+ >
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-col :xs="24" :md="12" :style="{ height: '350px', width: '350px' }">
|
|
|
|
+ <!-- :autoCrop="options.autoCrop" -->
|
|
|
|
+ <vue-cropper
|
|
|
|
+ ref="cropper"
|
|
|
|
+ :img="options.img"
|
|
|
|
+ :info="true"
|
|
|
|
+ :autoCrop="true"
|
|
|
|
+ :centerBox="true"
|
|
|
|
+ :autoCropWidth="options.autoCropWidth"
|
|
|
|
+ :full="options.full"
|
|
|
|
+ :outputType="options.outputType"
|
|
|
|
+ :autoCropHeight="options.autoCropHeight"
|
|
|
|
+ :fixedBox="options.fixedBox"
|
|
|
|
+ :enlarge="options.enlarge"
|
|
|
|
+ @realTime="realTime"
|
|
|
|
+ >
|
|
|
|
+ </vue-cropper>
|
|
|
|
|
|
- <div class="operation">
|
|
|
|
- <i class="el-icon-circle-plus-outline" @click="changeScale(1)"></i>
|
|
|
|
- <i class="el-icon-remove-outline" @click="changeScale(-1)"></i>
|
|
|
|
- <i class="icon-rate" @click="rotateRight"></i>
|
|
|
|
- </div>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
|
|
|
- <div class="previewImg">
|
|
|
|
- <span>预览图片</span>
|
|
|
|
- <div :class="options.previewsCircle ? 'avatar-upload-preview' : 'avatar-upload-preview_range'"
|
|
|
|
- :style="{ width: options.autoCropWidth + 'px', height: options.autoCropHeight + 'px', }">
|
|
|
|
- <img :src="previews.url" :style="previews.img" />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </el-col>
|
|
|
|
- </el-row>
|
|
|
|
- <template slot="footer">
|
|
|
|
- <div style="text-align: center">
|
|
|
|
- <el-button size="mini" @click="cancelHandel">取消</el-button>
|
|
|
|
- <el-button size="mini" type="primary" :loading="confirmLoading" @click="okHandel">保存</el-button>
|
|
|
|
- </div>
|
|
|
|
- </template>
|
|
|
|
- </el-dialog>
|
|
|
|
|
|
+ <div class="operation">
|
|
|
|
+ <i class="el-icon-circle-plus-outline" @click="changeScale(1)"></i>
|
|
|
|
+ <i class="el-icon-remove-outline" @click="changeScale(-1)"></i>
|
|
|
|
+ <i class="icon-rate" @click="rotateRight"></i>
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :xs="24" :md="12" :style="{ height: '350px' }">
|
|
|
|
+ <div class="previewImg">
|
|
|
|
+ <span>预览图片</span>
|
|
|
|
+ <div
|
|
|
|
+ :class="
|
|
|
|
+ options.previewsCircle
|
|
|
|
+ ? 'avatar-upload-preview'
|
|
|
|
+ : 'avatar-upload-preview_range'
|
|
|
|
+ "
|
|
|
|
+ :style="{
|
|
|
|
+ width: options.autoCropWidth + 'px',
|
|
|
|
+ height: options.autoCropHeight + 'px',
|
|
|
|
+ }"
|
|
|
|
+ >
|
|
|
|
+ <img :src="previews.url" :style="previews.img" />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <template slot="footer">
|
|
|
|
+ <div style="text-align: center">
|
|
|
|
+ <el-button size="mini" @click="cancelHandel">取消</el-button>
|
|
|
|
+ <el-button
|
|
|
|
+ size="mini"
|
|
|
|
+ type="primary"
|
|
|
|
+ :loading="confirmLoading"
|
|
|
|
+ @click="okHandel"
|
|
|
|
+ >保存</el-button
|
|
|
|
+ >
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </el-dialog>
|
|
</template>
|
|
</template>
|
|
<script>
|
|
<script>
|
|
-import { VueCropper } from 'vue-cropper'
|
|
|
|
-import { uploadFileWithBase64, uploadFile } from '@/api/appTenant'
|
|
|
|
|
|
+import { VueCropper } from "vue-cropper";
|
|
|
|
+import { uploadFileWithBase64, uploadFile } from "@/api/appTenant";
|
|
export default {
|
|
export default {
|
|
- name: 'CropperModal',
|
|
|
|
|
|
+ name: "CropperModal",
|
|
components: {
|
|
components: {
|
|
- VueCropper
|
|
|
|
- },
|
|
|
|
- props: {
|
|
|
|
|
|
+ VueCropper,
|
|
},
|
|
},
|
|
|
|
+ props: {},
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
visible: false,
|
|
visible: false,
|
|
img: null,
|
|
img: null,
|
|
confirmLoading: false,
|
|
confirmLoading: false,
|
|
options: {
|
|
options: {
|
|
- img: '', //裁剪图片的地址
|
|
|
|
|
|
+ img: "", //裁剪图片的地址
|
|
autoCrop: true, //是否默认生成截图框
|
|
autoCrop: true, //是否默认生成截图框
|
|
autoCropWidth: 180, //默认生成截图框宽度
|
|
autoCropWidth: 180, //默认生成截图框宽度
|
|
autoCropHeight: 180, //默认生成截图框高度
|
|
autoCropHeight: 180, //默认生成截图框高度
|
|
@@ -54,101 +89,104 @@ export default {
|
|
enlarge: 1, // 是否按照截图框比例输出 默认为1
|
|
enlarge: 1, // 是否按照截图框比例输出 默认为1
|
|
previewsCircle: true, //预览图是否是原圆形
|
|
previewsCircle: true, //预览图是否是原圆形
|
|
centerBox: true,
|
|
centerBox: true,
|
|
- outputType: 'png',
|
|
|
|
- title: '修改头像',
|
|
|
|
|
|
+ outputType: "png",
|
|
|
|
+ title: "修改头像",
|
|
name: null, // 文件名称
|
|
name: null, // 文件名称
|
|
},
|
|
},
|
|
previews: {},
|
|
previews: {},
|
|
url: {
|
|
url: {
|
|
- upload: '/sys/common/saveToImgByStr'
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ upload: "/sys/common/saveToImgByStr",
|
|
|
|
+ },
|
|
|
|
+ };
|
|
},
|
|
},
|
|
|
|
|
|
methods: {
|
|
methods: {
|
|
edit(record) {
|
|
edit(record) {
|
|
- const { options } = this
|
|
|
|
- this.visible = true
|
|
|
|
- this.options = Object.assign({}, options, record)
|
|
|
|
|
|
+ const { options } = this;
|
|
|
|
+ this.visible = true;
|
|
|
|
+ this.options = Object.assign({}, options, record);
|
|
},
|
|
},
|
|
/**
|
|
/**
|
|
* 取消截图
|
|
* 取消截图
|
|
*/
|
|
*/
|
|
cancelHandel() {
|
|
cancelHandel() {
|
|
- this.confirmLoading = false
|
|
|
|
- this.visible = false
|
|
|
|
- this.$emit('cropper-no')
|
|
|
|
|
|
+ this.confirmLoading = false;
|
|
|
|
+ this.visible = false;
|
|
|
|
+ this.$emit("cropper-no");
|
|
},
|
|
},
|
|
/**
|
|
/**
|
|
* 确认截图
|
|
* 确认截图
|
|
*/
|
|
*/
|
|
okHandel() {
|
|
okHandel() {
|
|
- const that = this
|
|
|
|
- that.confirmLoading = true
|
|
|
|
|
|
+ const that = this;
|
|
|
|
+ that.confirmLoading = true;
|
|
// 获取截图的base64 数据 getCropBlob getCropData
|
|
// 获取截图的base64 数据 getCropBlob getCropData
|
|
this.$refs.cropper.getCropBlob(async (data) => {
|
|
this.$refs.cropper.getCropBlob(async (data) => {
|
|
// const name = (this.options.name ? this.options.name.split('.')[0] : +new Date()) + '.png'
|
|
// const name = (this.options.name ? this.options.name.split('.')[0] : +new Date()) + '.png'
|
|
// let form = new FormData()
|
|
// let form = new FormData()
|
|
// form.append('file', this.blobToFile(data), name)
|
|
// form.append('file', this.blobToFile(data), name)
|
|
- // form.append('base64Str', data)
|
|
|
|
|
|
+ // form.append('base64Str', data)
|
|
// form.append('fileName', name)
|
|
// form.append('fileName', name)
|
|
// form.append('extName', 'png')
|
|
// form.append('extName', 'png')
|
|
try {
|
|
try {
|
|
// const res = await uploadFile(form)
|
|
// const res = await uploadFile(form)
|
|
- // form.append('base64Str', data)
|
|
|
|
- // form.append('fileName', name)
|
|
|
|
- // form.append('extName', 'png')
|
|
|
|
- // try {
|
|
|
|
- // const res = await uploadFileWithBase64(form)
|
|
|
|
- that.$emit('cropper-ok', data)
|
|
|
|
-
|
|
|
|
- } catch(err) {
|
|
|
|
- that.$message.error(err)
|
|
|
|
|
|
+ // form.append('base64Str', data)
|
|
|
|
+ // form.append('fileName', name)
|
|
|
|
+ // form.append('extName', 'png')
|
|
|
|
+ // try {
|
|
|
|
+ // const res = await uploadFileWithBase64(form)
|
|
|
|
+ that.$emit("cropper-ok", data);
|
|
|
|
+ } catch (err) {
|
|
|
|
+ that.$message.error(err);
|
|
} finally {
|
|
} finally {
|
|
- that.cancelHandel()
|
|
|
|
|
|
+ that.cancelHandel();
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ });
|
|
},
|
|
},
|
|
base64ToFile(urlData, fileName) {
|
|
base64ToFile(urlData, fileName) {
|
|
- let arr = urlData.split(',');
|
|
|
|
|
|
+ let arr = urlData.split(",");
|
|
let mime = arr[0].match(/:(.*?);/)[1];
|
|
let mime = arr[0].match(/:(.*?);/)[1];
|
|
let bytes = atob(arr[1]); // 解码base64
|
|
let bytes = atob(arr[1]); // 解码base64
|
|
- let n = bytes.length
|
|
|
|
|
|
+ let n = bytes.length;
|
|
let ia = new Uint8Array(n);
|
|
let ia = new Uint8Array(n);
|
|
while (n--) {
|
|
while (n--) {
|
|
- ia[n] = bytes.charCodeAt(n);
|
|
|
|
|
|
+ ia[n] = bytes.charCodeAt(n);
|
|
}
|
|
}
|
|
return new File([ia], fileName, { type: mime });
|
|
return new File([ia], fileName, { type: mime });
|
|
},
|
|
},
|
|
//转成blob
|
|
//转成blob
|
|
- blobToFile(Blob, fileName) { //兼容IE
|
|
|
|
- Blob.lastModifiedDate = new Date()
|
|
|
|
- Blob.name = fileName
|
|
|
|
- return Blob
|
|
|
|
|
|
+ blobToFile(Blob, fileName) {
|
|
|
|
+ //兼容IE
|
|
|
|
+ Blob.lastModifiedDate = new Date();
|
|
|
|
+ Blob.name = fileName;
|
|
|
|
+ return Blob;
|
|
},
|
|
},
|
|
//移动框的事件
|
|
//移动框的事件
|
|
realTime(data) {
|
|
realTime(data) {
|
|
- this.previews = data
|
|
|
|
|
|
+ this.previews = data;
|
|
},
|
|
},
|
|
//图片缩放
|
|
//图片缩放
|
|
- changeScale (num) {
|
|
|
|
- num = num || 1
|
|
|
|
- this.$refs.cropper.changeScale(num)
|
|
|
|
|
|
+ changeScale(num) {
|
|
|
|
+ num = num || 1;
|
|
|
|
+ this.$refs.cropper.changeScale(num);
|
|
},
|
|
},
|
|
//向左旋转
|
|
//向左旋转
|
|
- rotateLeft () {
|
|
|
|
- this.$refs.cropper.rotateLeft()
|
|
|
|
|
|
+ rotateLeft() {
|
|
|
|
+ this.$refs.cropper.rotateLeft();
|
|
},
|
|
},
|
|
//向右旋转
|
|
//向右旋转
|
|
- rotateRight () {
|
|
|
|
- this.$refs.cropper.rotateRight()
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+ rotateRight() {
|
|
|
|
+ this.$refs.cropper.rotateRight();
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+};
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
-* { touch-action: pan-y; touch-action: none; }
|
|
|
|
|
|
+* {
|
|
|
|
+ touch-action: pan-y;
|
|
|
|
+ touch-action: none;
|
|
|
|
+}
|
|
.avatar-upload-preview_range,
|
|
.avatar-upload-preview_range,
|
|
.avatar-upload-preview {
|
|
.avatar-upload-preview {
|
|
// position: absolute;
|
|
// position: absolute;
|
|
@@ -190,7 +228,7 @@ export default {
|
|
display: inline-block;
|
|
display: inline-block;
|
|
width: 20px;
|
|
width: 20px;
|
|
height: 20px;
|
|
height: 20px;
|
|
- background: url('../../assets/images/base/icon_rate.png') no-repeat center;
|
|
|
|
|
|
+ background: url("../../assets/images/base/icon_rate.png") no-repeat center;
|
|
background-size: contain;
|
|
background-size: contain;
|
|
}
|
|
}
|
|
}
|
|
}
|