Commit 0f9fe073 authored by 廖伟胜's avatar 廖伟胜

修改上传文件组件结构

parent 1b956aa6
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) {
......
<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)=>{
......
<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: true, default: false,
}, },
//上传类型 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,
}, },
//是否多选文件 //上传组件风格
multiple:{ uploadStyle:{
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>
...@@ -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)"/>
<uploadimg <UploadImg
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: 'CyUploadImgList',
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: 10, 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;
......
<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 {
dialog_visible: false, data: '',
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>
<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>
<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>
...@@ -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]"
:uploadType="item.type" :type="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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment