Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cy-admin-ui
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
webpack
cy-admin-ui
Commits
0f9fe073
Commit
0f9fe073
authored
Feb 16, 2022
by
廖伟胜
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改上传文件组件结构
parent
1b956aa6
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1041 additions
and
684 deletions
+1041
-684
index.js
packages/form/upload/index.js
+1
-1
upload-audio.vue
packages/form/upload/src/upload-audio.vue
+70
-86
upload-file.vue
packages/form/upload/src/upload-file.vue
+307
-125
upload-img-list.vue
packages/form/upload/src/upload-img-list.vue
+8
-26
upload-img.vue
packages/form/upload/src/upload-img.vue
+206
-146
upload-video.vue
packages/form/upload/src/upload-video.vue
+367
-112
upload.vue
packages/form/upload/src/upload.vue
+77
-182
layout-form.vue
packages/layout/src/layout-form.vue
+5
-6
No files found.
packages/form/upload/index.js
View file @
0f9fe073
import
Upload
from
'./src/upload
-img-list
'
;
import
Upload
from
'./src/upload'
;
/* istanbul ignore next */
/* istanbul ignore next */
Upload
.
install
=
function
(
Vue
)
{
Upload
.
install
=
function
(
Vue
)
{
...
...
packages/form/upload/src/
base-upload
.vue
→
packages/form/upload/src/
upload-audio
.vue
View file @
0f9fe073
<
template
>
<
template
>
<div>
<div>
<el-upload
ref=
"upload"
:show-file-list=
"false"
:on-preview=
"handler().handlePreview()"
:on-progress=
"(event, file, fileList)=>handler().uploadVideoProcess(event, file, fileList)"
:file-list=
"data"
:list-type=
"listType"
:on-exceed=
"(files, fileList)=>handler().handleExceed(files,fileList)"
:drag=
"uploadStyle === 'drag' ? true : false"
:limit=
"limit"
:on-success=
"(file) => handler().imageSuccess(file)"
:action=
"uploadDomain"
:before-upload=
"init().beforeUpload"
:multiple=
"multiple"
:headers=
"headers"
class=
"avatar-uploader"
>
<el-upload
ref=
"upload"
:show-file-list=
"false"
:on-preview=
"handler().handlePreview()"
:file-list=
"data"
:list-type=
"listType"
:on-exceed=
"(files, fileList)=>handler().handleExceed(files,fileList)"
:drag=
"uploadStyle === 'drag' ? true : false"
:limit=
"limit"
:on-success=
"(file) => handler().imageSuccess(file)"
:action=
"uploadDomain"
:before-upload=
"init().beforeUpload"
:multiple=
"multiple"
:headers=
"headers"
class=
"avatar-uploader"
>
<div
v-if=
"uploadType === 'image'"
style=
"display:inline"
>
<!--音频-->
<div
v-for=
"(item, index) in data"
:key=
"index"
style=
"float:left;"
@
click=
"handler().getIndex(index)"
>
<div
v-if=
"data.length >0"
style=
"display:inline"
>
<div
:style=
"style"
class=
"avatar"
>
<div
v-for=
"(item,index) in data"
:key=
"index"
style=
"float:left;"
@
click
.
stop=
"handler().getIndex(index)"
>
<i
v-if=
"showDel"
class=
"el-icon-close delete-icon"
title=
"删除"
@
click
.
stop=
"data.splice(index, 1)"
/>
<div
class=
"avatar"
>
<div
:style=
"`background-image:url($
{item.url})`" class="img"/>
<i
class=
"el-icon-close delete-icon"
title=
"删除"
@
click
.
stop=
"data.splice(index, 1)"
/>
</div>
<aplayer
class=
"audio-player"
:music=
"item"
></aplayer>
</div>
</div>
</div>
<div
v-if=
"data.length >0 && uploadType === 'video'"
style=
"display:inline"
@
click=
"handler().getIndex(index)"
>
<div
v-for=
"(item,index) in data"
:key=
"index"
style=
"float:left;"
>
<div
:style=
"style"
class=
"avatar"
>
<i
class=
"el-icon-close delete-icon"
title=
"删除"
@
click
.
stop=
"data.splice(index, 1)"
/>
<video
id=
"myVideo"
:src=
"item.url"
class=
"avatar video-avatar video_text"
controls=
"controls"
>
您的浏览器不支持视频播放
</video>
</div>
</div>
</div>
</div>
<el-progress
v-if=
"videoFlag == true"
type=
"circle"
<!--图片和视频-->
:percentage=
"videoUploadPercent"
<i
:style=
"style"
class=
"avatar el-icon-plus avatar-uploader-icon"
>
style=
"margin-top:7px;"
></el-progress>
</div>
<i
class=
"el-icon-upload"
v-if=
"uploadStyle === 'drag'"
></i>
<div
class=
"el-upload__text"
v-if=
"uploadStyle === 'drag'"
>
将文件拖到此处,或
<em>
点击上传
</em></div>
<el-button
v-if=
"uploadStyle === 'button' || uploadType === 'file'"
size=
"small"
type=
"primary"
>
点击上传
</el-button>
<i
v-else-if=
"uploadStyle === 'icon' || uploadType === 'image'"
:style=
"style"
class=
"avatar el-icon-plus avatar-uploader-icon"
>
<span
class=
"upload-label"
>
{{
label
}}
</span>
<span
class=
"upload-label"
>
{{
label
}}
</span>
</i>
</i>
</el-upload>
<!--文件类型提示-->
<p
class=
"Upload_pictures"
>
<div
slot=
"tip"
class=
"el-upload__tip"
style=
"margin-top:15px"
>
只能上传
{{
handler
().
listByString
(
fileType
)
}}
文件,且不超过500kb
</div>
<span></span>
</el-upload>
<span>
最多可以上传1个视频,建议大小50M,推荐格式mp4
</span>
</p>
<!-- 文件列表 -->
<transition-group
v-if=
"uploadType === 'file'"
class=
"upload-file-list el-upload-list el-upload-list--text"
name=
"el-fade-in-linear"
tag=
"ul"
>
<li
:key=
"index"
class=
"el-upload-list__item ele-upload-list__item-content"
v-for=
"(file, index) in data"
>
<el-link
:href=
"`$
{baseUrl}${file.url}`" :underline="false" target="_blank">
{{
file
}}
<span
class=
"el-icon-document"
>
{{
file
.
name
}}
</span>
</el-link>
<div
class=
"ele-upload-list__item-content-action"
>
<el-link
:underline=
"false"
@
click=
"handleDelete(index)"
type=
"danger"
>
删除
</el-link>
</div>
</li>
</transition-group>
<span
class=
"upload-tips"
>
{{
tips
}}
</span>
<span
class=
"upload-tips"
>
{{
tips
}}
</span>
</div>
</div>
</
template
>
</
template
>
...
@@ -60,6 +28,7 @@ import { mapState } from 'vuex'
...
@@ -60,6 +28,7 @@ import { mapState } from 'vuex'
import
{
getToken
}
from
'@/utils/auth'
// 验权
import
{
getToken
}
from
'@/utils/auth'
// 验权
export
default
{
export
default
{
name
:
'uploadAudio'
,
props
:
{
props
:
{
//上传文字描述
//上传文字描述
label
:
{
label
:
{
...
@@ -100,6 +69,10 @@ export default{
...
@@ -100,6 +69,10 @@ export default{
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
fileSize
:{
type
:
Number
,
default
:
3
},
// 上传图片后是否显示图
// 上传图片后是否显示图
show
:
{
show
:
{
type
:
Boolean
,
type
:
Boolean
,
...
@@ -212,11 +185,11 @@ export default{
...
@@ -212,11 +185,11 @@ export default{
},
},
},
},
watch: {
watch: {
value(
) {
value(value
) {
this.data = this.
value
this.data = this.
init().data(value)
},
},
data() {
data() {
this.$emit('
input
', this.data)
this.$emit('
input
', this.data)
this.$emit('
on
-
success
', this.data)
this.$emit('
on
-
success
', this.data)
},
},
},
},
...
@@ -224,27 +197,47 @@ export default{
...
@@ -224,27 +197,47 @@ export default{
this.index = null;
this.index = null;
this.data = this.value
this.data = this.value
this.init().token()
this.init().token()
// if(this.uploadType === '
video
'){
// this.handler().initVideo();
// }
},
},
methods: {
methods: {
init() {
init() {
return {
return {
// 初始化返回数据
value: (list) => {
let value = ''
const { dataType } = this
switch(dataType) {
case '
string
': // 字符串类型以逗号隔开
value = list.join('
,
')
break
case '
json
':
value = JSON.stringify(list)
break
case '
array
':
value = list
break
}
return value
},
// 初始化数据
data: (value) => {
let data = ''
const { dataType } = this
switch(dataType) {
case '
string
': // 字符串类型以逗号隔开
data = value ? value.split('
,
') : []
break
case '
json
':
data = value ? JSON.parse(value) : []
break
case '
array
':
data = value
break
}
data = Array.isArray(data) ? data : []
return data
},
// 上传前置操作
// 上传前置操作
beforeUpload: (file) => {
beforeUpload: (file) => {
if(this.uploadType === '
video
'){
var fileSize = file.size / 1024 / 1024 < 50;
if (['
video
/
mp4
', '
video
/
ogg
', '
video
/
flv
', '
video
/
avi
', '
video
/
wmv
', '
video
/
rmvb
', '
video
/
mov
'].indexOf(file.type) == -1) {
this.$message("请上传正确的视频格式");
return false;
}
if (!fileSize) {
this.$message("视频大小不能超过50MB");
return false;
}
this.isShowUploadVideo = false;
}
// 校检文件类型
// 校检文件类型
if (this.fileType) {
if (this.fileType) {
let fileExtension = "";
let fileExtension = "";
...
@@ -272,7 +265,7 @@ export default{
...
@@ -272,7 +265,7 @@ export default{
const { name } = file
const { name } = file
let path = `${dayjs().format('
YYYY
/
MM
/
DD
')}/${dayjs().format('
YYYYMMDDHHmmss
')}${Math.ceil(Math.random() * 1000000 % 1000000)}`
let path = `${dayjs().format('
YYYY
/
MM
/
DD
')}/${dayjs().format('
YYYYMMDDHHmmss
')}${Math.ceil(Math.random() * 1000000 % 1000000)}`
console.log('
path
', path)
//
console.log('
path
', path)
path = path.replace('
(
', '')
path = path.replace('
(
', '')
path = path.replace('
)
', '')
path = path.replace('
)
', '')
path = path.replace('
', '')
path = path.replace('
', '')
...
@@ -323,13 +316,6 @@ export default{
...
@@ -323,13 +316,6 @@ export default{
this.data = this.index != null ? this.data.splice(this.index,1,attr) : this.data.push(attr);
this.data = this.index != null ? this.data.splice(this.index,1,attr) : this.data.push(attr);
this.$refs.upload.clearFiles();
this.$refs.upload.clearFiles();
},
},
//进度条
uploadVideoProcess:(event, file, fileList)=>{
if(this.uploadType === '
video
'){
this.videoFlag = true;
this.videoUploadPercent = file.percentage.toFixed(0) * 1;
}
},
//获取索引
//获取索引
getIndex:(index)=>{
getIndex:(index)=>{
this.index = index;
this.index = index;
...
@@ -339,20 +325,18 @@ export default{
...
@@ -339,20 +325,18 @@ export default{
this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
},
},
handlePreview:(file)=>{
handlePreview:(file)=>{
console.log(file);
//
console.log(file);
},
},
initVideo:()=>{
//过滤数组
//初始化视频方法
listByString:(data)=>{
let myPlayer = this.$video(myVideo, {
let attr = '';
//是否显示控制栏
if(typeof data == '
object
' || typeof data == '
array
'){
controls: true,
data.map((item)=>{
//是否自动播放,muted:静音播放
attr+=item+'
/
'
autoplay: false,
})
//是否静音播放
attr = attr.slice(0,attr.length-1);
muted:false,
}
//是否流体自适应容器宽高
return attr
fluid:true,
});
},
},
// 获取文件名称
// 获取文件名称
getFileName:(name)=>{
getFileName:(name)=>{
...
...
packages/form/upload/src/upload-file.vue
View file @
0f9fe073
<
template
>
<
template
>
<div
class=
"upload-imags-list"
>
<div>
<div
class=
"img-box"
>
<el-upload
ref=
"upload"
:show-file-list=
"false"
:on-preview=
"handler().handlePreview()"
:file-list=
"data"
:list-type=
"listType"
:on-exceed=
"(files, fileList)=>handler().handleExceed(files,fileList)"
:drag=
"uploadStyle === 'drag' ? true : false"
:limit=
"limit"
:on-success=
"(file) => handler().imageSuccess(file)"
:action=
"uploadDomain"
:before-upload=
"init().beforeUpload"
:multiple=
"multiple"
:headers=
"headers"
class=
"avatar-uploader"
>
<UploadImg
<i
class=
"el-icon-upload"
v-if=
"uploadStyle === 'drag'"
></i>
v-model=
"list"
<div
class=
"el-upload__text"
v-if=
"uploadStyle === 'drag'"
>
将文件拖到此处,或
<em>
点击上传
</em></div>
:multiple=
"multiple"
<!--文件上传-->
:show-del=
"false"
<el-button
v-if=
"uploadStyle === 'button'"
size=
"small"
type=
"primary"
>
点击上传
</el-button>
:tips=
"tips"
<!--文件类型提示-->
:limit=
"limit"
<div
slot=
"tip"
class=
"el-upload__tip"
style=
"margin-top:15px"
>
只能上传
{{
handler
().
listByString
(
fileType
)
}}
文件,且不超过500kb
</div>
:uploadType=
"uploadType"
</el-upload>
:showDel=
"showDel"
<!-- 文件列表 -->
:label=
"label"
<transition-group
class=
"upload-file-list el-upload-list el-upload-list--text"
name=
"el-fade-in-linear"
tag=
"ul"
>
:source=
"source"
<li
:key=
"index"
class=
"el-upload-list__item ele-upload-list__item-content"
v-for=
"(file, index) in data"
>
:size=
"size"
<el-link
:href=
"`$
{baseUrl}${file.url}`" :underline="false" target="_blank">
:edit=
"edit"
<span
class=
"el-icon-document"
>
{{
file
.
name
}}
</span>
:dialog=
"dialog"
</el-link>
class=
"uploadImg"
/>
<div
class=
"ele-upload-list__item-content-action"
>
</div>
<el-link
:underline=
"false"
@
click=
"handleDelete(index)"
type=
"danger"
>
删除
</el-link>
</div>
</li>
</transition-group>
<span
class=
"upload-tips"
>
{{
tips
}}
</span>
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
>
import
UploadImg
from
'./base-upload'
import
dayjs
from
'dayjs'
import
{
mapState
}
from
'vuex'
import
{
getToken
}
from
'@/utils/auth'
// 验权
export
default
{
export
default
{
name
:
'CyUploadImgList'
,
name
:
'uploadFile'
,
components
:
{
UploadImg
,
},
props
:
{
props
:
{
//上传文字描述
label
:
{
label
:
{
type
:
String
,
type
:
String
,
default
:
'上传'
,
default
:
'上传'
,
},
},
limit
:
{
// 文件上传数量限制,默认10
//上传值
type
:
Number
,
value
:
{
default
:
10
,
type
:
[
String
,
Object
,
Array
],
default
:
''
,
},
},
//
是否删除
//
是否多选
showDel
:
{
multiple
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
tru
e
,
default
:
fals
e
,
},
},
//上传类型
limit
:
{
// 图片上传数量限制,默认10
uploadType
:{
type
:
Number
,
type
:
String
,
default
:
10
,
default
:
'file'
},
},
value
:
{
// 组件大小(px)
type
:
[
String
,
Object
,
Array
],
size
:
{
default
:
null
,
type
:
[
String
,
Number
],
default
:
100
,
},
},
edit
:
{
// 是否可编辑
// 图片大小限制(kb)
type
:
Boolean
,
sizeLimit
:
{
default
:
true
,
type
:
Number
,
default
:
3000
,
},
},
// 是否使用文件库组件
fileSize
:{
dialog
:
{
type
:
Number
,
default
:
3
},
// 上传图片后是否显示图
show
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
//
是否多选文件
//
上传组件风格
multip
le
:{
uploadSty
le
:{
type
:
Boolean
,
type
:
String
,
default
:
false
default
:
'button'
},
},
//
文件列表数据结构,json,array,string
//
文件样式
dataType
:
{
listType
:
{
type
:
String
,
type
:
String
,
default
:
'string'
,
default
:
''
},
},
tips
:
{
tips
:
{
type
:
String
,
type
:
String
,
default
:
''
,
default
:
''
,
},
},
// 文件类型, 例如["doc", "xls", "ppt", "txt", "pdf"]
fileType
:
{
type
:
Array
,
default
:
()
=>
[
'png'
,
'jpg'
,
'jpeg'
]
,
},
source
:
{
// 上传服务器
source
:
{
// 上传服务器
type
:
String
,
type
:
String
,
default
:
'local'
,
// local:本站点,qiniu:七牛云,oss:阿里云,tencent:腾讯云
default
:
'local'
,
// local:本站点,qiniu:七牛云,oss:阿里云,tencent:腾讯云
},
},
// 组件大小
size
:
{
type
:
Number
,
default
:
100
,
},
//上传组件风格
uploadStyle
:{
type
:
String
,
default
:
'icon'
},
//文件样式
listType
:{
type
:
String
,
default
:
''
},
},
},
data
()
{
data
()
{
return
{
return
{
dialog_visible
:
false
,
index
:
null
,
data
:
[],
qiniuToken
:
''
,
qiniuToken
:
''
,
list
:
[],
// 文件列表
baseUrl
:
process
.
env
.
VUE_APP_BASE_API
,
index
:
''
,
imgDomain
:
''
,
headers
:
{
Authorization
:
"Bearer "
+
getToken
(),
},
}
}
},
},
computed
:
{
...
mapState
({
ossConfig
:
state
=>
state
.
ossConfig
,
appConfig
:
state
=>
state
.
appConfig
,
}),
uploadDomain
()
{
const
{
source
}
=
this
let
uploadDomain
=
''
switch
(
source
)
{
case
'qiniu'
:
// 七牛云
break
case
'oss'
:
// 阿里云
break
case
'tencent'
:
// 腾讯云
break
default
:
// 默认,本地上传接口
uploadDomain
=
process
.
env
.
VUE_APP_BASE_API
+
"/common/upload"
// 上传的图片服务器地址
break
}
return
uploadDomain
},
style
()
{
const
style
=
{
height
:
`
${
this
.
size
}
px`
,
width
:
`
${
this
.
size
}
px`
,
lineHeight
:
`
${
this
.
size
}
px`
,
}
return
style
},
avatarStyle
()
{
const
style
=
{
lineHeight
:
`
${
this
.
size
}
px`
,
}
return
style
},
OssClient
()
{
const
{
access_key
,
bucket
,
region_id
,
secret
}
=
this
.
ossConfig
if
(
!
access_key
)
{
return
''
}
const
client
=
new
OSS
({
region
:
region_id
,
// 阿里云账号AccessKey拥有所有API的访问权限,建议遵循阿里云安全最佳实践,创建并使用STS方式访问API。
accessKeyId
:
access_key
,
accessKeySecret
:
secret
,
// stsToken: '
<
Your
securityToken
(
STS
)
>
',
bucket,
})
return client
},
// 大小转换
sizeText() {
const { sizeLimit } = this
const text = sizeLimit > 1000 ? (sizeLimit / (1024)).toFixed(2) + '
m
' : sizeLimit + '
kb
'
return text
},
},
watch: {
watch: {
value(value) {
value(value) {
this
.
list
=
this
.
init
().
data
(
value
)
this.
data
= this.init().data(value)
},
},
list
(
value
)
{
data(
) {
const
data
=
this
.
init
().
value
(
value
)
this.$emit('
input
', this.data
)
this
.
$emit
(
'
input'
,
data
)
this.$emit('
on
-
success
', this.
data)
},
},
},
},
created() {
created() {
this
.
list
=
this
.
init
().
data
(
this
.
value
)
this.index = null;
this.data = this.value
this.init().token()
},
},
methods: {
methods: {
init() {
init() {
return {
return {
// 初始化返回数据
// 初始化返回数据
value: (list) => {
value: (list) => {
let value = ''
let value = ''
const { dataType } = this
const { dataType } = this
...
@@ -152,76 +215,195 @@ export default{
...
@@ -152,76 +215,195 @@ export default{
data = Array.isArray(data) ? data : []
data = Array.isArray(data) ? data : []
return data
return data
},
},
// 上传前置操作
beforeUpload: (file) => {
// 校检文件类型
if (this.fileType) {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
}
const isTypeOk = this.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
});
if (!isTypeOk) {
this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
return false;
}
}
const { sizeText, sizeLimit, } = this
if (file.size > (sizeLimit * 1000)) {
this.$alert(`图片大小不能超过${sizeText}`)
return false;
}
if (this.uploadDomain) {
return true
}
const { name } = file
let path = `${dayjs().format('
YYYY
/
MM
/
DD
')}/${dayjs().format('
YYYYMMDDHHmmss
')}${Math.ceil(Math.random() * 1000000 % 1000000)}`
// console.log('
path
', path)
path = path.replace('
(
', '')
path = path.replace('
)
', '')
path = path.replace('
', '')
this.putObject(path, file)
// try {
// // 获取七牛云token
// const res = await this.$request.post('
/
admin
/
getQiniuToken
')
// this.qiniuToken = res.data.token
// return res.data.token
// } catch (err) {
// this.$message('
请求出错
')
// return false
// }
},
token: () => {
const { source } = this
let token = ''
switch (source) {
case '
local
': // 本地点上传
token = getToken()
this.token = token
break
}
},
}
}
},
},
handler() {
handler() {
return {
return {
upload
:
(
key
)
=>
{
// 图片上传成功回调
this
.
list
.
push
(
key
)
imageSuccess: (data,file) => {
},
const link = data.url;
choiceImg
:
(
index
)
=>
{
// this.data = url
if
(
!
this
.
edit
)
{
let attrs = {
return
name:file.name,
url:link
}
}
this
.
index
=
index
this.data = this.data.push(attrs);
this
.
$refs
.
uploadImg
.
show
()
this.$refs.upload.clearFiles();
},
// 文件个数超出
handleExceed:(file,fileList)=>{
this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
},
},
confirm
:
(
data
)
=>
{
handlePreview:(file)=>{
const
{
index
,
limit
}
=
this
// console.log(file);
let
{
list
}
=
this
},
if
(
index
===
''
)
{
//过滤数组
list
=
list
.
concat
(
data
)
listByString:(data)=>{
}
else
{
let attr = '';
list
.
splice
(
index
,
1
,
data
)
if(typeof data == '
object
' || typeof data == '
array
'){
data.map((item)=>{
attr+=item+'
/
'
})
attr = attr.slice(0,attr.length-1);
}
}
this
.
list
=
list
.
slice
(
0
,
limit
)
return attr
const
value
=
this
.
init
().
value
(
this
.
list
)
},
this
.
$emit
(
'input'
,
value
)
// 获取文件名称
getFileName:(name)=>{
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
} else {
return "";
}
},
del: () => {
this.data = ''
this.$emit('
delete
')
},
},
}
}
},
},
/**
* key 文件吗
* data 文件
*/
async putObject(key, data) {
try {
console.log('
file
', data)
console.log('
OssClient
', this.OssClient)
const { OssClient } = this
// object-key可以自定义为文件名(例如file.txt)或目录(例如abc/test/file.txt)的形式,实现将文件上传至当前Bucket或Bucket下的指定目录。
const result = await OssClient.put(key, data)
const { name } = result
this.data = name
this.$emit('
on
-
confirm
', this.data)
} catch (e) {
console.log('
error
', e)
}
}
},
},
}
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.upload-imags-list
{
.upload-file-uploader
{
font-size
:
0
;
margin-bottom
:
5px
;
.avatar-uploader
{
}
display
:
block
;
.upload-file-list
.el-upload-list__item
{
display
:
inline-block
;
border
:
1px
solid
#e4e7ed
;
margin-right
:
5px
;
line-height
:
2
;
margin-bottom
:
5px
;
margin-bottom
:
10px
;
float
:
left
;
position
:
relative
;
.img-box
{
}
.upload-file-list
.ele-upload-list__item-content
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
color
:
inherit
;
}
.video-avatar
{
margin-top
:
-16
.5px
;
}
.ele-upload-list__item-content-action
.el-link
{
margin-right
:
10px
;
}
.avatar-uploader
{
display
:
block
;
margin-bottom
:
2px
;
margin-right
:
2px
;
position
:
relative
;
line-height
:
0
;
.avatar-uploader-icon
{
width
:
100%
;
height
:
100%
;
font-size
:
16px
;
}
.avatar
{
width
:
100%
;
height
:
100%
;
margin-right
:
5px
;
border
:
1px
solid
rgb
(
241
,
241
,
241
);
box-sizing
:
border-box
;
&
.avatar-uploader-icon
{
}
.delete-icon
{
position
:
relative
;
top
:
0
;
float
:
right
;
font-size
:
16px
;
background
:
red
;
color
:
white
;
border-radius
:
4px
;
z-index
:
1000
;
cursor
:
pointer
;
}
.img
{
background-position
:
center
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
width
:
100%
;
width
:
100%
;
height
:
100%
;
height
:
100%
;
box-sizing
:
border-box
;
border-radius
:
4px
;
position
:
relative
;
.delete-icon
{
position
:
absolute
;
top
:
0
;
right
:
0
;
font-size
:
16px
;
background
:
red
;
color
:
white
;
border-radius
:
4px
;
z-index
:
100
;
cursor
:
pointer
;
}
.img
{
background-position
:
center
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
width
:
100%
;
height
:
100%
;
}
}
}
.avatar-uploader-icon
{
.upload-label
{
box-sizing
:
border-box
;
font-size
:
14px
;
}
.upload-tips
{
display
:
block
;
font-size
:
12px
;
}
}
}
}
}
}
</
style
>
</
style
>
packages/form/upload/src/upload-img-list.vue
View file @
0f9fe073
...
@@ -3,18 +3,14 @@
...
@@ -3,18 +3,14 @@
<div
v-for=
"(item, index) in list"
:key=
"index"
class=
"avatar-uploader img"
>
<div
v-for=
"(item, index) in list"
:key=
"index"
class=
"avatar-uploader img"
>
<div
class=
"img-box"
>
<div
class=
"img-box"
>
<i
v-if=
"edit"
class=
"el-icon-close delete-icon"
title=
"删除"
@
click
.
stop=
"list.splice(index, 1)"
/>
<i
v-if=
"edit"
class=
"el-icon-close delete-icon"
title=
"删除"
@
click
.
stop=
"list.splice(index, 1)"
/>
<
uploadi
mg
<
UploadI
mg
v-model=
"list"
v-model=
"list
[index]
"
:multiple=
"false"
:multiple=
"false"
:show-del=
"false"
:show-del=
"false"
:tips=
"tips"
:tips=
"tips"
:source=
"source"
:source=
"source"
:uploadstyle=
"uploadstyle"
:datatype=
"datatype"
:listtype=
"listtype"
:size=
"size"
:size=
"size"
class=
"uploadimg"
>
class=
"uploadImg"
/>
</uploadimg>
</div>
</div>
</div>
</div>
<div
v-if=
"list.length
<
limit
&&
edit
"
class=
"avatar-uploader"
>
<div
v-if=
"list.length
<
limit
&&
edit
"
class=
"avatar-uploader"
>
...
@@ -26,10 +22,6 @@
...
@@ -26,10 +22,6 @@
:tips=
"tips"
:tips=
"tips"
:source=
"source"
:source=
"source"
:size=
"size"
:size=
"size"
v-model=
"value"
:dataType=
"dataType"
:uploadStyle=
"uploadStyle"
:listType=
"listType"
class=
"uploadImg"
class=
"uploadImg"
@
on-success=
"(e) => handler().upload(e)"
/>
@
on-success=
"(e) => handler().upload(e)"
/>
</div>
</div>
...
@@ -38,9 +30,8 @@
...
@@ -38,9 +30,8 @@
<
script
>
<
script
>
import
UploadImg
from
'./upload-img'
import
UploadImg
from
'./upload-img'
export
default
{
export
default
{
name
:
'CyUploadImg'
,
name
:
'CyUploadImg
List
'
,
components
:
{
components
:
{
UploadImg
,
UploadImg
,
},
},
...
@@ -51,10 +42,10 @@ export default{
...
@@ -51,10 +42,10 @@ export default{
},
},
limit
:
{
// 图片上传数量限制,默认10
limit
:
{
// 图片上传数量限制,默认10
type
:
Number
,
type
:
Number
,
default
:
1
0
,
default
:
1
,
},
},
value
:
{
value
:
{
type
:
null
,
type
:
[
String
,
Object
,
Array
]
,
default
:
null
,
default
:
null
,
},
},
edit
:
{
// 是否可编辑
edit
:
{
// 是否可编辑
...
@@ -84,16 +75,6 @@ export default{
...
@@ -84,16 +75,6 @@ export default{
type
:
Number
,
type
:
Number
,
default
:
100
,
default
:
100
,
},
},
//上传组件风格
uploadStyle
:{
type
:
String
,
default
:
'icon'
},
//文件样式
listType
:{
type
:
String
,
default
:
''
},
},
},
data
()
{
data
()
{
return
{
return
{
...
@@ -113,7 +94,7 @@ export default{
...
@@ -113,7 +94,7 @@ export default{
},
},
},
},
created
()
{
created
()
{
this
.
list
=
this
.
init
().
data
(
this
.
value
)
;
this
.
list
=
this
.
init
().
data
(
this
.
value
)
},
},
methods
:
{
methods
:
{
init
()
{
init
()
{
...
@@ -188,6 +169,7 @@ export default{
...
@@ -188,6 +169,7 @@ export default{
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.upload-imags-list
{
.upload-imags-list
{
font-size
:
0
;
font-size
:
0
;
overflow
:
auto
;
.avatar-uploader
{
.avatar-uploader
{
display
:
block
;
display
:
block
;
display
:
inline-block
;
display
:
inline-block
;
...
...
packages/form/upload/src/upload-img.vue
View file @
0f9fe073
<
template
>
<
template
>
<div
class=
"upload-imags-list"
>
<div>
<div
class=
"img-box"
>
<el-upload
:show-file-list=
"false"
:on-success=
"(file) => handler().imageSuccess(file)"
:action=
"uploadDomain"
:data=
"
{ token: qiniuToken, 'X-Access-Token': token }" :before-upload="init().beforeUpload" :multiple="multiple" :headers="headers" class="avatar-uploader" >
<UploadImg
<div
v-if=
"data && show"
:style=
"style"
class=
"avatar"
>
v-model=
"list"
<i
v-if=
"showDel"
class=
"el-icon-close delete-icon"
title=
"删除"
@
click
.
stop=
"handler().del()"
/>
:multiple=
"multiple"
<div
:style=
"`background-image:url($
{src})`" class="img"/>
:show-del=
"false"
:tips=
"tips"
:limit=
"limit"
:uploadType=
"uploadType"
:showDel=
"showDel"
:label=
"label"
:source=
"source"
:size=
"size"
:edit=
"edit"
:dialog=
"dialog"
class=
"uploadImg"
/>
</div>
</div>
<i
v-else
:style=
"style"
class=
"avatar el-icon-plus avatar-uploader-icon"
>
<span
class=
"upload-label"
>
{{
label
}}
</span>
</i>
</el-upload>
<span
class=
"upload-tips"
>
{{
tips
}}
</span>
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
>
import
UploadImg
from
'./base-upload'
import
dayjs
from
'dayjs'
import
{
mapState
}
from
'vuex'
import
{
getToken
}
from
'@/utils/auth'
// 验权
export
default
{
export
default
{
name
:
'CyUploadImgList'
,
components
:
{
UploadImg
,
},
props
:
{
props
:
{
label
:
{
label
:
{
type
:
String
,
type
:
String
,
default
:
'上传'
,
default
:
'上传'
,
},
},
limit
:
{
// 图片上传数量限制,默认10
value
:
{
type
:
Number
,
default
:
10
,
},
value
:
{
type
:
[
String
,
Object
,
Array
],
type
:
[
String
,
Object
,
Array
],
default
:
null
,
default
:
''
,
},
},
//上传类型
// 是否多选
uploadType
:{
multiple
:
{
type
:
String
,
type
:
Boolean
,
default
:
'image'
default
:
false
,
},
// 组件大小(px)
size
:
{
type
:
[
String
,
Number
],
default
:
100
,
},
// 图片大小限制(kb)
sizeLimit
:
{
type
:
Number
,
default
:
3000
,
},
},
edit
:
{
// 是否可编辑
showDel
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
//
是否使用图片库组件
//
上传图片后是否显示图
dialog
:
{
show
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
// 图片列表数据结构,json,array,string
dataType
:
{
type
:
String
,
default
:
'string'
,
},
tips
:
{
tips
:
{
type
:
String
,
type
:
String
,
default
:
''
,
default
:
''
,
...
@@ -67,150 +60,217 @@ export default{
...
@@ -67,150 +60,217 @@ export default{
type
:
String
,
type
:
String
,
default
:
'local'
,
// local:本站点,qiniu:七牛云,oss:阿里云,tencent:腾讯云
default
:
'local'
,
// local:本站点,qiniu:七牛云,oss:阿里云,tencent:腾讯云
},
},
// 组件大小
size
:
{
type
:
Number
,
default
:
100
,
},
//上传组件风格
uploadStyle
:{
type
:
String
,
default
:
'icon'
},
//文件样式
listType
:{
type
:
String
,
default
:
''
},
},
},
data
()
{
data
()
{
return
{
return
{
d
ialog_visible
:
false
,
d
ata
:
''
,
qiniuToken
:
''
,
qiniuToken
:
''
,
list
:
[],
// 文件列表
imgDomain
:
''
,
index
:
''
,
token
:
''
,
headers
:
{
Authorization
:
"Bearer "
+
getToken
(),
},
}
}
},
},
computed
:
{
...
mapState
({
ossConfig
:
state
=>
state
.
ossConfig
,
appConfig
:
state
=>
state
.
appConfig
,
}),
uploadDomain
()
{
const
{
source
}
=
this
let
uploadDomain
=
''
switch
(
source
)
{
case
'qiniu'
:
// 七牛云
break
case
'oss'
:
// 阿里云
break
case
'tencent'
:
// 腾讯云
break
default
:
// 默认,本地上传接口
uploadDomain
=
process
.
env
.
VUE_APP_BASE_API
+
"/file/upload"
// 上传的图片服务器地址
break
}
return
uploadDomain
},
src
()
{
const
{
data
,
imgDomain
}
=
this
const
reg
=
/^
([
hH
][
tT
]{2}[
pP
]
:
\/\/
|
[
hH
][
tT
]{2}[
pP
][
sS
]
:
\/\/)(([
A-Za-z0-9-~
]
+
)\.)
+
([
A-Za-z0-9-~
\/])
+$/
if
(
reg
.
test
(
data
))
{
return
data
}
return
data
?
imgDomain
+
data
:
''
},
style
()
{
const
style
=
{
height
:
`
${
this
.
size
}
px`
,
width
:
`
${
this
.
size
}
px`
,
lineHeight
:
`
${
this
.
size
}
px`
,
}
return
style
},
avatarStyle
()
{
const
style
=
{
lineHeight
:
`
${
this
.
size
}
px`
,
}
return
style
},
OssClient
()
{
const
{
access_key
,
bucket
,
region_id
,
secret
}
=
this
.
ossConfig
if
(
!
access_key
)
{
return
''
}
const
client
=
new
OSS
({
region
:
region_id
,
// 阿里云账号AccessKey拥有所有API的访问权限,建议遵循阿里云安全最佳实践,创建并使用STS方式访问API。
accessKeyId
:
access_key
,
accessKeySecret
:
secret
,
// stsToken: '
<
Your
securityToken
(
STS
)
>
',
bucket,
})
return client
},
// 大小转换
sizeText() {
const { sizeLimit } = this
const text = sizeLimit > 1000 ? (sizeLimit / (1024)).toFixed(2) + '
m
' : sizeLimit + '
kb
'
return text
},
},
watch: {
watch: {
value
(
value
)
{
value() {
this
.
list
=
this
.
init
().
data
(
value
)
this.
data = this.value
},
},
list
(
value
)
{
data(
) {
const
data
=
this
.
init
().
value
(
value
)
this.$emit('
input
', this.data
)
this
.
$emit
(
'
input'
,
data
)
this.$emit('
on
-
success
', this.
data)
},
},
},
},
created() {
created() {
this
.
list
=
this
.
init
().
data
(
this
.
value
)
this.data = this.value
this.init().token()
},
},
methods: {
methods: {
init() {
init() {
return {
return {
// 初始化返回数据
// 上传前置操作
value
:
(
list
)
=>
{
beforeUpload: async(file) => {
let
value
=
''
const { sizeText, sizeLimit, } = this
const
{
dataType
}
=
this
if (file.size > (sizeLimit * 1000)) {
switch
(
dataType
)
{
this.$alert(`图片大小不能超过${sizeText}`)
case
'string'
:
// 字符串类型以逗号隔开
return
value
=
list
.
join
(
','
)
}
break
if (this.uploadDomain) {
case
'json'
:
return true
value
=
JSON
.
stringify
(
list
)
break
case
'array'
:
value
=
list
break
}
}
return
value
const { name } = file
let path = `${dayjs().format('
YYYY
/
MM
/
DD
')}/${dayjs().format('
YYYYMMDDHHmmss
')}${Math.ceil(Math.random() * 1000000 % 1000000)}`
console.log('
path
', path)
path = path.replace('
(
', '')
path = path.replace('
)
', '')
path = path.replace('
', '')
this.putObject(path, file)
// try {
// // 获取七牛云token
// const res = await this.$request.post('
/
admin
/
getQiniuToken
')
// this.qiniuToken = res.data.token
// return res.data.token
// } catch (err) {
// this.$message('
请求出错
')
// return false
// }
},
},
// 初始化数据
token: () => {
data
:
(
value
)
=>
{
const { source } = this
let
data
=
''
let token = ''
const
{
dataType
}
=
this
switch (source) {
switch
(
dataType
)
{
case '
local
': // 本地点上传
case
'string'
:
// 字符串类型以逗号隔开
token = getToken()
data
=
value
?
value
.
split
(
','
)
:
[]
this.token = token
break
case
'json'
:
data
=
value
?
JSON
.
parse
(
value
)
:
[]
break
case
'array'
:
data
=
value
break
break
}
}
data
=
Array
.
isArray
(
data
)
?
data
:
[]
return
data
},
},
}
}
},
},
handler() {
handler() {
return {
return {
upload
:
(
key
)
=>
{
// 图片上传成功回调
this
.
list
.
push
(
key
)
imageSuccess: ({ data }) => {
const { url } = data
this.data = url
},
},
choiceImg
:
(
index
)
=>
{
del: () => {
if
(
!
this
.
edit
)
{
this.data = ''
return
this.$emit('
delete
')
}
this
.
index
=
index
this
.
$refs
.
uploadImg
.
show
()
},
confirm
:
(
data
)
=>
{
const
{
index
,
limit
}
=
this
let
{
list
}
=
this
if
(
index
===
''
)
{
list
=
list
.
concat
(
data
)
}
else
{
list
.
splice
(
index
,
1
,
data
)
}
this
.
list
=
list
.
slice
(
0
,
limit
)
const
value
=
this
.
init
().
value
(
this
.
list
)
this
.
$emit
(
'input'
,
value
)
},
},
}
}
},
},
/**
* key 文件吗
* data 文件
*/
async putObject(key, data) {
try {
console.log('
file
', data)
console.log('
OssClient
', this.OssClient)
const { OssClient } = this
// object-key可以自定义为文件名(例如file.txt)或目录(例如abc/test/file.txt)的形式,实现将文件上传至当前Bucket或Bucket下的指定目录。
const result = await OssClient.put(key, data)
const { name } = result
this.data = name
this.$emit('
on
-
confirm
', this.data)
} catch (e) {
console.log('
error
', e)
}
}
},
},
}
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.upload-imags-list
{
.avatar-uploader
{
font-size
:
0
;
display
:
block
;
.avatar-uploader
{
margin-bottom
:
2px
;
display
:
block
;
margin-right
:
2px
;
display
:
inline-block
;
position
:
relative
;
margin-right
:
5px
;
line-height
:
0
;
margin-bottom
:
5px
;
.avatar-uploader-icon
{
float
:
left
;
width
:
100%
;
.img-box
{
height
:
100%
;
font-size
:
16px
;
}
.avatar
{
width
:
100%
;
height
:
100%
;
border
:
1px
solid
rgb
(
241
,
241
,
241
);
box-sizing
:
border-box
;
&
.avatar-uploader-icon
{
}
.delete-icon
{
position
:
absolute
;
top
:
0
;
right
:
0
;
font-size
:
16px
;
background
:
red
;
color
:
white
;
border-radius
:
4px
;
cursor
:
pointer
;
}
.img
{
background-position
:
center
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
width
:
100%
;
width
:
100%
;
height
:
100%
;
height
:
100%
;
box-sizing
:
border-box
;
border-radius
:
4px
;
position
:
relative
;
.delete-icon
{
position
:
absolute
;
top
:
0
;
right
:
0
;
font-size
:
16px
;
background
:
red
;
color
:
white
;
border-radius
:
4px
;
z-index
:
100
;
cursor
:
pointer
;
}
.img
{
background-position
:
center
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
width
:
100%
;
height
:
100%
;
}
}
}
.avatar-uploader-icon
{
.upload-label
{
box-sizing
:
border-box
;
font-size
:
14px
;
}
.upload-tips
{
display
:
block
;
font-size
:
12px
;
}
}
}
}
}
}
</
style
>
</
style
>
packages/form/upload/src/upload-video.vue
View file @
0f9fe073
<
template
>
<
template
>
<div
class=
"upload-imags-list"
>
<div>
<div
class=
"img-box"
>
<el-upload
ref=
"upload"
:show-file-list=
"false"
:on-preview=
"handler().handlePreview()"
:on-progress=
"(event, file, fileList)=>handler().uploadVideoProcess(event, file, fileList)"
:file-list=
"data"
:list-type=
"listType"
:on-exceed=
"(files, fileList)=>handler().handleExceed(files,fileList)"
:drag=
"uploadStyle === 'drag' ? true : false"
:limit=
"limit"
:on-success=
"(file) => handler().imageSuccess(file)"
:action=
"uploadDomain"
:before-upload=
"init().beforeUpload"
:multiple=
"multiple"
:headers=
"headers"
class=
"avatar-uploader"
>
<UploadImg
<!--视频-->
v-model=
"list"
<div
v-if=
"data.length >0"
style=
"display:inline"
@
click=
"handler().getIndex(index)"
>
:multiple=
"multiple"
<div
v-for=
"(item,index) in data"
:key=
"index"
style=
"float:left;"
>
:show-del=
"false"
<div
:style=
"style"
class=
"avatar"
>
:tips=
"tips"
<i
class=
"el-icon-close delete-icon"
title=
"删除"
@
click
.
stop=
"data.splice(index, 1)"
/>
:limit=
"limit"
<video
id=
"myVideo"
:uploadType=
"uploadType"
:src=
"item.url"
:showDel=
"showDel"
class=
"avatar video-avatar video_text"
:label=
"label"
controls=
"controls"
>
:source=
"source"
您的浏览器不支持视频播放
:size=
"size"
</video>
:edit=
"edit"
</div>
:dialog=
"dialog"
</div>
class=
"uploadImg"
/>
<el-progress
v-if=
"videoFlag == true"
type=
"circle"
:percentage=
"videoUploadPercent"
style=
"margin-top:7px;"
></el-progress>
</div>
</div>
<!--图片和视频-->
<i
:style=
"style"
class=
"avatar el-icon-plus avatar-uploader-icon"
>
<span
class=
"upload-label"
>
{{
label
}}
</span>
</i>
<!--文件类型提示-->
<div
slot=
"tip"
class=
"el-upload__tip"
style=
"margin-top:15px"
>
只能上传
{{
handler
().
listByString
(
fileType
)
}}
文件,且不超过500kb
</div>
</el-upload>
<!--
<p
class=
"upload_pictures"
style=
"z-index:1000;font-size:15px"
>
<span>
最多可以上传
{{
limit
}}
个视频,建议大小50M,推荐格式mp4
</span>
</p>
-->
<span
class=
"upload-tips"
>
{{
tips
}}
</span>
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
>
import
UploadImg
from
'./base-upload'
import
dayjs
from
'dayjs'
import
{
mapState
}
from
'vuex'
import
{
getToken
}
from
'@/utils/auth'
// 验权
export
default
{
export
default
{
name
:
'CyUploadImgList'
,
name
:
'uploadVideo'
,
components
:
{
UploadImg
,
},
props
:
{
props
:
{
//上传文字描述
label
:
{
label
:
{
type
:
String
,
type
:
String
,
default
:
'上传'
,
default
:
'上传'
,
},
},
limit
:
{
// 视频上传数量限制,默认10
//上传值
value
:
{
type
:
[
String
,
Object
,
Array
],
default
:
''
,
},
// 是否多选
multiple
:
{
type
:
Boolean
,
default
:
false
,
},
limit
:
{
// 图片上传数量限制,默认10
type
:
Number
,
type
:
Number
,
default
:
10
,
default
:
10
,
},
},
//上传类型
// 组件大小(px)
uploadType
:
{
size
:
{
type
:
String
,
type
:
[
String
,
Number
]
,
default
:
'video'
default
:
100
,
},
},
value
:
{
// 图片大小限制(kb)
type
:
[
String
,
Object
,
Array
],
sizeLimit
:
{
default
:
null
,
type
:
Number
,
default
:
3000
,
},
},
edit
:
{
// 是否可编辑
//显示删除
showDel
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
// 是否使用视频库组件
fileSize
:{
dialog
:
{
type
:
Number
,
default
:
3
},
// 上传图片后是否显示图
show
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
// 视频列表数据结构,json,array,string
//上传组件风格
dataType
:
{
type
:
String
,
default
:
'string'
,
},
tips
:
{
type
:
String
,
default
:
''
,
},
source
:
{
// 上传服务器
type
:
String
,
default
:
'local'
,
// local:本站点,qiniu:七牛云,oss:阿里云,tencent:腾讯云
},
// 组件大小
size
:
{
type
:
Number
,
default
:
200
,
},
//上传组件风格
uploadStyle
:{
uploadStyle
:{
type
:
String
,
type
:
String
,
default
:
'icon'
default
:
'icon'
...
@@ -82,31 +95,120 @@ export default{
...
@@ -82,31 +95,120 @@ export default{
type
:
String
,
type
:
String
,
default
:
''
default
:
''
},
},
tips
:
{
type
:
String
,
default
:
''
,
},
// 文件类型, 例如["doc", "xls", "ppt", "txt", "pdf"]
fileType
:
{
type
:
Array
,
default
:
()
=>
[
'png'
,
'jpg'
,
'jpeg'
]
,
},
source
:
{
// 上传服务器
type
:
String
,
default
:
'local'
,
// local:本站点,qiniu:七牛云,oss:阿里云,tencent:腾讯云
},
},
},
data
()
{
data
()
{
return
{
return
{
dialog_visible
:
false
,
index
:
null
,
data
:
''
,
qiniuToken
:
''
,
qiniuToken
:
''
,
list
:
[],
// 文件列表
baseUrl
:
process
.
env
.
VUE_APP_BASE_API
,
index
:
''
,
videoFlag
:
false
,
//是否显示进度条
videoUploadPercent
:
""
,
//进度条的进度,
isShowUploadVideo
:
false
,
imgDomain
:
''
,
headers
:
{
Authorization
:
"Bearer "
+
getToken
(),
},
}
}
},
},
computed
:
{
...
mapState
({
ossConfig
:
state
=>
state
.
ossConfig
,
appConfig
:
state
=>
state
.
appConfig
,
}),
uploadDomain
()
{
const
{
source
}
=
this
let
uploadDomain
=
''
switch
(
source
)
{
case
'qiniu'
:
// 七牛云
break
case
'oss'
:
// 阿里云
break
case
'tencent'
:
// 腾讯云
break
default
:
// 默认,本地上传接口
uploadDomain
=
process
.
env
.
VUE_APP_BASE_API
+
"/common/upload"
// 上传的图片服务器地址
break
}
return
uploadDomain
},
src
()
{
const
{
data
,
imgDomain
}
=
this
const
reg
=
/^
([
hH
][
tT
]{2}[
pP
]
:
\/\/
|
[
hH
][
tT
]{2}[
pP
][
sS
]
:
\/\/)(([
A-Za-z0-9-~
]
+
)\.)
+
([
A-Za-z0-9-~
\/])
+$/
if
(
reg
.
test
(
data
))
{
return
data
}
return
data
?
imgDomain
+
data
:
''
},
style
()
{
const
style
=
{
height
:
`
${
this
.
size
}
px`
,
width
:
`
${
this
.
size
}
px`
,
lineHeight
:
`
${
this
.
size
}
px`
,
}
return
style
},
avatarStyle
()
{
const
style
=
{
lineHeight
:
`
${
this
.
size
}
px`
,
}
return
style
},
OssClient
()
{
const
{
access_key
,
bucket
,
region_id
,
secret
}
=
this
.
ossConfig
if
(
!
access_key
)
{
return
''
}
const
client
=
new
OSS
({
region
:
region_id
,
// 阿里云账号AccessKey拥有所有API的访问权限,建议遵循阿里云安全最佳实践,创建并使用STS方式访问API。
accessKeyId
:
access_key
,
accessKeySecret
:
secret
,
// stsToken: '
<
Your
securityToken
(
STS
)
>
',
bucket,
})
return client
},
// 大小转换
sizeText() {
const { sizeLimit } = this
const text = sizeLimit > 1000 ? (sizeLimit / (1024)).toFixed(2) + '
m
' : sizeLimit + '
kb
'
return text
},
},
watch: {
watch: {
value(value) {
value(value) {
this
.
list
=
value
;
this.
data = this.init().data(value)
},
},
list
(
value
)
{
data(
) {
const
data
=
this
.
init
().
value
(
value
)
this.$emit('
input
', this.data
)
this
.
$emit
(
'
input'
,
data
)
this.$emit('
on
-
success
', this.
data)
},
},
},
},
created() {
created() {
this
.
list
=
this
.
init
().
data
(
this
.
value
)
this.index = null;
this.data = this.value
this.init().token()
},
},
methods: {
methods: {
init() {
init() {
return {
return {
// 初始化返回数据
// 初始化返回数据
value: (list) => {
value: (list) => {
let value = ''
let value = ''
const { dataType } = this
const { dataType } = this
...
@@ -141,76 +243,229 @@ export default{
...
@@ -141,76 +243,229 @@ export default{
data = Array.isArray(data) ? data : []
data = Array.isArray(data) ? data : []
return data
return data
},
},
// 上传前置操作
beforeUpload: (file) => {
var fileSize = file.size / 1024 / 1024 < 50;
if (['
video
/
mp4
', '
video
/
ogg
', '
video
/
flv
', '
video
/
avi
', '
video
/
wmv
', '
video
/
rmvb
', '
video
/
mov
'].indexOf(file.type) == -1) {
this.$message("请上传正确的视频格式");
return false;
}
if (!fileSize) {
this.$message("视频大小不能超过50MB");
return false;
}
this.isShowUploadVideo = false;
// 校检文件类型
if (this.fileType) {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
}
const isTypeOk = this.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
});
if (!isTypeOk) {
this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
return false;
}
}
const { sizeText, sizeLimit, } = this
if (file.size > (sizeLimit * 1000)) {
this.$alert(`图片大小不能超过${sizeText}`)
return false;
}
if (this.uploadDomain) {
return true
}
const { name } = file
let path = `${dayjs().format('
YYYY
/
MM
/
DD
')}/${dayjs().format('
YYYYMMDDHHmmss
')}${Math.ceil(Math.random() * 1000000 % 1000000)}`
// console.log('
path
', path)
path = path.replace('
(
', '')
path = path.replace('
)
', '')
path = path.replace('
', '')
this.putObject(path, file)
// try {
// // 获取七牛云token
// const res = await this.$request.post('
/
admin
/
getQiniuToken
')
// this.qiniuToken = res.data.token
// return res.data.token
// } catch (err) {
// this.$message('
请求出错
')
// return false
// }
},
token: () => {
const { source } = this
let token = ''
switch (source) {
case '
local
': // 本地点上传
token = getToken()
this.token = token
break
}
},
}
}
},
},
handler() {
handler() {
return {
return {
upload
:
(
key
)
=>
{
// 图片上传成功回调
this
.
list
.
push
(
key
)
imageSuccess: (data,file) => {
},
const link = data.url;
choiceImg
:
(
index
)
=>
{
// this.data = url
if
(
!
this
.
edit
)
{
let attr =
{
return
url:link,
}
}
this
.
index
=
index
this.isShowUploadVideo = true;
this
.
$refs
.
uploadImg
.
show
()
this.videoFlag = false;
this.videoUploadPercent = 0;
this.data = this.index != null ? this.data.splice(this.index,1,attr) : this.data.push(attr);
this.$refs.upload.clearFiles();
},
//进度条
uploadVideoProcess:(event, file, fileList)=>{
this.videoFlag = true;
this.videoUploadPercent = file.percentage.toFixed(0) * 1;
},
//获取索引
getIndex:(index)=>{
this.index = index;
},
// 文件个数超出
handleExceed:(file,fileList)=>{
this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
},
handlePreview:(file)=>{
// console.log(file);
},
},
confirm
:
(
data
)
=>
{
//过滤数组
const
{
index
,
limit
}
=
this
listByString:(data)=>{
let
{
list
}
=
this
let attr = '';
if
(
index
===
''
)
{
if(typeof data == '
object
' || typeof data == '
array
'){
list
=
list
.
concat
(
data
)
data.map((item)=>{
}
else
{
attr+=item+'
/
'
list
.
splice
(
index
,
1
,
data
)
})
attr = attr.slice(0,attr.length-1);
}
}
this
.
list
=
list
.
slice
(
0
,
limit
)
return attr
const
value
=
this
.
init
().
value
(
this
.
list
)
},
this
.
$emit
(
'input'
,
value
)
initVideo:()=>{
//初始化视频方法
let myPlayer = this.$video(myVideo, {
//是否显示控制栏
controls: true,
//是否自动播放,muted:静音播放
autoplay: false,
//是否静音播放
muted:false,
//是否流体自适应容器宽高
fluid:true,
});
},
// 获取文件名称
getFileName:(name)=>{
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
} else {
return "";
}
},
del: () => {
this.data = ''
this.$emit('
delete
')
},
},
}
}
},
},
/**
* key 文件吗
* data 文件
*/
async putObject(key, data) {
try {
console.log('
file
', data)
console.log('
OssClient
', this.OssClient)
const { OssClient } = this
// object-key可以自定义为文件名(例如file.txt)或目录(例如abc/test/file.txt)的形式,实现将文件上传至当前Bucket或Bucket下的指定目录。
const result = await OssClient.put(key, data)
const { name } = result
this.data = name
this.$emit('
on
-
confirm
', this.data)
} catch (e) {
console.log('
error
', e)
}
}
},
},
}
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.upload-imags-list
{
.upload-file-uploader
{
font-size
:
0
;
margin-bottom
:
5px
;
.avatar-uploader
{
}
display
:
block
;
.upload-file-list
.el-upload-list__item
{
display
:
inline-block
;
border
:
1px
solid
#e4e7ed
;
margin-right
:
5px
;
line-height
:
2
;
margin-bottom
:
5px
;
margin-bottom
:
10px
;
float
:
left
;
position
:
relative
;
.img-box
{
}
.upload-file-list
.ele-upload-list__item-content
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
color
:
inherit
;
}
.video-avatar
{
margin-top
:
-16
.5px
;
}
.ele-upload-list__item-content-action
.el-link
{
margin-right
:
10px
;
}
.avatar-uploader
{
display
:
block
;
margin-bottom
:
2px
;
margin-right
:
2px
;
position
:
relative
;
line-height
:
0
;
.avatar-uploader-icon
{
width
:
100%
;
height
:
100%
;
font-size
:
16px
;
}
.avatar
{
width
:
100%
;
height
:
100%
;
margin-right
:
5px
;
border
:
1px
solid
rgb
(
241
,
241
,
241
);
box-sizing
:
border-box
;
&
.avatar-uploader-icon
{
}
.delete-icon
{
position
:
relative
;
top
:
0
;
float
:
right
;
font-size
:
16px
;
background
:
red
;
color
:
white
;
border-radius
:
4px
;
z-index
:
1000
;
cursor
:
pointer
;
}
.img
{
background-position
:
center
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
width
:
100%
;
width
:
100%
;
height
:
100%
;
height
:
100%
;
box-sizing
:
border-box
;
border-radius
:
4px
;
position
:
relative
;
.delete-icon
{
position
:
absolute
;
top
:
0
;
right
:
0
;
font-size
:
16px
;
background
:
red
;
color
:
white
;
border-radius
:
4px
;
z-index
:
100
;
cursor
:
pointer
;
}
.img
{
background-position
:
center
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
width
:
100%
;
height
:
100%
;
}
}
}
.avatar-uploader-icon
{
.upload-label
{
box-sizing
:
border-box
;
font-size
:
14px
;
}
.upload-tips
{
display
:
block
;
font-size
:
12px
;
}
}
}
}
}
}
</
style
>
</
style
>
packages/form/upload/src/upload.vue
View file @
0f9fe073
<
template
>
<
template
>
<div
class=
"upload-imags-list"
>
<div>
<div
class=
"img-box"
>
<UploadImageList
<UploadImg
v-if=
"type === 'image'"
v-model=
"list"
:label=
"label"
:multiple=
"multiple"
:limit=
"limit"
:show-del=
"false"
:edit=
"edit"
:tips=
"tips"
v-model=
"value"
:limit=
"limit"
:showDel=
"showDel"
:uploadType=
"uploadType"
:dialog=
"dialog"
:showDel=
"showDel"
:data-type=
"dataType"
:label=
"label"
:multiple=
"multiple"
:source=
"source"
:tips=
"tips"
:size=
"size"
:source=
"source"
:edit=
"edit"
:size=
"size"
:dialog=
"dialog"
/>
class=
"uploadImg"
/>
<UploadFile
v-if=
"type === 'file'"
</div>
:label=
"label"
:limit=
"limit"
v-model=
"value"
:edit=
"edit"
:dialog=
"dialog"
:data-type=
"dataType"
:tips=
"tips"
:source=
"source"
:size=
"size"
/>
<UploadVideo
v-if=
"type === 'video'"
:label=
"label"
:limit=
"limit"
:edit=
"edit"
:showDel=
"showDel"
v-model=
"value"
:dialog=
"dialog"
:data-type=
"dataType"
:tips=
"tips"
:source=
"source"
:size=
"size"
/>
<UploadAudio
v-if=
"type === 'audio'"
:label=
"label"
:limit=
"limit"
:edit=
"edit"
:showDel=
"showDel"
v-model=
"value"
:dialog=
"dialog"
:data-type=
"dataType"
:tips=
"tips"
:source=
"source"
:size=
"size"
/>
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
>
import
UploadImg
from
'./base-upload'
import
UploadImageList
from
'./upload-img-list'
import
UploadFile
from
'./upload-file'
export
default
{
import
UploadVideo
from
'./upload-video'
name
:
'Upload'
,
import
UploadAudio
from
'./upload-audio'
export
default
{
name
:
'CyUpload'
,
components
:
{
components
:
{
UploadImg
,
UploadImageList
,
UploadFile
,
UploadVideo
,
UploadAudio
,
},
},
props
:
{
props
:
{
// 上传类型,可选值,image,file,video,audio
type
:
{
type
:
String
,
default
:
'image'
,
},
label
:
{
label
:
{
type
:
String
,
type
:
String
,
default
:
'上传'
,
default
:
'上传'
,
},
},
limit
:
{
//
文件
上传数量限制,默认10
limit
:
{
//
图片
上传数量限制,默认10
type
:
Number
,
type
:
Number
,
default
:
10
,
default
:
1
,
},
//是否删除
showDel
:{
type
:
Boolean
,
default
:
true
,
},
//上传类型
uploadType
:{
type
:
String
,
default
:
'file'
},
},
value
:
{
value
:
{
type
:
[
String
,
Object
,
Array
],
type
:
[
String
,
Object
,
Array
],
default
:
null
,
default
:
null
,
},
// 是否多选
multiple
:
{
type
:
Boolean
,
default
:
false
,
},
},
edit
:
{
// 是否可编辑
edit
:
{
// 是否可编辑
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
// 是否使用
文件
库组件
// 是否使用
图片
库组件
dialog
:
{
dialog
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
true
,
default
:
true
,
},
},
//是否
多选文件
//是否
显示可删除
multiple
:
{
showDel
:
{
type
:
Boolean
,
type
:
Boolean
,
default
:
false
default
:
true
,
},
},
//
文件
列表数据结构,json,array,string
//
图片
列表数据结构,json,array,string
dataType
:
{
dataType
:
{
type
:
String
,
type
:
String
,
default
:
'string'
,
default
:
'string'
,
...
@@ -83,148 +120,6 @@ export default{
...
@@ -83,148 +120,6 @@ export default{
type
:
Number
,
type
:
Number
,
default
:
100
,
default
:
100
,
},
},
//上传组件风格
uploadStyle
:{
type
:
String
,
default
:
'icon'
},
//文件样式
listType
:{
type
:
String
,
default
:
''
},
},
data
()
{
return
{
dialog_visible
:
false
,
qiniuToken
:
''
,
list
:
[],
// 文件列表
index
:
''
,
}
},
watch
:
{
value
(
value
)
{
this
.
list
=
this
.
init
().
data
(
value
)
},
list
(
value
)
{
const
data
=
this
.
init
().
value
(
value
)
this
.
$emit
(
'input'
,
data
)
},
},
created
()
{
this
.
list
=
this
.
init
().
data
(
this
.
value
)
},
methods
:
{
init
()
{
return
{
// 初始化返回数据
value
:
(
list
)
=>
{
let
value
=
''
const
{
dataType
}
=
this
switch
(
dataType
)
{
case
'string'
:
// 字符串类型以逗号隔开
value
=
list
.
join
(
','
)
break
case
'json'
:
value
=
JSON
.
stringify
(
list
)
break
case
'array'
:
value
=
list
break
}
return
value
},
// 初始化数据
data
:
(
value
)
=>
{
let
data
=
''
const
{
dataType
}
=
this
if
(
value
!=
null
){
switch
(
dataType
)
{
case
'string'
:
// 字符串类型以逗号隔开
data
=
value
?
value
.
split
(
','
)
:
[]
break
case
'json'
:
data
=
value
?
JSON
.
parse
(
value
)
:
[]
break
case
'array'
:
data
=
value
break
}
}
data
=
Array
.
isArray
(
data
)
?
data
:
[]
return
data
},
}
},
handler
()
{
return
{
upload
:
(
key
)
=>
{
this
.
list
.
push
(
key
)
},
choiceImg
:
(
index
)
=>
{
if
(
!
this
.
edit
)
{
return
}
this
.
index
=
index
this
.
$refs
.
uploadImg
.
show
()
},
confirm
:
(
data
)
=>
{
const
{
index
,
limit
}
=
this
let
{
list
}
=
this
if
(
index
===
''
)
{
list
=
list
.
concat
(
data
)
}
else
{
list
.
splice
(
index
,
1
,
data
)
}
this
.
list
=
list
.
slice
(
0
,
limit
)
const
value
=
this
.
init
().
value
(
this
.
list
)
this
.
$emit
(
'input'
,
value
)
},
}
},
},
},
}
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
.upload-imags-list
{
font-size
:
0
;
.avatar-uploader
{
display
:
block
;
display
:
inline-block
;
margin-right
:
5px
;
margin-bottom
:
5px
;
float
:
left
;
.img-box
{
width
:
100%
;
height
:
100%
;
box-sizing
:
border-box
;
border-radius
:
4px
;
position
:
relative
;
.delete-icon
{
position
:
absolute
;
top
:
0
;
right
:
0
;
font-size
:
16px
;
background
:
red
;
color
:
white
;
border-radius
:
4px
;
z-index
:
100
;
cursor
:
pointer
;
}
.img
{
background-position
:
center
;
background-size
:
contain
;
background-repeat
:
no-repeat
;
width
:
100%
;
height
:
100%
;
}
}
.avatar-uploader-icon
{
box-sizing
:
border-box
;
}
}
}
</
style
>
packages/layout/src/layout-form.vue
View file @
0f9fe073
...
@@ -48,7 +48,7 @@
...
@@ -48,7 +48,7 @@
<cyupload
<cyupload
:ref=
"form[item.field]"
:ref=
"form[item.field]"
v-model=
"form[item.field]"
v-model=
"form[item.field]"
:
uploadT
ype=
"item.type"
:
t
ype=
"item.type"
:limit=
"(item.upload && item.upload.limit) || 1"
:limit=
"(item.upload && item.upload.limit) || 1"
:size=
"(item.upload && item.upload.size) || 100"
:size=
"(item.upload && item.upload.size) || 100"
:dataType=
"(item.upload && item.upload.dataType) || 'array'"
:dataType=
"(item.upload && item.upload.dataType) || 'array'"
...
@@ -58,6 +58,7 @@
...
@@ -58,6 +58,7 @@
:multiple=
"(item.upload && item.upload.multiple) || false"
:multiple=
"(item.upload && item.upload.multiple) || false"
:tips=
"(item.upload && item.upload.tips) || ''"
:tips=
"(item.upload && item.upload.tips) || ''"
:source=
"(item.upload && item.upload.source) || ''"
:source=
"(item.upload && item.upload.source) || ''"
:fileType=
"(item.upload && item.upload.fileType)"
/>
/>
<!--
<cy-upload
<!--
<cy-upload
:ref=
"form[item.field]"
:ref=
"form[item.field]"
...
@@ -109,12 +110,10 @@
...
@@ -109,12 +110,10 @@
<
script
>
<
script
>
import
request
from
'@/utils/request'
import
request
from
'@/utils/request'
import
{
getDicts
}
from
'@/api/system/dict/data'
import
{
getDicts
}
from
'@/api/system/dict/data'
import
uploadImg
from
'../../form/upload/src/upload-img'
import
uploadFile
from
'../../form/upload/src/upload-file'
import
Cyupload
from
'../../form/upload/src/upload'
import
Cyupload
from
'../../form/upload/src/upload'
export
default
{
export
default
{
components
:{
components
:{
uploadImg
,
uploadFile
,
Cyupload
Cyupload
},
},
props
:
{
props
:
{
primaryKey
:
{
primaryKey
:
{
...
@@ -260,8 +259,8 @@ export default {
...
@@ -260,8 +259,8 @@ export default {
fieldList
.
forEach
(
item
=>
{
fieldList
.
forEach
(
item
=>
{
const
{
field
,
type
}
=
item
const
{
field
,
type
}
=
item
let
{
value
,
placeholder
,
attr
,
checkboxGroup
,
dict
,
options
}
=
item
let
{
value
,
placeholder
,
attr
,
checkboxGroup
,
dict
,
options
}
=
item
console
.
log
(
options
);
//
console.log(options);
console
.
log
(
value
);
//
console.log(value);
attr
=
attr
||
{}
attr
=
attr
||
{}
checkboxGroup
=
checkboxGroup
||
{}
checkboxGroup
=
checkboxGroup
||
{}
if
(
!
placeholder
)
{
if
(
!
placeholder
)
{
...
...
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