Commit 1b956aa6 authored by 廖伟胜's avatar 廖伟胜

修改文件组件(差音频组件)

parent 5ca77c4e
<template>
<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" >
<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 :style="style" class="avatar" >
<i v-if="showDel" class="el-icon-close delete-icon" title="删除" @click.stop="data.splice(index, 1)"/>
<div :style="`background-image:url(${item.url})`" class="img"/>
</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>
<el-progress v-if="videoFlag == true"
type="circle"
:percentage="videoUploadPercent"
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>
</i>
</el-upload>
<p class="Upload_pictures">
<span></span>
<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>
</div>
</template>
<script>
import dayjs from 'dayjs'
import { mapState } from 'vuex'
import { getToken } from '@/utils/auth' // 验权
export default{
props: {
//上传文字描述
label: {
type: String,
default: '上传',
},
//上传类型
uploadType:{
type: String,
default: 'image'
},
//上传值
value: {
type: [String, Object, Array],
default: '',
},
// 是否多选
multiple: {
type: Boolean,
default: false,
},
limit: { // 图片上传数量限制,默认10
type: Number,
default: 10,
},
// 组件大小(px)
size: {
type: [String, Number],
default: 100,
},
// 图片大小限制(kb)
sizeLimit: {
type: Number,
default: 3000,
},
//显示删除
showDel: {
type: Boolean,
default: true,
},
// 上传图片后是否显示图
show: {
type: Boolean,
default: true,
},
//上传组件风格
uploadStyle:{
type:String,
default:'icon'
},
//文件样式
listType:{
type:String,
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() {
return {
index:null,
data: '',
qiniuToken: '',
baseUrl: process.env.VUE_APP_BASE_API,
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: {
value() {
this.data = this.value
},
data() {
this.$emit('input', this.data)
this.$emit('on-success', this.data)
},
},
created() {
this.index = null;
this.data = this.value
this.init().token()
// if(this.uploadType === 'video'){
// this.handler().initVideo();
// }
},
methods: {
init() {
return {
// 上传前置操作
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) {
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() {
return {
// 图片上传成功回调
imageSuccess: (data,file) => {
const link = data.url;
// this.data = url
let attr = {
url:link,
}
let attrs = {
name:file.name,
url:link
}
if(this.uploadType === 'video'){
this.isShowUploadVideo = true;
this.videoFlag = false;
this.videoUploadPercent = 0;
}else if(this.uploadType == 'file'){
this.data = this.data.push(attrs);
return;
}
this.data = this.index != null ? this.data.splice(this.index,1,attr) : this.data.push(attr);
this.$refs.upload.clearFiles();
},
//进度条
uploadVideoProcess:(event, file, fileList)=>{
if(this.uploadType === 'video'){
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);
},
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>
<style lang="scss" scoped>
.upload-file-uploader {
margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
border: 1px solid #e4e7ed;
line-height: 2;
margin-bottom: 10px;
position: relative;
}
.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%;
height: 100%;
}
.upload-label{
font-size: 14px;
}
.upload-tips{
display: block;
font-size: 12px;
}
}
}
</style>
<template> <template>
<div> <div class="upload-imags-list">
文件上传 <div class="img-box" >
<UploadImg
v-model="list"
:multiple="multiple"
: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> </div>
</template> </template>
<script> <script>
export default { import UploadImg from './base-upload'
export default{
name: 'CyUploadImgList',
components: {
UploadImg,
},
props: {
label: {
type: String,
default: '上传',
},
limit: { // 文件上传数量限制,默认10
type: Number,
default: 10,
},
//是否删除
showDel:{
type: Boolean,
default: true,
},
//上传类型
uploadType:{
type: String,
default: 'file'
},
value: {
type: [String, Object, Array],
default: null,
},
edit: { // 是否可编辑
type: Boolean,
default: true,
},
// 是否使用文件库组件
dialog: {
type: Boolean,
default: true,
},
//是否多选文件
multiple:{
type: Boolean,
default:false
},
// 文件列表数据结构,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: 100,
},
//上传组件风格
uploadStyle:{
type:String,
default:'icon'
},
//文件样式
listType:{
type:String,
default:''
},
},
data() { data() {
return {} 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: { 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
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>
...@@ -3,14 +3,18 @@ ...@@ -3,14 +3,18 @@
<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[index]" v-model="list"
: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" >
...@@ -22,6 +26,10 @@ ...@@ -22,6 +26,10 @@
: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>
...@@ -32,7 +40,7 @@ ...@@ -32,7 +40,7 @@
import UploadImg from './upload-img' import UploadImg from './upload-img'
export default{ export default{
name: 'CyUpload', name: 'CyUploadImg',
components: { components: {
UploadImg, UploadImg,
}, },
...@@ -43,7 +51,7 @@ export default{ ...@@ -43,7 +51,7 @@ export default{
}, },
limit: { // 图片上传数量限制,默认10 limit: { // 图片上传数量限制,默认10
type: Number, type: Number,
default: 1, default: 10,
}, },
value: { value: {
type: null, type: null,
...@@ -76,6 +84,16 @@ export default{ ...@@ -76,6 +84,16 @@ export default{
type: Number, type: Number,
default: 100, default: 100,
}, },
//上传组件风格
uploadStyle:{
type:String,
default:'icon'
},
//文件样式
listType:{
type:String,
default:''
},
}, },
data() { data() {
return { return {
...@@ -95,7 +113,7 @@ export default{ ...@@ -95,7 +113,7 @@ export default{
}, },
}, },
created() { created() {
this.list = this.init().data(this.value) this.list = this.init().data(this.value);
}, },
methods: { methods: {
init() { init() {
......
<template> <template>
<div> <div class="upload-imags-list">
<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" > <div class="img-box" >
<div v-if="data && show" :style="style" class="avatar"> <UploadImg
<i v-if="showDel" class="el-icon-close delete-icon" title="删除" @click.stop="handler().del()"/> v-model="list"
<div :style="`background-image:url(${src})`" class="img"/> :multiple="multiple"
: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 dayjs from 'dayjs' import UploadImg from './base-upload'
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: '上传',
}, },
value: { limit: { // 图片上传数量限制,默认10
type: String, type: Number,
default: '', default: 10,
},
// 是否多选
multiple: {
type: Boolean,
default: false,
}, },
// 组件大小(px) value: {
size: { type: [String, Object, Array],
type: [String, Number], default: null,
default: 100,
}, },
// 图片大小限制(kb) //上传类型
sizeLimit: { uploadType:{
type: Number, type: String,
default: 3000, default: 'image'
}, },
showDel: { edit: { // 是否可编辑
type: Boolean, type: Boolean,
default: true, default: true,
}, },
// 上传图片后是否显示图 // 是否使用图片库组件
show: { dialog: {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
// 图片列表数据结构,json,array,string
dataType: {
type: String,
default: 'string',
},
tips: { tips: {
type: String, type: String,
default: '', default: '',
...@@ -60,216 +67,150 @@ export default{ ...@@ -60,216 +67,150 @@ 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 {
data: '', dialog_visible: false,
qiniuToken: '', qiniuToken: '',
imgDomain: '', list: [], // 文件列表
headers: { index: '',
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.data = this.value this.list = this.init().data(value)
}, },
data() { list(value) {
this.$emit('input', this.data) const data = this.init().value(value)
this.$emit('on-success', this.data) this.$emit('input', data)
}, },
}, },
created() { created() {
this.data = this.value this.list = this.init().data(this.value)
this.init().token()
}, },
methods: { methods: {
init() { init() {
return { return {
// 上传前置操作 // 初始化返回数据
beforeUpload: async(file) => { value: (list) => {
const { sizeText, sizeLimit, } = this let value = ''
if (file.size > (sizeLimit * 1000)) { const { dataType } = this
this.$alert(`图片大小不能超过${sizeText}`) switch(dataType) {
return case 'string': // 字符串类型以逗号隔开
} value = list.join(',')
if (this.uploadDomain) { break
return true case 'json':
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: () => { // 初始化数据
const { source } = this data: (value) => {
let token = '' let data = ''
switch (source) { const { dataType } = this
case 'local': // 本地点上传 switch(dataType) {
token = getToken() case 'string': // 字符串类型以逗号隔开
this.token = token data = value ? value.split(',') : []
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) => {
imageSuccess: ({ data }) => { this.list.push(key)
const { url } = data },
this.data = url choiceImg: (index) => {
if (!this.edit) {
return
}
this.index = index
this.$refs.uploadImg.show()
}, },
del: () => { confirm: (data) => {
this.data = '' const { index, limit } = this
this.$emit('delete') 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>
.avatar-uploader{ .upload-imags-list{
display: block; font-size: 0;
margin-bottom: 2px; .avatar-uploader{
margin-right: 2px; display: block;
position: relative; display: inline-block;
line-height: 0; margin-right: 5px;
.avatar-uploader-icon{ margin-bottom: 5px;
width: 100%; float: left;
height: 100%; .img-box{
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%;
}
} }
.upload-label{ .avatar-uploader-icon{
font-size: 14px; box-sizing: border-box;
}
.upload-tips{
display: block;
font-size: 12px;
} }
} }
} }
</style> </style>
<template>
<div class="upload-imags-list">
<div class="img-box" >
<UploadImg
v-model="list"
:multiple="multiple"
: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>
</template>
<script>
import UploadImg from './base-upload'
export default{
name: 'CyUploadImgList',
components: {
UploadImg,
},
props: {
label: {
type: String,
default: '上传',
},
limit: { // 视频上传数量限制,默认10
type: Number,
default: 10,
},
//上传类型
uploadType:{
type: String,
default: 'video'
},
value: {
type: [String, Object, Array],
default: null,
},
edit: { // 是否可编辑
type: Boolean,
default: true,
},
// 是否使用视频库组件
dialog: {
type: Boolean,
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:{
type:String,
default:'icon'
},
//文件样式
listType:{
type:String,
default:''
},
},
data() {
return {
dialog_visible: false,
qiniuToken: '',
list: [], // 文件列表
index: '',
}
},
watch: {
value(value) {
this.list = 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
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>
<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>
<template>
<div class="upload-imags-list">
<div class="img-box" >
<UploadImg
v-model="list"
:multiple="multiple"
: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>
</template>
<script>
import UploadImg from './base-upload'
export default{
name: 'Upload',
components: {
UploadImg,
},
props: {
label: {
type: String,
default: '上传',
},
limit: { // 文件上传数量限制,默认10
type: Number,
default: 10,
},
//是否删除
showDel:{
type: Boolean,
default: true,
},
//上传类型
uploadType:{
type: String,
default: 'file'
},
value: {
type: [String, Object, Array],
default: null,
},
edit: { // 是否可编辑
type: Boolean,
default: true,
},
// 是否使用文件库组件
dialog: {
type: Boolean,
default: true,
},
//是否多选文件
multiple:{
type: Boolean,
default:false
},
// 文件列表数据结构,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: 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>
<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>
...@@ -17,14 +17,55 @@ ...@@ -17,14 +17,55 @@
v-model="form[item.field]"> v-model="form[item.field]">
<el-radio v-for="(option, optionIndex) in item.options" :key="optionIndex" :label="option.value">{{ option.label }}</el-radio> <el-radio v-for="(option, optionIndex) in item.options" :key="optionIndex" :label="option.value">{{ option.label }}</el-radio>
</el-radio-group> </el-radio-group>
<el-checkbox v-else-if="item.type === 'checkbox'"
v-model="form[item.field]"
:label="item.label" :border="item.border != null ? item.border : false"
:size="item.size != null ? item.size : null"
:name="item.name" :disabled="item.disabled != null ? item.disabled : false"></el-checkbox>
<el-checkbox-group
v-else-if="item.type === 'checkbox-group'"
v-model="form[item.field]"
:size="item.size != null ? item.size : null"
:min="item.checkboxGroup.min != null ? item.checkboxGroup.min : 0"
:max="item.checkboxGroup.max != null ? item.checkboxGroup.max : 100"
>
<el-checkbox v-show="item.checkboxGroup.type != 'button'"
v-for="(option, optionIndexs) in item.options"
:disabled="option.disabled != null ? option.disabled : false"
:border="option.border != null ? option.border : false"
:key="optionIndexs+'checkbox'"
:label="option.label"
:name="option.name"/>
<el-checkbox-button v-show="item.checkboxGroup.type == 'button'"
v-for="(option, optionIndex) in item.options"
:disabled="option.disabled != null ? option.disabled : false"
:border="option.border != null ? option.border : false"
:key="optionIndex+'checkbox-button'"
:label="option.label"
:name="option.name"/>
</el-checkbox-group>
<div v-else-if="handler().uploadType(item)" style="display: inline-block;"> <div v-else-if="handler().uploadType(item)" style="display: inline-block;">
<cy-upload <cyupload
:ref="form[item.field]"
v-model="form[item.field]"
:uploadType="item.type"
:limit="(item.upload && item.upload.limit) || 1"
:size="(item.upload && item.upload.size) || 100"
:dataType="(item.upload && item.upload.dataType) || 'array'"
:edit="(item.upload && item.upload.edit) || true"
:showDel="(item.upload && item.upload.showDel) || true"
:label="(item.upload && item.upload.label) || ''"
:multiple="(item.upload && item.upload.multiple) || false"
:tips="(item.upload && item.upload.tips) || ''"
:source="(item.upload && item.upload.source) || ''"
/>
<!-- <cy-upload
:ref="form[item.field]" :ref="form[item.field]"
:type="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) || 'string'" :dataType="(item.upload && item.upload.dataType) || 'string'"
v-model="form[item.field]" /> v-model="form[item.field]" /> -->
</div> </div>
<el-date-picker <el-date-picker
v-else-if="item.type === 'date'" v-else-if="item.type === 'date'"
...@@ -33,6 +74,7 @@ ...@@ -33,6 +74,7 @@
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd"
class="input" class="input"
type="date"/> type="date"/>
<slot v-else-if="item.type == 'slot'" :name="item.slotName" :field="item" :form="form" :index="index"/> <slot v-else-if="item.type == 'slot'" :name="item.slotName" :field="item" :form="form" :index="index"/>
<el-input <el-input
v-else v-else
...@@ -67,7 +109,13 @@ ...@@ -67,7 +109,13 @@
<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'
export default { export default {
components:{
uploadImg,uploadFile,Cyupload
},
props: { props: {
primaryKey: { primaryKey: {
type: String, type: String,
...@@ -89,6 +137,9 @@ export default { ...@@ -89,6 +137,9 @@ export default {
}, },
loading: false, // 控制表格的加载状态 loading: false, // 控制表格的加载状态
saveLoading: false, // 保存状态 saveLoading: false, // 保存状态
video:[{url:"https://vd4.bdstatic.com/mda-kb5mi75zvcx94wir/v1-cae/sc/mda-kb5mi75zvcx94wir.mp4?v_from_s=hkapp-haokan-hnb&auth_key=1644909031-0-0-fc3f17824543985f4541f98638fb95a9&bcevod_channel=searchbox_feed&pd=1&pt=3&logid=2431577623&vid=4581260007125923518&abtest=&klogid=2431577623"},{url:"https://vd4.bdstatic.com/mda-kb5mi75zvcx94wir/v1-cae/sc/mda-kb5mi75zvcx94wir.mp4?v_from_s=hkapp-haokan-hnb&auth_key=1644909031-0-0-fc3f17824543985f4541f98638fb95a9&bcevod_channel=searchbox_feed&pd=1&pt=3&logid=2431577623&vid=4581260007125923518&abtest=&klogid=2431577623"}],
fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}],
list: [{url: 'https://lmg.jj20.com/up/allimg/4k/s/01/210924112Q25J9-0-lp.jpg'},{ url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
} }
}, },
computed: { computed: {
...@@ -207,9 +258,12 @@ export default { ...@@ -207,9 +258,12 @@ export default {
return return
} }
fieldList.forEach(item => { fieldList.forEach(item => {
const { field, type, } = item const { field, type } = item
let { value, placeholder, attr, dict, } = item let { value, placeholder, attr, checkboxGroup,dict,options } = item
console.log(options);
console.log(value);
attr = attr || {} attr = attr || {}
checkboxGroup = checkboxGroup || {}
if (!placeholder) { if (!placeholder) {
switch (type) { switch (type) {
case 'select': case 'radio': case 'select': case 'radio':
...@@ -235,12 +289,13 @@ export default { ...@@ -235,12 +289,13 @@ export default {
break break
} }
} }
value = value || '' value = type == 'checkbox-group' ? (value || []) : (value || '')
// value = value || ''
attr.placeholder = placeholder attr.placeholder = placeholder
item.attr = attr item.attr = attr
item.checkboxGroup = checkboxGroup
item.change = item.change || (() => {}) item.change = item.change || (() => {})
form[field] = value form[field] = value
}) })
form[primaryKey] = data[primaryKey] form[primaryKey] = data[primaryKey]
......
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