wms-antdvue/.svn/pristine/b6/b60d82a8015f52bd4197ee94ffbe99f52db5d8f8.svn-base
2024-11-07 16:33:03 +08:00

167 lines
4.0 KiB
Plaintext

<template>
<div class="img-cropper" :class="{ 'img-cropper-auto': $slots.default }">
<slot name="default"></slot>
<template v-if="!$slots.default">
<template v-if="src">
<div class="img-cropper-img" @click="openCropper">
<div class="img-boxs">
<img :src="src" :class="{ circled: circled }" />
</div>
<div class="mask" :class="{ circled: circled }" @click.stop>
<div class="handle-icon" @click="openCropper">
<span class="icon"><FormOutlined /></span>
</div>
<div class="handle-icon" @click="viewImg">
<span class="icon"><ZoomInOutlined /></span>
</div>
<div class="handle-icon" @click="deleteImg">
<span class="icon"><DeleteOutlined /></span>
</div>
</div>
</div>
</template>
<template v-else>
<div class="img-cropper-img" @click="openCropper">
<div class="addImg">
<span class="icon"><PlusOutlined /></span>
</div>
</div>
</template>
</template>
<CropperModal
ref="cropperRef"
:title="title"
subBtuText="确认上传"
:uploadApi="uploadApi"
:circled="circled"
@upload-success="handleSuccess"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import CropperModal from './CropperModal.vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import {
PlusOutlined,
ZoomInOutlined,
DeleteOutlined,
FormOutlined,
} from '@ant-design/icons-vue';
import { cssUnit } from '@/utils';
const cropperRef = ref();
const props = defineProps({
title: { type: String, default: '图片上传' },
src: { type: String, required: true },
circled: { type: Boolean, default: false },
width: { type: [String, Number], default: 120 },
uploadApi: {
type: Function as PropType<(params) => Promise<any>>,
},
});
const getWidth = cssUnit(props.width);
const iconSize = cssUnit(Math.ceil(parseInt(getWidth) / 4));
// const emit = defineEmits(['change']);
const emit = defineEmits(['uploadSuccess']);
const viewImg = () => {
window.open(props.src);
};
const deleteImg = () => {
emit('uploadSuccess', { fileUrl: '' });
};
function handleSuccess(value) {
emit('uploadSuccess', value);
}
function openCropper() {
cropperRef.value.openModal();
}
defineExpose({
openCropper,
});
</script>
<style lang="less" scoped>
.img-cropper {
width: v-bind(getWidth);
height: v-bind(getWidth);
overflow: hidden;
text-align: center;
position: relative;
&-img {
position: relative;
width: 100%;
height: 100%;
border-radius: 50%;
.img-boxs {
border: 1px dashed #999999;
padding: 5px;
}
.addImg {
width: v-bind(getWidth);
height: v-bind(getWidth);
border: 1px dashed #999999;
display: flex;
justify-content: center;
align-items: center;
.icon {
color: #999999;
font-size: v-bind(iconSize);
}
}
.mask {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 10;
left: 0;
top: 0;
opacity: 0;
transition: opacity 0.4s;
.handle-icon {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 6%;
color: aliceblue;
.icon {
color: #fff;
font-size: 20px;
}
}
}
&:hover {
cursor: pointer;
.mask {
opacity: 1;
}
}
}
}
.img-cropper-auto {
width: auto;
height: auto;
display: inline-block;
}
.circled {
border-radius: 50%;
}
</style>