Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pet-finance-web
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
刘怀志
pet-finance-web
Commits
b8f538a9
Commit
b8f538a9
authored
Aug 09, 2023
by
刘怀志
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
上传图片功能修改
parent
20b37ad5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
243 additions
and
27 deletions
+243
-27
config.js
src/api/system/config.js
+8
-0
index.vue
src/components/ImageUpload/index.vue
+158
-27
index.vue
src/components/imageCropper/index.vue
+77
-0
No files found.
src/api/system/config.js
View file @
b8f538a9
...
@@ -58,3 +58,11 @@ export function refreshCache() {
...
@@ -58,3 +58,11 @@ export function refreshCache() {
method
:
'delete'
method
:
'delete'
})
})
}
}
export
function
uploadCommon
(
data
)
{
return
request
({
headers
:
{
'Content-Type'
:
'multipart/form-data'
},
url
:
'/common/upload'
,
method
:
'post'
,
data
})
}
src/components/ImageUpload/index.vue
View file @
b8f538a9
<
template
>
<
template
>
<div
class=
"component-upload-image"
>
<div
class=
"component-upload-image"
>
<ImageCropperModal
:visible=
"cropperVisible"
:url=
"file"
:auto-crop-width=
"autoCropWidth"
:auto-crop-height=
"autoCropHeight"
@
cancel=
"cropperVisible = false"
@
confirm=
"onConfirm"
/>
<el-upload
<el-upload
ref=
"imageUpload"
ref=
"imageUpload"
:action=
"uploadImgUrl"
multiple
action
list-type=
"picture-card"
list-type=
"picture-card"
:on-success=
"handleUploadSuccess"
:on-success=
"handleUploadSuccess"
:before-upload=
"handleBeforeUpload"
:before-upload=
"handleBeforeUpload"
:limit=
"
1
"
:limit=
"
limit
"
:on-error=
"handleUploadError"
:on-error=
"handleUploadError"
:on-exceed=
"handleExceed"
:on-exceed=
"handleExceed"
:on-remove=
"handleDelete"
:on-remove=
"handleDelete"
:show-file-list=
"true"
:show-file-list=
"true"
:headers=
"headers"
:headers=
"headers"
:file-list=
"fileList"
:file-list=
"fileList"
:auto-upload=
"false"
:on-change=
"changeUpload"
:on-preview=
"handlePictureCardPreview"
:on-preview=
"handlePictureCardPreview"
:class=
"
{hide: fileList.length >= limit
:class=
"
{hide: fileList.length >= limit
|| $refs.imageUpload
&&
$refs.imageUpload.uploadFiles.length >= limit
|| $refs.imageUpload
&&
$refs.imageUpload.uploadFiles.length >= limit
|| number >= limit}"
|| number >= limit}"
>
>
<i
class=
"el-icon-plus"
/>
<i
slot=
"default"
class=
"el-icon-plus"
/>
<div
slot=
"file"
slot-scope=
"
{file}" class="customer-upload-area">
<el-image
:ref=
"file.url"
class=
"el-upload-list__item-thumbnail customer-upload-error"
:src=
"file.url"
:preview-src-list=
"[file.url]"
>
<div
slot=
"error"
class=
"image-slot"
>
<i
class=
"el-icon-picture-outline"
/>
<div>
加载失败
</div>
</div>
</el-image>
<label
class=
"el-upload-list__item-status-label"
>
<i
class=
"el-icon-upload-success el-icon-check"
/>
</label>
<span
class=
"el-upload-list__item-actions"
>
<span
class=
"el-upload-list__item-preview"
@
click=
"handlePictureCardPreview(file)"
>
<i
class=
"el-icon-zoom-in"
/>
</span>
<span
class=
"el-upload-list__item-delete"
@
click=
"handleDelete(file)"
>
<i
class=
"el-icon-delete"
/>
</span>
</span>
</div>
</el-upload>
</el-upload>
<!-- 上传提示 -->
<!-- 上传提示 -->
...
@@ -45,9 +81,15 @@
...
@@ -45,9 +81,15 @@
</template>
</template>
<
script
>
<
script
>
import
ImageCropperModal
from
'@/components/imageCropper/index'
import
{
getToken
}
from
'@/utils/auth'
import
{
getToken
}
from
'@/utils/auth'
import
{
uploadCommon
}
from
'@/api/system/config'
export
default
{
export
default
{
components
:
{
ImageCropperModal
},
props
:
{
props
:
{
value
:
[
String
,
Object
,
Array
],
value
:
[
String
,
Object
,
Array
],
// 图片数量限制
// 图片数量限制
...
@@ -58,7 +100,7 @@ export default {
...
@@ -58,7 +100,7 @@ export default {
// 大小限制(MB)
// 大小限制(MB)
fileSize
:
{
fileSize
:
{
type
:
Number
,
type
:
Number
,
default
:
4
default
:
5
},
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType
:
{
fileType
:
{
...
@@ -73,6 +115,14 @@ export default {
...
@@ -73,6 +115,14 @@ export default {
},
},
data
()
{
data
()
{
return
{
return
{
queryParams
:
{
companyImgUrl
:
''
},
autoCropWidth
:
'400'
,
// 要裁剪的宽
autoCropHeight
:
'400'
,
// 要裁剪的高
file
:
''
,
fileName
:
''
,
// 存放文件名
cropperVisible
:
false
,
// 控制弹窗打开关闭
number
:
0
,
number
:
0
,
uploadList
:
[],
uploadList
:
[],
dialogImageUrl
:
''
,
dialogImageUrl
:
''
,
...
@@ -96,15 +146,16 @@ export default {
...
@@ -96,15 +146,16 @@ export default {
value
:
{
value
:
{
handler
(
val
)
{
handler
(
val
)
{
if
(
val
)
{
if
(
val
)
{
console
.
log
(
'kkkkkkkkkkkkkkkkkk'
,
this
.
baseUrl
)
// 首先将值转为数组
// 首先将值转为数组
const
list
=
Array
.
isArray
(
val
)
?
val
:
this
.
value
.
split
(
','
)
const
list
=
Array
.
isArray
(
val
)
?
val
:
this
.
value
.
split
(
','
)
// 然后将数组转为对象数组
// 然后将数组转为对象数组
this
.
fileList
=
list
.
map
(
item
=>
{
this
.
fileList
=
list
.
map
(
item
=>
{
if
(
typeof
item
===
'string'
)
{
if
(
typeof
item
===
'string'
)
{
if
(
item
.
indexOf
(
this
.
baseUrl
)
===
-
1
)
{
if
(
item
.
indexOf
(
this
.
baseUrl
)
===
-
1
)
{
item
=
{
name
:
this
.
baseUrl
+
item
,
url
:
encodeURI
(
this
.
baseUrl
+
item
)
}
item
=
{
name
:
this
.
baseUrl
+
item
,
url
:
this
.
baseUrl
+
item
}
}
else
{
}
else
{
item
=
{
name
:
item
,
url
:
encodeURI
(
item
)
}
item
=
{
name
:
item
,
url
:
item
}
}
}
}
}
return
item
return
item
...
@@ -119,8 +170,73 @@ export default {
...
@@ -119,8 +170,73 @@ export default {
}
}
},
},
methods
:
{
methods
:
{
// 文件状态改变时
changeUpload
(
file
)
{
var
img
=
file
.
name
.
substring
(
file
.
name
.
lastIndexOf
(
'.'
)
+
1
)
const
suffix
=
img
===
'jpg'
||
img
===
'png'
||
img
===
'jpeg'
if
(
!
suffix
)
{
this
.
$message
.
error
(
'只能上传图片!'
)
return
false
}
// URL.createObjectURL的参数只能是blob或者file类型
// 第一种方法用FileReader,URL.createObjectURL接收blob类型
const
reader
=
new
FileReader
()
reader
.
onload
=
()
=>
{
// 把Array Buffer转化为blob 如果是base64不需要
this
.
file
=
typeof
reader
.
result
===
'object'
?
window
.
URL
.
createObjectURL
(
new
Blob
([
reader
.
result
]))
:
reader
.
result
}
// 转化为base64
this
.
cropperVisible
=
true
reader
.
readAsArrayBuffer
(
file
.
raw
)
// 第二种方法,URL.createObjectURL接收file类型
// this.$nextTick(() => {
// this.file = URL.createObjectURL(file.raw)
// this.cropperVisible = true
// })
this
.
fileName
=
file
.
name
},
// 点击剪裁弹框的确定按钮
async
onConfirm
(
blob
)
{
// 这里的new FormData()指,以文件的方式传给后端(FormData的数据)
const
form
=
new
FormData
()
// new File()的第一个参数是一个字符串数组,数组中的每一个元素对应着文件中一行的内容
// 第二个参数就是文件名字符串
// 第三个参数可以设定一些文件的属性,比如文件的MIME,最后更新时间等
const
file
=
new
File
([
blob
],
this
.
fileName
,
{
type
:
blob
.
type
,
lastModified
:
Date
.
now
()
})
file
.
uid
=
Date
.
now
()
form
.
append
(
'file'
,
file
)
// 如果想在这里打印查看form的值,会发现它是空对象
// 解决办法,需要用form.get('键')的方法获取值
// console.log(form.get('file'))
// 这里调用接口,获取后端返给的图片地址
this
.
number
++
uploadCommon
(
form
).
then
(
res
=>
{
this
.
cropperVisible
=
false
if
(
res
.
code
===
200
)
{
this
.
uploadList
.
push
({
name
:
res
.
fileName
,
url
:
res
.
fileName
})
this
.
uploadedSuccessfully
()
}
else
{
this
.
number
--
// this.$modal.closeLoading()
this
.
$modal
.
msgError
(
res
.
msg
)
this
.
$refs
.
imageUpload
.
handleRemove
(
file
)
this
.
uploadedSuccessfully
()
}
}).
catch
(
err
=>
{
this
.
handleUploadError
(
err
)
})
},
// 上传前loading加载
// 上传前loading加载
handleBeforeUpload
(
file
)
{
handleBeforeUpload
(
file
)
{
console
.
log
(
'图片file---,'
,
file
.
name
)
const
nameTest
=
/^
[^
%;
]
*$/
if
(
!
nameTest
.
test
(
file
.
name
))
{
this
.
$modal
.
msgError
(
'不能含有%;等特殊字符'
)
return
false
}
let
isImg
=
false
let
isImg
=
false
if
(
this
.
fileType
.
length
)
{
if
(
this
.
fileType
.
length
)
{
let
fileExtension
=
''
let
fileExtension
=
''
...
@@ -137,13 +253,13 @@ export default {
...
@@ -137,13 +253,13 @@ export default {
}
}
if
(
!
isImg
)
{
if
(
!
isImg
)
{
this
.
$modal
.
msgError
(
`文件格式不正确, 请上传
${
this
.
fileType
.
join
(
'/'
)}
图片格式文件`
)
this
.
$modal
.
msgError
(
`文件格式不正确, 请上传
${
this
.
fileType
.
join
(
'/'
)}
图片格式文件
!
`
)
return
false
return
false
}
}
if
(
this
.
fileSize
)
{
if
(
this
.
fileSize
)
{
const
isLt
=
file
.
size
/
1024
/
1024
<
this
.
fileSize
const
isLt
=
file
.
size
/
1024
/
1024
<
this
.
fileSize
if
(
!
isLt
)
{
if
(
!
isLt
)
{
this
.
$modal
.
msgError
(
`上传图片大小不能超过
${
this
.
fileSize
}
MB`
)
this
.
$modal
.
msgError
(
`上传图片大小不能超过
${
this
.
fileSize
}
MB
!
`
)
return
false
return
false
}
}
}
}
...
@@ -152,7 +268,7 @@ export default {
...
@@ -152,7 +268,7 @@ export default {
},
},
// 文件个数超出
// 文件个数超出
handleExceed
()
{
handleExceed
()
{
this
.
$modal
.
msgError
(
`上传文件数量不能超过
${
this
.
limit
}
个`
)
this
.
$modal
.
msgError
(
`上传文件数量不能超过
${
this
.
limit
}
个
!
`
)
},
},
// 上传成功回调
// 上传成功回调
handleUploadSuccess
(
res
,
file
)
{
handleUploadSuccess
(
res
,
file
)
{
...
@@ -161,7 +277,7 @@ export default {
...
@@ -161,7 +277,7 @@ export default {
this
.
uploadedSuccessfully
()
this
.
uploadedSuccessfully
()
}
else
{
}
else
{
this
.
number
--
this
.
number
--
this
.
$modal
.
closeLoading
()
//
this.$modal.closeLoading()
this
.
$modal
.
msgError
(
res
.
msg
)
this
.
$modal
.
msgError
(
res
.
msg
)
this
.
$refs
.
imageUpload
.
handleRemove
(
file
)
this
.
$refs
.
imageUpload
.
handleRemove
(
file
)
this
.
uploadedSuccessfully
()
this
.
uploadedSuccessfully
()
...
@@ -178,22 +294,22 @@ export default {
...
@@ -178,22 +294,22 @@ export default {
// 上传失败
// 上传失败
handleUploadError
()
{
handleUploadError
()
{
this
.
$modal
.
msgError
(
'上传图片失败,请重试'
)
this
.
$modal
.
msgError
(
'上传图片失败,请重试'
)
this
.
$modal
.
closeLoading
()
//
this.$modal.closeLoading()
},
},
// 上传结束处理
// 上传结束处理
uploadedSuccessfully
()
{
uploadedSuccessfully
()
{
console
.
log
(
'uploadedSuccessfully'
,
this
.
number
,
this
.
uploadList
.
length
)
if
(
this
.
number
>
0
&&
this
.
uploadList
.
length
===
this
.
number
)
{
if
(
this
.
number
>
0
&&
this
.
uploadList
.
length
===
this
.
number
)
{
this
.
fileList
=
this
.
fileList
.
concat
(
this
.
uploadList
)
this
.
fileList
=
this
.
fileList
.
concat
(
this
.
uploadList
)
this
.
uploadList
=
[]
this
.
uploadList
=
[]
this
.
number
=
0
this
.
number
=
0
this
.
$emit
(
'input'
,
this
.
listToString
(
this
.
fileList
))
this
.
$emit
(
'input'
,
this
.
listToString
(
this
.
fileList
))
this
.
$modal
.
closeLoading
()
//
this.$modal.closeLoading()
}
}
},
},
// 预览
// 预览
handlePictureCardPreview
(
file
)
{
handlePictureCardPreview
(
file
)
{
this
.
dialogImageUrl
=
file
.
url
this
.
$refs
[
file
.
url
].
clickHandler
()
this
.
dialogVisible
=
true
},
},
// 对象转成指定字符串分隔
// 对象转成指定字符串分隔
listToString
(
list
,
separator
)
{
listToString
(
list
,
separator
)
{
...
@@ -210,29 +326,44 @@ export default {
...
@@ -210,29 +326,44 @@ export default {
}
}
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
scoped
lang=
"scss"
>
.customer-upload-area
{
width
:
100%
;
height
:
100%
;
.customer-upload-error
{
width
:
100%
;
height
:
100%
;
color
:
#DB4747
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
align-content
:
center
;
text-align
:
center
;
font-size
:
12px
;
.el-icon-picture-outline
{
font-size
:
18px
;
}
}
}
// .el-upload--picture-card 控制加号部分
// .el-upload--picture-card 控制加号部分
::v-deep
.hide
.el-upload--picture-card
{
::v-deep
.hide
.el-upload--picture-card
{
display
:
none
;
display
:
none
;
}
::v-deep
.el-upload-list--picture-card
{
line-height
:
0
;
}
::v-deep
.el-upload-list__item
{
margin
:
0
0
.5rem
0
0
!
important
;
}
}
// 去掉动画效果
// 去掉动画效果
::v-deep
.el-list-enter-active
,
::v-deep
.el-list-enter-active
,
::v-deep
.el-list-leave-active
{
::v-deep
.el-list-leave-active
{
transition
:
all
0s
;
transition
:
all
0s
;
}
}
::v-deep
.el-list-enter
,
.el-list-leave-active
{
::v-deep
.el-list-enter
,
.el-list-leave-active
{
opacity
:
0
;
opacity
:
0
;
transform
:
translateY
(
0
);
transform
:
translateY
(
0
);
}
}
::v-deep
.el-upload
:focus
{
::v-deep
.el-upload-list--picture-card
{
border-color
:
#5FB54B
!
important
;
line-height
:
0
;
color
:
#5FB54B
!
important
;
}
::v-deep
.el-upload-list__item
{
margin
:
0
0
.5rem
0
0
!
important
;
}
}
</
style
>
</
style
>
src/components/imageCropper/index.vue
0 → 100644
View file @
b8f538a9
<
template
>
<div
class=
"image-cropper-modal"
>
<el-dialog
:visible=
"visible"
:append-to-body=
"true"
:close-on-click-modal=
"false"
title=
"裁剪图片"
width=
"700px"
class=
"image-cropper-dialog"
@
close=
"visible = false"
>
<vue-cropper
ref=
"imageCropper"
:img=
"url"
:auto-crop-width=
"autoCropWidth"
:auto-crop-height=
"autoCropHeight"
:auto-crop=
"true"
:fixed=
"false"
:fixed-number=
"[1, 1]"
:fixed-box=
"true"
:output-size=
"1"
output-type=
"png"
/>
<template
#
footer
>
<span
class=
"dialog-footer"
>
<el-button
class=
"common-btn cancel"
@
click=
"onCancel"
>
取 消
</el-button>
<el-button
class=
"common-btn confirm"
type=
"primary"
@
click=
"onConfirm"
>
确 定
</el-button>
</span>
</
template
>
</el-dialog>
</div>
</template>
<
script
>
import
{
VueCropper
}
from
'vue-cropper'
export
default
{
name
:
'ImageCropperModal'
,
components
:
{
VueCropper
},
props
:
{
visible
:
{
type
:
Boolean
,
default
:
false
},
url
:
{
type
:
String
,
default
:
''
},
autoCropWidth
:
{
type
:
String
,
default
:
`
${
100
*
4
}
`
},
autoCropHeight
:
{
type
:
String
,
default
:
`
${
100
*
4
}
`
}
},
methods
:
{
onCancel
()
{
this
.
$emit
(
'cancel'
)
},
onConfirm
()
{
this
.
$refs
.
imageCropper
.
getCropBlob
((
blob
)
=>
{
this
.
$emit
(
'confirm'
,
blob
)
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.image-cropper-dialog
{
.vue-cropper
{
height
:
500px
;
}
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment