|
@@ -1,427 +0,0 @@
|
|
|
-// import { ElImage, ElMessage, ElUpload } from 'element-plus'
|
|
|
-import { defineComponent } from 'vue'
|
|
|
-import styles from './index.module.less'
|
|
|
-import iconUpload from '../col-upload/images/icon_upload.png'
|
|
|
-// import Cropper from './cropper'
|
|
|
-import { VueCropper } from 'vue-cropper'
|
|
|
-import umiRequest from 'umi-request'
|
|
|
-import 'vue-cropper/dist/index.css'
|
|
|
-import {
|
|
|
- ElButton,
|
|
|
- ElCol,
|
|
|
- ElDialog,
|
|
|
- ElIcon,
|
|
|
- ElImage,
|
|
|
- ElMessage,
|
|
|
- ElUpload,
|
|
|
- ElRow
|
|
|
-} from 'element-plus'
|
|
|
-import { CirclePlus, Remove } from '@element-plus/icons-vue'
|
|
|
-import iconRate from '../col-upload/images/icon_rate.png'
|
|
|
-import request from '@/helpers/request'
|
|
|
-
|
|
|
-export default defineComponent({
|
|
|
- name: 'col-cropper',
|
|
|
- props: {
|
|
|
- modelValue: {
|
|
|
- type: String,
|
|
|
- default: ''
|
|
|
- },
|
|
|
- options: {
|
|
|
- // 裁切需要参数
|
|
|
- type: Object,
|
|
|
- default: {
|
|
|
- autoCrop: true, //是否默认生成截图框
|
|
|
- enlarge: 1, // 图片放大倍数
|
|
|
- autoCropWidth: 200, //默认生成截图框宽度
|
|
|
- autoCropHeight: 200, //默认生成截图框高度
|
|
|
- fixedBox: true, //是否固定截图框大小 不允许改变
|
|
|
- previewsCircle: true, //预览图是否是原圆形
|
|
|
- title: '上传图片'
|
|
|
- }
|
|
|
- },
|
|
|
- // 显示图片原始图片
|
|
|
- showSize: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
- },
|
|
|
- disabled: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
- },
|
|
|
- bucket: {
|
|
|
- type: String,
|
|
|
- default: 'daya'
|
|
|
- },
|
|
|
- size: {
|
|
|
- type: Number,
|
|
|
- default: 5 // 默认5M
|
|
|
- },
|
|
|
- accept: {
|
|
|
- type: String,
|
|
|
- default: 'images/*'
|
|
|
- },
|
|
|
- tips: {
|
|
|
- type: String,
|
|
|
- default: '请上传图片'
|
|
|
- },
|
|
|
- extraTips: {
|
|
|
- type: String,
|
|
|
- default: '图片最大不能超过5MB'
|
|
|
- },
|
|
|
- cropUploadSuccess: {
|
|
|
- type: Function,
|
|
|
- default: (data: string) => {}
|
|
|
- }
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- isStopRun: false,
|
|
|
- loading: false,
|
|
|
- ossUploadUrl: 'https://ks3-cn-beijing.ksyuncs.com/' + this.bucket,
|
|
|
- dataObj: {
|
|
|
- policy: '',
|
|
|
- signature: '',
|
|
|
- key: '',
|
|
|
- KSSAccessKeyId: '',
|
|
|
- acl: 'public-read',
|
|
|
- name: ''
|
|
|
- },
|
|
|
- visible: false,
|
|
|
- img: null,
|
|
|
- optionsList: {
|
|
|
- img: '', //裁剪图片的地址
|
|
|
- autoCrop: true, //是否默认生成截图框
|
|
|
- autoCropWidth: 180, //默认生成截图框宽度
|
|
|
- autoCropHeight: 180, //默认生成截图框高度
|
|
|
- fixedBox: false, //是否固定截图框大小 不允许改变
|
|
|
- full: false,
|
|
|
- enlarge: 1, // 是否按照截图框比例输出 默认为1
|
|
|
- previewsCircle: true, //预览图是否是原圆形
|
|
|
- centerBox: true,
|
|
|
- outputType: 'png',
|
|
|
- title: '修改头像',
|
|
|
- name: null // 文件名称
|
|
|
- },
|
|
|
- previews: {} as any,
|
|
|
- url: {
|
|
|
- upload: '/sys/common/saveToImgByStr'
|
|
|
- },
|
|
|
- submitLoading: false
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- onDelete() {
|
|
|
- // 删除图片
|
|
|
- this.$emit('update:modelValue', '')
|
|
|
- },
|
|
|
- //从本地选择文件
|
|
|
- async handleChange(info: any) {
|
|
|
- if (this.isStopRun) {
|
|
|
- return
|
|
|
- }
|
|
|
- this.loading = true
|
|
|
- const options = this.options
|
|
|
- this.getBase64(info.file, (imageUrl: any) => {
|
|
|
- const target = Object.assign({}, options, {
|
|
|
- img: imageUrl,
|
|
|
- name: info.file.name // 上传文件名
|
|
|
- })
|
|
|
- // ;(this as any).$refs.CropperModal.edit(target)
|
|
|
- this.edit(target)
|
|
|
- })
|
|
|
- },
|
|
|
- // 上传之前 格式与大小校验
|
|
|
- beforeUpload(file) {
|
|
|
- this.isStopRun = false
|
|
|
- var fileType = file.type
|
|
|
- if (fileType.indexOf('image') < 0) {
|
|
|
- ElMessage.warning('请上传图片')
|
|
|
- this.isStopRun = true
|
|
|
- return false
|
|
|
- }
|
|
|
- // const isJpgOrPng = this.acceptArray.includes(file.type)
|
|
|
- // if (!isJpgOrPng) {
|
|
|
- // ElMessage.error('你上传图片格式不正确!')
|
|
|
- // this.isStopRun = true
|
|
|
- // }
|
|
|
- console.log(this.size)
|
|
|
- const size = this.size || 0
|
|
|
- const isLtSize = file.size < size * 1024 * 1024
|
|
|
- if (!isLtSize) {
|
|
|
- ElMessage.error('图片大小不能超过' + this.size + 'MB!')
|
|
|
- this.isStopRun = true
|
|
|
- }
|
|
|
- return isLtSize
|
|
|
- },
|
|
|
- error() {
|
|
|
- this.remove()
|
|
|
- this.loading = false
|
|
|
- },
|
|
|
- remove() {
|
|
|
- this.onDelete()
|
|
|
- },
|
|
|
- //获取服务器返回的地址
|
|
|
- handleCropperSuccess(data: any) {
|
|
|
- //将返回的数据回显
|
|
|
- this.loading = false
|
|
|
- console.log(data, 'success')
|
|
|
- this.$emit('update:modelValue', data)
|
|
|
- // this.cropUploadSuccess(data)
|
|
|
- // this.$emit('cropUploadSuccess', data)
|
|
|
- // console.log(this.modelValue, 'modelValue')
|
|
|
- },
|
|
|
- // 取消上传
|
|
|
- handleCropperClose() {
|
|
|
- this.loading = false
|
|
|
- this.remove()
|
|
|
- },
|
|
|
- getBase64(img, callback) {
|
|
|
- const reader = new FileReader()
|
|
|
- reader.addEventListener('load', () => callback(reader.result))
|
|
|
- reader.readAsDataURL(img)
|
|
|
- },
|
|
|
- edit(record: any) {
|
|
|
- const { options } = this
|
|
|
- this.visible = true
|
|
|
- this.optionsList = Object.assign({}, options, record)
|
|
|
- console.log(this.options)
|
|
|
- },
|
|
|
- /**
|
|
|
- * 取消截图
|
|
|
- */
|
|
|
- cancelHandel() {
|
|
|
- this.visible = false
|
|
|
- // this.cropperNo()
|
|
|
- this.loading = false
|
|
|
- this.remove()
|
|
|
- },
|
|
|
- /**
|
|
|
- * 确认截图
|
|
|
- */
|
|
|
- okHandel() {
|
|
|
- ;(this as any).$refs.cropperRef.getCropBlob(async data => {
|
|
|
- this.submitLoading = true
|
|
|
- const options: any = this.options
|
|
|
- const fileName =
|
|
|
- (options.name ? options.name.split('.')[0] : +new Date()) + '.png'
|
|
|
- try {
|
|
|
- let key = new Date().getTime() + fileName
|
|
|
- let obj = {
|
|
|
- filename: fileName,
|
|
|
- bucketName: this.bucket,
|
|
|
- postData: {
|
|
|
- filename: fileName,
|
|
|
- acl: 'public-read',
|
|
|
- key: key,
|
|
|
- unknowValueField: []
|
|
|
- }
|
|
|
- }
|
|
|
- const res = await request.post('/api-website/getUploadSign', {
|
|
|
- data: obj
|
|
|
- })
|
|
|
- this.dataObj = {
|
|
|
- policy: res.data.policy,
|
|
|
- signature: res.data.signature,
|
|
|
- key: key,
|
|
|
- KSSAccessKeyId: res.data.kssAccessKeyId,
|
|
|
- acl: 'public-read',
|
|
|
- name: fileName
|
|
|
- }
|
|
|
-
|
|
|
- let formData = new FormData()
|
|
|
- for (let key in this.dataObj) {
|
|
|
- formData.append(key, this.dataObj[key])
|
|
|
- }
|
|
|
- formData.append('file', this.blobToFile(data, fileName), fileName)
|
|
|
- await umiRequest(this.ossUploadUrl, {
|
|
|
- method: 'POST',
|
|
|
- data: formData
|
|
|
- })
|
|
|
- console.log(this.ossUploadUrl + '/' + key)
|
|
|
- const uploadUrl = this.ossUploadUrl + '/' + key
|
|
|
- // this.cropperOk(uploadUrl)
|
|
|
- this.$emit('update:modelValue', uploadUrl)
|
|
|
- } catch (err: any) {
|
|
|
- ElMessage.error(err)
|
|
|
- } finally {
|
|
|
- this.submitLoading = false
|
|
|
- this.cancelHandel()
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- //转成blob
|
|
|
- blobToFile(Blob: any, fileName: any) {
|
|
|
- //兼容IE
|
|
|
- Blob.lastModifiedDate = new Date()
|
|
|
- Blob.name = fileName
|
|
|
- return Blob
|
|
|
- },
|
|
|
- base64ToFile(urlData: any, fileName: any) {
|
|
|
- let arr = urlData.split(',')
|
|
|
- let mime = arr[0].match(/:(.*?);/)[1]
|
|
|
- let bytes = atob(arr[1]) // 解码base64
|
|
|
- let n = bytes.length
|
|
|
- let ia = new Uint8Array(n)
|
|
|
- while (n--) {
|
|
|
- ia[n] = bytes.charCodeAt(n)
|
|
|
- }
|
|
|
- return new File([ia], fileName, { type: mime })
|
|
|
- },
|
|
|
- //移动框的事件
|
|
|
- realTime(data: any) {
|
|
|
- this.previews = data
|
|
|
- },
|
|
|
- //图片缩放
|
|
|
- changeScale(num: number) {
|
|
|
- num = num || 1
|
|
|
- ;(this as any).$refs.cropperRef.changeScale(num)
|
|
|
- },
|
|
|
- //向左旋转
|
|
|
- rotateLeft() {
|
|
|
- ;(this as any).$refs.cropperRef.rotateLeft()
|
|
|
- },
|
|
|
- //向右旋转
|
|
|
- rotateRight() {
|
|
|
- ;(this as any).$refs.cropperRef.rotateRight()
|
|
|
- }
|
|
|
- },
|
|
|
- render() {
|
|
|
- return (
|
|
|
- <div class={[styles.colUpload, 'w-full']}>
|
|
|
- <ElUpload
|
|
|
- disabled={this.disabled}
|
|
|
- showFileList={false}
|
|
|
- accept={this.accept}
|
|
|
- beforeUpload={this.beforeUpload}
|
|
|
- // @ts-ignore
|
|
|
- httpRequest={this.handleChange}
|
|
|
- // limit={1}
|
|
|
- ref="uploadRef"
|
|
|
- >
|
|
|
- <div
|
|
|
- ref="uploadDom"
|
|
|
- class={[styles.uploadClass, 'w-full']}
|
|
|
- style={{ height: '106px' }}
|
|
|
- >
|
|
|
- {this.modelValue ? (
|
|
|
- <ElImage
|
|
|
- src={this.modelValue}
|
|
|
- fit="cover"
|
|
|
- class={styles.uploadSection}
|
|
|
- />
|
|
|
- ) : (
|
|
|
- <div
|
|
|
- class={[
|
|
|
- styles.uploadSection,
|
|
|
- 'flex items-center flex-col justify-center'
|
|
|
- ]}
|
|
|
- >
|
|
|
- <img src={iconUpload} class="w-8 h-7 mb-3" />
|
|
|
- <p>{this.tips}</p>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- </ElUpload>
|
|
|
-
|
|
|
- <p class="text-3 text-[#999999] leading-6 pt-1">{this.extraTips}</p>
|
|
|
-
|
|
|
- <ElDialog
|
|
|
- modelValue={this.visible}
|
|
|
- onUpdate:modelValue={val => (this.visible = val)}
|
|
|
- appendToBody
|
|
|
- title={this.options.title}
|
|
|
- closeOnClickModal={false}
|
|
|
- width={'800px'}
|
|
|
- v-slots={{
|
|
|
- footer: () => (
|
|
|
- <span class="dialog-footer !text-center block">
|
|
|
- <ElButton
|
|
|
- onClick={this.cancelHandel}
|
|
|
- disabled={this.submitLoading}
|
|
|
- >
|
|
|
- 取消
|
|
|
- </ElButton>
|
|
|
- <ElButton
|
|
|
- type="primary"
|
|
|
- onClick={this.okHandel}
|
|
|
- loading={this.submitLoading}
|
|
|
- >
|
|
|
- 保 存
|
|
|
- </ElButton>
|
|
|
- </span>
|
|
|
- )
|
|
|
- }}
|
|
|
- >
|
|
|
- <ElRow>
|
|
|
- <ElCol xs={24} md={12} style={{ width: '350px' }}>
|
|
|
- <VueCropper
|
|
|
- ref="cropperRef"
|
|
|
- img={this.optionsList.img}
|
|
|
- info={true}
|
|
|
- autoCrop={this.optionsList.autoCrop}
|
|
|
- autoCropWidth={this.optionsList.autoCropWidth}
|
|
|
- full={this.optionsList.full}
|
|
|
- outputType={this.optionsList.outputType}
|
|
|
- autoCropHeight={this.optionsList.autoCropHeight}
|
|
|
- fixedBox={this.optionsList.fixedBox}
|
|
|
- enlarge={this.optionsList.enlarge}
|
|
|
- onRealTime={this.realTime}
|
|
|
- style={{ height: '350px' }}
|
|
|
- />
|
|
|
- <div class="flex pt-2">
|
|
|
- <div
|
|
|
- onClick={() => {
|
|
|
- this.changeScale(1)
|
|
|
- }}
|
|
|
- class="mr-2 cursor-pointer"
|
|
|
- title="放大"
|
|
|
- >
|
|
|
- <ElIcon size={30} color="#333">
|
|
|
- <CirclePlus />
|
|
|
- </ElIcon>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- onClick={() => {
|
|
|
- this.changeScale(-1)
|
|
|
- }}
|
|
|
- class="mr-2 cursor-pointer"
|
|
|
- title="缩小"
|
|
|
- >
|
|
|
- <ElIcon size={30} color="#333">
|
|
|
- <Remove />
|
|
|
- </ElIcon>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- onClick={this.rotateRight}
|
|
|
- title="向右旋转"
|
|
|
- class="cursor-pointer"
|
|
|
- >
|
|
|
- <img src={iconRate} class="w-[30px] h-[30px]" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </ElCol>
|
|
|
- <ElCol xs={24} md={12} style={{ height: '350px' }}>
|
|
|
- <div class={styles.previewImg}>
|
|
|
- <span>预览图片</span>
|
|
|
- <div
|
|
|
- class={
|
|
|
- this.optionsList.previewsCircle
|
|
|
- ? styles['avatar-upload-preview']
|
|
|
- : styles['avatar-upload-preview_range']
|
|
|
- }
|
|
|
- style={{
|
|
|
- width: this.optionsList.autoCropWidth + 'px',
|
|
|
- height: this.optionsList.autoCropHeight + 'px'
|
|
|
- }}
|
|
|
- >
|
|
|
- <ElImage src={this.previews.url} style={this.previews.img} />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </ElCol>
|
|
|
- </ElRow>
|
|
|
- </ElDialog>
|
|
|
- </div>
|
|
|
- )
|
|
|
- }
|
|
|
-})
|