13 changed files with 916 additions and 12 deletions
-
1.env.development
-
3.env.production
-
5package.json
-
3public/static/config.js
-
11src/api/stockTask/index.js
-
2src/assets/styles/sidebar.scss
-
3src/main.js
-
15src/utils/upload.js
-
9src/views/visualCheck/checkManage/checkLog/index.vue
-
6src/views/visualCheck/checkManage/dataScreening/girdList.vue
-
515src/views/visualCheck/checkManage/mobileCheck/index.vue
-
271src/views/visualCheck/checkManage/mobileCheck/module/corpper.vue
-
84src/views/visualCheck/checkManage/paramSetting/index.vue
@ -0,0 +1,515 @@ |
|||
<template> |
|||
<div class="app-container row-container"> |
|||
<!-- style="height: calc(100vh - 200px);" --> |
|||
<!-- style="height: calc(100vh);" --> |
|||
<div class="container-wrap" :style="{ height: !isMobile ? 'calc(100vh - 200px)' : '' }"> |
|||
<span class="right-top-line" /> |
|||
<span class="left-bottom-line" /> |
|||
<div class="camera-container"> |
|||
|
|||
<div :class="!isMobile ? 'mobile-step' : 'mobile-step isMobile-step'"> |
|||
<!-- <span>选择目标位置</span> --> |
|||
<el-divider content-position="left"><img src="@/assets/images/collect/one.png"><span>选择目标位置</span></el-divider> |
|||
<div class="step-style"> |
|||
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="90px"> |
|||
<el-form-item class="collection-tree-select" label="所在架位" prop="actualShelfId"> |
|||
<treeselect |
|||
v-model="form.actualShelfId" |
|||
:options="regionTreeData" |
|||
flat |
|||
:multiple="false" |
|||
placeholder="选择架" |
|||
:normalizer="normalizer" |
|||
:default-expand-level="levelNumber" |
|||
style="width: 282px;" |
|||
:disabled="!stepOne" |
|||
:searchable="false" |
|||
@select="node=>treeSelectInput(node)" |
|||
> |
|||
<div slot="value-label" slot-scope="{ node }">{{ getAutoNameUnknown(node.label) }}</div> |
|||
</treeselect> |
|||
</el-form-item> |
|||
<el-form-item class="collection-tree-select" label="所在层位" prop="gridId"> |
|||
<treeselect |
|||
v-model="form.gridId" |
|||
:options="girdData" |
|||
placeholder="选择层位" |
|||
:normalizer="normalizerGird" |
|||
:default-expand-level="levelNumber" |
|||
:disabled="!stepOne" |
|||
style="width: 282px; " |
|||
:searchable="false" |
|||
@select="node=>gridSelectInput(node)" |
|||
> |
|||
<div slot="value-label" slot-scope="{ node }">{{ getAutoNameUnknown(node.label) }}</div> |
|||
</treeselect> |
|||
</el-form-item> |
|||
</el-form> |
|||
<el-button v-if="stepOne" class="check-btn" style="margin-bottom: 18px" :loading="submitLoading" type="primary" @click="submitStepOne">下一步</el-button> |
|||
</div> |
|||
</div> |
|||
<div :class="!isMobile ? 'mobile-step' : 'mobile-step isMobile-step'"> |
|||
<!-- <span>拍照上传</span> --> |
|||
<el-divider content-position="left"><img src="@/assets/images/collect/two2.png"><span>拍照上传</span></el-divider> |
|||
<!-- style="margin: 20px 0;" --> |
|||
<div v-if="!stepOne" class="step-style"> |
|||
<div class="mobile-check-upload"> |
|||
<div class="upload-input"> |
|||
<input |
|||
ref="imgFile" |
|||
accept="image/*" |
|||
capture="camera" |
|||
type="file" |
|||
multiple |
|||
:disabled="stepOne" |
|||
@change="previewFiles" |
|||
> |
|||
<div class="upload-zip"><i class="iconfont icon-shangchuan2" />{{ isMobile ? '拍照上传':'上传文件' }}</div> |
|||
</div> |
|||
<div style="margin-left: 40px;"> |
|||
<div v-for="(imgSrc, index) in imageSources" :key="index" style="display: inline-block; margin: 10px;"> |
|||
<img |
|||
:src="imgSrc" |
|||
style="display: inline-block; max-width: 100px; max-height: 100px;" |
|||
@click="showCoverPreview(imgSrc)" |
|||
> |
|||
<i class="iconfont icon-shanchu1" @click="deleteImage(index)" /> |
|||
</div> |
|||
</div> |
|||
<!-- 裁切上传 --> |
|||
<!-- <el-form ref="formValidate" :model="formValidate" :rules="ruleCropper" label-width="100px" class="mobile-stepForm"> |
|||
<el-form-item label="照片上传" prop="mainImage"> |
|||
<div v-if="formValidate.mainImage !== ''" class="list-img-box"> |
|||
<img :src="formValidate.mainImage" style="max-width:300px; max-height:150px" alt="图书" @click="showCoverPreview(formValidate.mainImage)"> |
|||
</div> |
|||
<div class="upload-zip" @click="uploadPicture('flagImg')"><i class="iconfont icon-shangchuan2" />{{ isMobile ? '拍照上传':'上传文件' }}</div> |
|||
<input v-model="formValidate.mainImage" type="hidden" placeholder="请添加照片"> |
|||
</el-form-item> |
|||
</el-form> --> |
|||
</div> |
|||
<div> |
|||
<el-button type="primary" @click="returnStepOne">上一步</el-button> |
|||
<el-button class="check-btn" :loading="submitLoading" type="primary" @click="saveData">下一步</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div :class="!isMobile ? 'mobile-step' : 'mobile-step isMobile-step'"> |
|||
<!-- <span>开始盘点</span> --> |
|||
<el-divider content-position="left"><img src="@/assets/images/collect/three2.png"><span>开始盘点</span></el-divider> |
|||
<div v-if="stepThree" class="step-style step-three-text"> |
|||
<p v-if="mobileResult"> |
|||
移动盘点已创建成功,单号【{{ mobileResult.stockBill }}】,查看详情请转到: |
|||
<router-link :to="{ path: '/check/check/checkLog'}"> |
|||
盘点日志 |
|||
</router-link> |
|||
</p> |
|||
<p v-else> |
|||
移动盘点创建失败 |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 点击缩略图看大图 --> |
|||
<el-dialog v-if="!isMobile" class="preview-dialog" :append-to-body="true" :close-on-click-modal="false" :before-close="handleClose" :visible="showCoverVisible" title="查看大图"> |
|||
<span class="dialog-right-top" /> |
|||
<span class="dialog-left-bottom" /> |
|||
<div class="setting-dialog" style="max-height:calc(100vh - 230px); overflow:auto;"> |
|||
<img style="max-width:100%; object-fit: contain;" :src="previewSrc"> |
|||
</div> |
|||
</el-dialog> |
|||
<el-dialog v-else class="mobile-dialog" :append-to-body="true" :close-on-click-modal="false" :before-close="handleClose" :visible="showCoverVisible" title="查看大图"> |
|||
<span class="dialog-right-top" /> |
|||
<span class="dialog-left-bottom" /> |
|||
<div class="setting-dialog"> |
|||
<img style="max-width:100%; max-height: 100%; object-fit: contain;" :src="previewSrc"> |
|||
</div> |
|||
</el-dialog> |
|||
|
|||
<!-- 剪裁组件弹窗 --> |
|||
<el-dialog |
|||
title="裁切照片" |
|||
:close-on-click-modal="false" |
|||
:modal-append-to-body="false" |
|||
append-to-body |
|||
:visible.sync="cropperModel" |
|||
width="950px" |
|||
center |
|||
> |
|||
<cropper-image |
|||
ref="child" |
|||
@uploadImgSuccess="handleUploadSuccess" |
|||
/> |
|||
</el-dialog> |
|||
<!--查看大图--> |
|||
<el-dialog |
|||
:close-on-click-modal="false" |
|||
:modal-append-to-body="false" |
|||
append-to-body |
|||
title="查看大图" |
|||
:visible.sync="imgVisible" |
|||
center |
|||
> |
|||
<img v-if="imgVisible" :src="imgName" style="width: 100%" alt="查看"> |
|||
</el-dialog> |
|||
|
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { FetchRegionTree } from '@/api/deviceVI/index' |
|||
import { FetchShelfGridAllByShelfId } from '@/api/shelf/index' |
|||
import { mapGetters } from 'vuex' |
|||
import { removeQUPrefix } from '@/utils/index' |
|||
import { mobileUpload } from '@/utils/upload' |
|||
|
|||
import Treeselect from '@riophae/vue-treeselect' |
|||
import '@riophae/vue-treeselect/dist/vue-treeselect.css' |
|||
|
|||
import CropperImage from './module/corpper.vue' |
|||
|
|||
export default { |
|||
name: 'MobileCheck', |
|||
components: { Treeselect, CropperImage }, |
|||
data() { |
|||
return { |
|||
form: { actualShelfId: null, gridId: null }, |
|||
levelNumber: 4, |
|||
regionTreeData: [], |
|||
selectShelfVal: null, |
|||
selectGridVal: null, |
|||
girdData: [], |
|||
permission: { |
|||
add: ['admin', 'paramSetting:add'], |
|||
edit: ['admin', 'paramSetting:edit'], |
|||
del: ['admin', 'paramSetting:del'] |
|||
}, |
|||
showCoverVisible: false, // 查看大图dialog |
|||
previewSrc: '', // 查看大图src |
|||
imageSources: [], // 存储图片的数据URL |
|||
selectedFiles: [], // 存储选中的图片 File 对象 |
|||
isMobile: false, |
|||
submitLoading: false, |
|||
rules: { |
|||
gridId: [ |
|||
{ required: true, message: '请选择层位', trigger: 'change' } |
|||
], |
|||
actualShelfId: [ |
|||
{ required: true, message: '请选择书架', trigger: 'change' } |
|||
] |
|||
}, |
|||
stepOne: true, |
|||
stepTwo: false, |
|||
stepThree: false, |
|||
// 裁切图片参数 |
|||
formValidate: { |
|||
mainImage: '' |
|||
}, |
|||
ruleCropper: { |
|||
mainImage: [ |
|||
{ required: true, message: '请上传照片', trigger: 'blur' } |
|||
] |
|||
}, |
|||
cropperModel: false, |
|||
imgName: '', |
|||
imgVisible: false |
|||
} |
|||
}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'baseApi' |
|||
]) |
|||
}, |
|||
created() { |
|||
FetchRegionTree().then(res => { |
|||
this.regionTreeData = [this.transformData(res)] |
|||
}).catch(() => { |
|||
}) |
|||
this.checkDevice() |
|||
}, |
|||
beforeDestroy() { |
|||
}, |
|||
mounted() { |
|||
}, |
|||
methods: { |
|||
// 处理vue-treeSelect回显出现unknown问题 |
|||
getAutoNameUnknown(name) { |
|||
if (name.lastIndexOf('unknown') > -1) { |
|||
return name.split('(')[0] |
|||
} else { |
|||
return name |
|||
} |
|||
}, |
|||
normalizer(node) { |
|||
if (node.children && !node.children.length) { |
|||
delete node.children |
|||
} |
|||
return { |
|||
id: node.id, |
|||
label: node.label, |
|||
children: node.children, |
|||
isDisabled: !node.shelfId |
|||
} |
|||
}, |
|||
normalizerGird(node) { |
|||
return { |
|||
id: node.id, |
|||
label: removeQUPrefix(node.gridName) |
|||
} |
|||
}, |
|||
transformData(data) { |
|||
return { |
|||
id: data.fondsId, |
|||
fondsId: data.fondsId, |
|||
label: data.fondsName, |
|||
children: data.floors.map(floor => ({ |
|||
id: floor.id, |
|||
floorId: floor.id, |
|||
label: floor.floorName, |
|||
children: floor.regions.map(region => ({ |
|||
id: region.id, |
|||
regionId: region.id, |
|||
label: region.regionName, |
|||
parentFloorId: floor.id, |
|||
children: region.bookShelf.map(shelfItem => ({ |
|||
id: shelfItem.shelfId, |
|||
shelfId: shelfItem.shelfId, |
|||
label: shelfItem.shelfName, |
|||
regionName: floor.floorName + '-' + region.regionName, |
|||
parentRegionId: region.id |
|||
})) |
|||
})) |
|||
})) |
|||
} |
|||
}, |
|||
treeSelectInput(value) { |
|||
console.log(value) |
|||
// '3F-成人图书借阅区-001排A面' |
|||
this.selectShelfVal = value |
|||
this.form.gridId = null |
|||
this.getShelfGridAllByShelfId() |
|||
}, |
|||
getShelfGridAllByShelfId() { |
|||
const params = { |
|||
'shelfId': this.selectShelfVal.id |
|||
} |
|||
FetchShelfGridAllByShelfId(params).then(res => { |
|||
this.girdData = res |
|||
}).catch(() => { |
|||
}) |
|||
}, |
|||
gridSelectInput(value) { |
|||
console.log(value) |
|||
this.selectGridVal = value |
|||
}, |
|||
checkDevice() { |
|||
const userAgent = navigator.userAgent.toLowerCase() |
|||
const mobileKeywords = ['android', 'iphone', 'ipad', 'ipod'] |
|||
this.isMobile = mobileKeywords.some(keyword => userAgent.includes(keyword)) |
|||
}, |
|||
previewFiles() { |
|||
const files = this.$refs.imgFile.files |
|||
const maxImages = 3 |
|||
const remainingSlots = maxImages - this.imageSources.length |
|||
|
|||
if (remainingSlots === 0) { |
|||
this.$message({ message: '已有 3 张图片,不能再上传', type: 'error', offset: 8 }) |
|||
} |
|||
|
|||
const validFiles = [] |
|||
for (let i = 0; i < files.length; i++) { |
|||
const file = files[i] |
|||
if (file.type === 'image/jpeg') { |
|||
validFiles.push(file) |
|||
} else { |
|||
this.$message({ message: `文件 ${file.name} 不是 JPG 格式,将忽略该文件`, type: 'error', offset: 8 }) |
|||
} |
|||
} |
|||
|
|||
if (validFiles.length > remainingSlots) { |
|||
this.$message({ message: `最多只能再上传 ${remainingSlots} 张图片,将只处理部分选择的图片`, type: 'error', offset: 8 }) |
|||
} |
|||
|
|||
const numFilesToProcess = Math.min(validFiles.length, remainingSlots) |
|||
for (let i = 0; i < numFilesToProcess; i++) { |
|||
const file = validFiles[i] |
|||
const reader = new FileReader() |
|||
reader.onload = (e) => { |
|||
this.imageSources.push(e.target.result) |
|||
} |
|||
reader.readAsDataURL(file) |
|||
this.selectedFiles.push(file) |
|||
} |
|||
}, |
|||
submitStepOne() { |
|||
this.$refs.form.validate((valid) => { |
|||
if (valid) { |
|||
this.stepOne = false |
|||
} else { |
|||
console.log('error submit!!') |
|||
return false |
|||
} |
|||
}) |
|||
}, |
|||
returnStepOne() { |
|||
this.stepOne = true |
|||
this.stepTwo = false |
|||
this.imageSources = [] |
|||
this.selectedFiles = [] |
|||
}, |
|||
saveData() { |
|||
// this.formValidate.mainImage === '' |
|||
if (this.selectedFiles.length === 0) { |
|||
this.$message({ message: '请上传照片', type: 'error', offset: 8 }) |
|||
} else { |
|||
this.submitLoading = true |
|||
|
|||
const params = { |
|||
'gridId': this.form.gridId, |
|||
'stockRegion': this.selectShelfVal.regionName + '-' + removeQUPrefix(this.selectGridVal.gridName) |
|||
} |
|||
mobileUpload(this.baseApi + '/api/stocktask-task/moveBill', this.selectedFiles, params).then(res => { |
|||
console.log(res) |
|||
if (res.data.code === 200) { |
|||
this.mobileResult = res.data.data |
|||
this.stepOne = false |
|||
this.stepTwo = true |
|||
} else { |
|||
this.$message({ message: res.data.message, type: 'error', offset: 8 }) |
|||
this.mobileResult = null |
|||
} |
|||
this.submitLoading = false |
|||
}) |
|||
} |
|||
}, |
|||
deleteImage(index) { |
|||
this.imageSources.splice(index, 1) |
|||
this.selectedFiles.splice(index, 1) |
|||
}, |
|||
handleClose(done) { |
|||
this.showCoverVisible = false |
|||
done() |
|||
}, |
|||
// 查看大图 |
|||
showCoverPreview(imgSrc) { |
|||
this.showCoverVisible = true |
|||
this.previewSrc = imgSrc |
|||
}, |
|||
// 裁切上传照片设置 ----- |
|||
uploadPicture() { |
|||
this.cropperModel = true |
|||
}, |
|||
// 图片上传成功后 |
|||
handleUploadSuccess(data) { |
|||
console.log(data) |
|||
this.formValidate.mainImage = data.url |
|||
this.selectedFiles = data.file |
|||
// switch (data.name) { |
|||
// case 'flagImg': |
|||
// this.formValidate.mainImage = 'http://ydfblog.cn/dfs/' + data.url |
|||
// console.log('最终输出' + data.name) |
|||
// break |
|||
// } |
|||
this.cropperModel = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.camera-container{ |
|||
height: 100%; |
|||
} |
|||
.mobile-step{ |
|||
position: relative; |
|||
height: calc(100% / 3); |
|||
::v-deep .el-divider--horizontal{ |
|||
margin: 0 !important; |
|||
.el-divider__text{ |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
img{ |
|||
display: block; |
|||
margin-top: -10px; |
|||
} |
|||
span{ |
|||
font-size: 16px; |
|||
margin-left: 10px; |
|||
font-weight: bold; |
|||
color: #0c0e1e; |
|||
} |
|||
} |
|||
} |
|||
// padding-left: 20px; |
|||
// &::before{ |
|||
// content: ''; |
|||
// position: absolute; |
|||
// top: 0; |
|||
// left: 0; |
|||
// width: 10px; |
|||
// height: 10px; |
|||
// border-radius: 50%; |
|||
// background-color: #0c0e1e; |
|||
// } |
|||
// &::after{ |
|||
// content: ''; |
|||
// position: absolute; |
|||
// top: 8px; |
|||
// left: 4px; |
|||
// width: 2px; |
|||
// height: calc(100% - 20px); |
|||
// background-color: #0c0e1e; |
|||
// } |
|||
} |
|||
|
|||
.isMobile-step{ |
|||
height: 200px; |
|||
} |
|||
|
|||
.mobile-check-upload{ |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: center; |
|||
.upload-input{ |
|||
margin-top: 0 !important; |
|||
} |
|||
} |
|||
// .bg-button{ |
|||
// color: #fff; |
|||
// background: #1f55eb; |
|||
// } |
|||
.mobile-dialog{ |
|||
::v-deep .el-dialog{ |
|||
width: 100%; |
|||
} |
|||
} |
|||
.upload-input input{ |
|||
width: 105px; |
|||
} |
|||
.step-style{ |
|||
display: flex; justify-content: space-between; align-items: center; height: calc(100%); padding: 0 16px; |
|||
} |
|||
.step-three-text { |
|||
justify-content: flex-start; |
|||
a{ |
|||
font-weight: bold; |
|||
color: #1f55eb; |
|||
} |
|||
} |
|||
|
|||
.vue-treeselect__search { |
|||
display: none; |
|||
} |
|||
|
|||
.mobile-stepForm{ |
|||
::v-deep .el-form-item__content{ |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
align-items: end; |
|||
.upload-zip{ |
|||
margin-left: 40px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,271 @@ |
|||
<template> |
|||
<div class="cropper-content"> |
|||
<div class="cropper-box"> |
|||
<div class="cropper"> |
|||
<vue-cropper |
|||
ref="cropper" |
|||
:img="option.img" |
|||
:output-size="option.outputSize" |
|||
:output-type="option.outputType" |
|||
:info="option.info" |
|||
:can-scale="option.canScale" |
|||
:auto-crop="option.autoCrop" |
|||
:auto-crop-width="option.autoCropWidth" |
|||
:auto-crop-height="option.autoCropHeight" |
|||
:fixed="option.fixed" |
|||
:fixed-number="option.fixedNumber" |
|||
:full="option.full" |
|||
:fixed-box="option.fixedBox" |
|||
:can-move="option.canMove" |
|||
:can-move-box="option.canMoveBox" |
|||
:original="option.original" |
|||
:center-box="option.centerBox" |
|||
:height="option.height" |
|||
:info-true="option.infoTrue" |
|||
:max-img-size="option.maxImgSize" |
|||
:enlarge="option.enlarge" |
|||
:mode="option.mode" |
|||
@realTime="realTime" |
|||
@imgLoad="imgLoad" |
|||
/> |
|||
</div> |
|||
<!--底部操作工具按钮--> |
|||
<div class="footer-btn"> |
|||
<div class="scope-btn"> |
|||
<label class="btn" for="uploads">上传照片</label> |
|||
<input id="uploads" type="file" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" capture="camera" @change="selectImg($event)"> |
|||
<el-button size="mini" type="danger" icon="el-icon-zoom-in" @click="changeScale(1)">放大</el-button> |
|||
<el-button size="mini" type="danger" icon="el-icon-zoom-out" @click="changeScale(-1)">缩小</el-button> |
|||
<!-- <el-button size="mini" type="danger" @click="rotateLeft">↺ 左旋转</el-button> |
|||
<el-button size="mini" type="danger" @click="rotateRight">↻ 右旋转</el-button> --> |
|||
</div> |
|||
<div class="upload-cropper-btn"> |
|||
<el-button size="mini" type="success" @click="uploadImg('blob')">确认裁切 <i class="el-icon-upload" /></el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!--预览效果图--> |
|||
<div class="show-preview"> |
|||
<div :style="previews.div" class="preview"> |
|||
<img :src="previews.url" :style="previews.img"> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { VueCropper } from 'vue-cropper' |
|||
export default { |
|||
name: 'CropperImage', |
|||
components: { |
|||
VueCropper |
|||
}, |
|||
data() { |
|||
return { |
|||
previews: {}, |
|||
option: { |
|||
img: '', // 裁剪图片的地址 |
|||
outputSize: 1, // 裁剪生成图片的质量(可选0.1 - 1) |
|||
outputType: 'jpeg', // 裁剪生成图片的格式(jpeg || png || webp) |
|||
fixedNumber: [1.53, 1], // 截图框的宽高比例 |
|||
infoTrue: false, // true为展示真实输出图片宽高,false展示看到的截图框宽高 |
|||
maxImgSize: 10 * 1024 * 1024, // 最大图片大小 10MB |
|||
enlarge: 1, // 图片根据截图框输出比例倍数 |
|||
full: false, // 输出原图比例截图 props名full |
|||
canMove: true, // 上传图片是否可以移动 |
|||
original: false, // 上传图片按照原始比例渲染 |
|||
height: true, // 是否按照设备的dpr 输出等比例图片 |
|||
canMoveBox: true, // 截图框是否可以拖动 |
|||
autoCrop: true, // 是否默认生成截图框 |
|||
autoCropWidth: 200, // 默认截图框宽度 |
|||
autoCropHeight: 200, // 默认生成截图框高度 |
|||
fixedBox: false, // 固定截图框大小 |
|||
mode: 'cover', // 图片默认渲染方式 |
|||
info: true, // 裁剪框的大小信息 |
|||
canScale: true, // 图片是否允许滚轮缩放 |
|||
fixed: false, // 是否开启截图框宽高固定比例 |
|||
centerBox: false // 截图框是否被限制在图片里面 |
|||
}, |
|||
imageUrl: '' |
|||
} |
|||
}, |
|||
beforeDestroy() { |
|||
if (this.imageUrl) { |
|||
URL.revokeObjectURL(this.imageUrl) |
|||
} |
|||
}, |
|||
methods: { |
|||
// 初始化函数 |
|||
imgLoad(msg) { |
|||
console.log('工具初始化函数=====' + msg) |
|||
}, |
|||
// 图片缩放 |
|||
changeScale(num) { |
|||
num = num || 1 |
|||
this.$refs.cropper.changeScale(num) |
|||
}, |
|||
// 向左旋转 |
|||
rotateLeft() { |
|||
this.$refs.cropper.rotateLeft() |
|||
}, |
|||
// 向右旋转 |
|||
rotateRight() { |
|||
this.$refs.cropper.rotateRight() |
|||
}, |
|||
// 实时预览函数 |
|||
realTime(data) { |
|||
this.previews = data |
|||
}, |
|||
// 选择图片 |
|||
selectImg(e) { |
|||
const file = e.target.files[0] |
|||
if (!/\.(jpg|jpeg|JPG)$/.test(e.target.value)) { |
|||
this.$message({ |
|||
message: '图片类型要求:jpeg、jpg', |
|||
type: 'error' |
|||
}) |
|||
return false |
|||
} |
|||
// 转化为blob |
|||
const reader = new FileReader() |
|||
reader.onload = (e) => { |
|||
let data |
|||
if (typeof e.target.result === 'object') { |
|||
data = window.URL.createObjectURL(new Blob([e.target.result])) |
|||
} else { |
|||
data = e.target.result |
|||
} |
|||
this.option.img = data |
|||
} |
|||
// 转化为base64 |
|||
reader.readAsDataURL(file) |
|||
this.selectedFiles = file |
|||
}, |
|||
// 上传图片 |
|||
uploadImg(type) { |
|||
const _this = this |
|||
if (type === 'blob') { |
|||
// 获取截图的blob数据 |
|||
this.$refs.cropper.getCropBlob(async(data) => { |
|||
console.log('data', data) |
|||
// 将 Blob 转换为 File 类型 |
|||
const file = new File([data], 'DX.jpg', { type: data.type }) |
|||
// 为 File 创建一个临时的 URL |
|||
this.imageUrl = URL.createObjectURL(file) |
|||
// const formData = new FormData() |
|||
// formData.append('file', file, 'DX.jpg') |
|||
console.log('file', file) |
|||
const imgInfo = { |
|||
url: this.imageUrl, |
|||
file: file |
|||
} |
|||
console.log('imgInfo', imgInfo) |
|||
_this.$emit('uploadImgSuccess', imgInfo) |
|||
// 调用axios上传 |
|||
// const { data: res } = await _this.$http.post('/api/file/imgUpload', formData) |
|||
// if (res.code === 200) { |
|||
// _this.$message({ |
|||
// message: res.msg, |
|||
// type: 'success' |
|||
// }) |
|||
// const data = res.data.replace('[', '').replace(']', '').split(',') |
|||
// const imgInfo = { |
|||
// name: _this.cropperName, |
|||
// url: data[0] |
|||
// } |
|||
// console.log('imgInfo', imgInfo) |
|||
// _this.$emit('uploadImgSuccess', imgInfo) |
|||
// } else { |
|||
// _this.$message({ |
|||
// message: '文件服务异常,请联系管理员!', |
|||
// type: 'error' |
|||
// }) |
|||
// } |
|||
}) |
|||
} |
|||
}, |
|||
// 将base64的图片转换为file文件 |
|||
convertBase64UrlToBlob(urlData) { |
|||
const bytes = window.atob(urlData.split(',')[1])// 去掉url的头,并转换为byte |
|||
// 处理异常,将ascii码小于0的转换为大于0 |
|||
const ab = new ArrayBuffer(bytes.length) |
|||
const ia = new Uint8Array(ab) |
|||
for (var i = 0; i < bytes.length; i++) { |
|||
ia[i] = bytes.charCodeAt(i) |
|||
} |
|||
return new Blob([ab], { type: 'image/jpeg' }) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.cropper-content{ |
|||
display: flex; |
|||
display: -webkit-flex; |
|||
justify-content: flex-end; |
|||
.cropper-box{ |
|||
flex: 1; |
|||
width: 100%; |
|||
.cropper{ |
|||
width: auto; |
|||
height: 300px; |
|||
} |
|||
} |
|||
|
|||
.show-preview{ |
|||
flex: 1; |
|||
-webkit-flex: 1; |
|||
display: flex; |
|||
display: -webkit-flex; |
|||
justify-content: center; |
|||
.preview{ |
|||
overflow: hidden; |
|||
border:1px solid #67c23a; |
|||
background: #cccccc; |
|||
} |
|||
} |
|||
} |
|||
.footer-btn{ |
|||
margin-top: 30px; |
|||
display: flex; |
|||
display: -webkit-flex; |
|||
justify-content: space-between; |
|||
.scope-btn{ |
|||
display: flex; |
|||
display: -webkit-flex; |
|||
justify-content: space-between; |
|||
padding-right: 10px; |
|||
} |
|||
.upload-cropper-btn{ |
|||
flex: 1; |
|||
-webkit-flex: 1; |
|||
display: flex; |
|||
display: -webkit-flex; |
|||
justify-content: flex-end; |
|||
} |
|||
.btn { |
|||
outline: none; |
|||
display: inline-block; |
|||
line-height: 1; |
|||
white-space: nowrap; |
|||
cursor: pointer; |
|||
-webkit-appearance: none; |
|||
text-align: center; |
|||
-webkit-box-sizing: border-box; |
|||
box-sizing: border-box; |
|||
outline: 0; |
|||
-webkit-transition: .1s; |
|||
transition: .1s; |
|||
font-weight: 500; |
|||
padding: 8px 15px; |
|||
font-size: 12px; |
|||
border-radius: 3px; |
|||
color: #fff; |
|||
background-color: #409EFF; |
|||
border-color: #409EFF; |
|||
margin-right: 10px; |
|||
} |
|||
} |
|||
</style> |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue