parent
1c45eba3d4
commit
1ee7f009e1
|
@ -5,8 +5,24 @@ export default {
|
||||||
upload: {
|
upload: {
|
||||||
url: `${config.API_URL}/upload`,
|
url: `${config.API_URL}/upload`,
|
||||||
name: "文件上传",
|
name: "文件上传",
|
||||||
post: async function(data){
|
post: async function(data, config={}){
|
||||||
return await http.post(this.url, data);
|
return await http.post(this.url, data, config);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
file: {
|
||||||
|
menu: {
|
||||||
|
url: `${config.API_URL}/file/menu`,
|
||||||
|
name: "获取文件分类",
|
||||||
|
get: async function(){
|
||||||
|
return await http.get(this.url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
url: `${config.API_URL}/file/list`,
|
||||||
|
name: "获取文件列表",
|
||||||
|
get: async function(params){
|
||||||
|
return await http.get(this.url, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import http from "@/utils/request"
|
||||||
export default {
|
export default {
|
||||||
menu: {
|
menu: {
|
||||||
myMenus: {
|
myMenus: {
|
||||||
url: `${config.API_URL}/system/menu/my/1.2.6`,
|
url: `${config.API_URL}/system/menu/my/1.2.8`,
|
||||||
name: "获取我的菜单",
|
name: "获取我的菜单",
|
||||||
get: async function(){
|
get: async function(){
|
||||||
return await http.get(this.url);
|
return await http.get(this.url);
|
||||||
|
|
|
@ -0,0 +1,283 @@
|
||||||
|
<!--
|
||||||
|
* @Descripttion: 资源文件选择器
|
||||||
|
* @version: 1.0
|
||||||
|
* @Author: sakuya
|
||||||
|
* @Date: 2021年10月11日16:01:40
|
||||||
|
* @LastEditors:
|
||||||
|
* @LastEditTime:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="sc-file-select">
|
||||||
|
<div class="sc-file-select__side" v-loading="menuLoading">
|
||||||
|
<div class="sc-file-select__side-menu">
|
||||||
|
<el-tree ref="group" class="menu" :data="menu" :node-key="treeProps.key" :props="treeProps" :current-node-key="menu.length>0?menu[0][treeProps.key]:''" highlight-current @node-click="groupClick">
|
||||||
|
<template #default="{ node }">
|
||||||
|
<span class="el-tree-node__label">
|
||||||
|
<i class="el-icon-folder icon"></i>{{node.label}}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
<div class="sc-file-select__side-msg" v-if="multiple">
|
||||||
|
已选择 <b>{{value.length}}</b> / <b>{{max}}</b> 项
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sc-file-select__files" v-loading="listLoading">
|
||||||
|
<div class="sc-file-select__top">
|
||||||
|
<div class="upload" v-if="!hideUpload">
|
||||||
|
<el-upload class="sc-file-select__upload" action="" multiple :show-file-list="false" :accept="accept" :on-change="uploadChange" :before-upload="uploadBefore" :on-progress="uploadProcess" :on-success="uploadSuccess" :on-error="uploadError" :http-request="uploadRequest">
|
||||||
|
<el-button type="primary" icon="el-icon-upload2">本地上传</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<span class="tips"><i class="el-icon-warning-outline"></i>大小不超过{{maxSize}}MB</span>
|
||||||
|
</div>
|
||||||
|
<div class="keyword">
|
||||||
|
<el-input v-model="keyword" prefix-icon="el-icon-search" placeholder="文件名搜索" clearable @keyup.enter="search" @clear="search"></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sc-file-select__list">
|
||||||
|
<el-scrollbar ref="scrollbar">
|
||||||
|
<el-empty v-if="fileList.length==0 && data.length==0" description="无数据" :image-size="80"></el-empty>
|
||||||
|
<div v-for="(file, index) in fileList" :key="index" class="sc-file-select__item">
|
||||||
|
<div class="sc-file-select__item__file">
|
||||||
|
<div class="sc-file-select__item__upload">
|
||||||
|
<el-progress type="circle" :percentage="file.progress" :width="70"></el-progress>
|
||||||
|
</div>
|
||||||
|
<el-image :src="file.tempImg" fit="contain"></el-image>
|
||||||
|
</div>
|
||||||
|
<p>{{file.name}}</p>
|
||||||
|
</div>
|
||||||
|
<div v-for="item in data" :key="item[fileProps.key]" class="sc-file-select__item" :class="{active: value.includes(item[fileProps.url]) }" @click="select(item)">
|
||||||
|
<div class="sc-file-select__item__file">
|
||||||
|
<div class="sc-file-select__item__checkbox" v-if="multiple">
|
||||||
|
<i class="el-icon-check"></i>
|
||||||
|
</div>
|
||||||
|
<div class="sc-file-select__item__select" v-else>
|
||||||
|
<i class="el-icon-check"></i>
|
||||||
|
</div>
|
||||||
|
<div class="sc-file-select__item__box"></div>
|
||||||
|
<el-image v-if="_isImg(item[fileProps.url])" :src="item[fileProps.url]" fit="contain" lazy></el-image>
|
||||||
|
<div v-else class="item-file item-file-doc">
|
||||||
|
<i v-if="files[_getExt(item[fileProps.url])]" :class="files[_getExt(item[fileProps.url])].icon" :style="{color:files[_getExt(item[fileProps.url])].color}"></i>
|
||||||
|
<i v-else class="sc-icon-file-list-fill" style="color: #999;"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p :title="item[fileProps.fileName]">{{item[fileProps.fileName]}}</p>
|
||||||
|
</div>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
<div class="sc-file-select__pagination">
|
||||||
|
<el-pagination small background layout="prev, pager, next" :total="total" :page-size="pageSize" v-model:currentPage="currentPage" @current-change="reload"></el-pagination>
|
||||||
|
</div>
|
||||||
|
<div class="sc-file-select__do">
|
||||||
|
<slot name="do"></slot>
|
||||||
|
<el-button type="primary" :disabled="value.length<=0" @click="submit">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import config from "@/config/fileSelect"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
modelValue: null,
|
||||||
|
hideUpload: { type: Boolean, default: false },
|
||||||
|
multiple: { type: Boolean, default: false },
|
||||||
|
max: {type: Number, default: config.max},
|
||||||
|
onlyImage: { type: Boolean, default: false },
|
||||||
|
maxSize: {type: Number, default: config.maxSize},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
keyword: null,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0,
|
||||||
|
currentPage: 1,
|
||||||
|
data: [],
|
||||||
|
menu: [],
|
||||||
|
menuId: '',
|
||||||
|
value: this.multiple ? [] : '',
|
||||||
|
fileList: [],
|
||||||
|
accept: this.onlyImage ? "image/gif, image/jpeg, image/png" : "",
|
||||||
|
listLoading: false,
|
||||||
|
menuLoading: false,
|
||||||
|
treeProps: config.menuProps,
|
||||||
|
fileProps: config.fileProps,
|
||||||
|
files: config.files
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
multiple(){
|
||||||
|
this.value = this.multiple ? [] : ''
|
||||||
|
this.$emit('update:modelValue', JSON.parse(JSON.stringify(this.value)));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getMenu()
|
||||||
|
this.getData()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//获取分类数据
|
||||||
|
async getMenu(){
|
||||||
|
this.menuLoading = true
|
||||||
|
var res = await config.menuApiObj.get()
|
||||||
|
this.menu = res.data
|
||||||
|
this.menuLoading = false
|
||||||
|
},
|
||||||
|
//获取列表数据
|
||||||
|
async getData(){
|
||||||
|
this.listLoading = true
|
||||||
|
var reqData = {
|
||||||
|
[config.request.menuKey]: this.menuId,
|
||||||
|
[config.request.page]: this.currentPage,
|
||||||
|
[config.request.pageSize]: this.pageSize,
|
||||||
|
[config.request.keyword]: this.keyword
|
||||||
|
}
|
||||||
|
if(this.onlyImage){
|
||||||
|
reqData.type = 'image'
|
||||||
|
}
|
||||||
|
var res = await config.listApiObj.get(reqData)
|
||||||
|
var parseData = config.listParseData(res)
|
||||||
|
this.data = parseData.rows
|
||||||
|
this.total = parseData.total
|
||||||
|
this.listLoading = false
|
||||||
|
this.$refs.scrollbar.setScrollTop(0)
|
||||||
|
},
|
||||||
|
//树点击事件
|
||||||
|
groupClick(data){
|
||||||
|
this.menuId = data.id
|
||||||
|
this.currentPage = 1
|
||||||
|
this.keyword = null
|
||||||
|
this.getData()
|
||||||
|
},
|
||||||
|
//分页刷新表格
|
||||||
|
reload(){
|
||||||
|
this.getData()
|
||||||
|
},
|
||||||
|
search(){
|
||||||
|
this.currentPage = 1
|
||||||
|
this.getData()
|
||||||
|
},
|
||||||
|
select(item){
|
||||||
|
const itemUrl = item[this.fileProps.url]
|
||||||
|
if(this.multiple){
|
||||||
|
if(this.value.includes(itemUrl)){
|
||||||
|
this.value.splice(this.value.findIndex(f => f == itemUrl), 1)
|
||||||
|
}else{
|
||||||
|
this.value.push(itemUrl)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(this.value.includes(itemUrl)){
|
||||||
|
this.value = ''
|
||||||
|
}else{
|
||||||
|
this.value = itemUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit(){
|
||||||
|
const value = JSON.parse(JSON.stringify(this.value))
|
||||||
|
this.$emit('update:modelValue', value);
|
||||||
|
this.$emit('submit', value);
|
||||||
|
},
|
||||||
|
//上传处理
|
||||||
|
uploadChange(file, fileList){
|
||||||
|
file.tempImg = URL.createObjectURL(file.raw);
|
||||||
|
this.fileList = fileList
|
||||||
|
},
|
||||||
|
uploadBefore(file){
|
||||||
|
const maxSize = file.size / 1024 / 1024 < this.maxSize;
|
||||||
|
if (!maxSize) {
|
||||||
|
this.$message.warning(`上传文件大小不能超过 ${this.maxSize}MB!`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadRequest(param){
|
||||||
|
var apiObj = config.apiObj;
|
||||||
|
const data = new FormData();
|
||||||
|
data.append("file", param.file);
|
||||||
|
data.append([config.request.menuKey], this.menuId);
|
||||||
|
apiObj.post(data, {
|
||||||
|
onUploadProgress: e => {
|
||||||
|
param.onProgress(e)
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
param.onSuccess(res)
|
||||||
|
}).catch(err => {
|
||||||
|
param.onError(err)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
uploadProcess(event, file){
|
||||||
|
file.progress = Number((event.loaded / event.total * 100).toFixed(2))
|
||||||
|
},
|
||||||
|
uploadSuccess(res, file){
|
||||||
|
this.fileList.splice(this.fileList.findIndex(f => f.uid == file.uid), 1)
|
||||||
|
var response = config.uploadParseData(res);
|
||||||
|
this.data.unshift({
|
||||||
|
[this.fileProps.key]: response.id,
|
||||||
|
[this.fileProps.fileName]: response.fileName,
|
||||||
|
[this.fileProps.url]: response.url
|
||||||
|
})
|
||||||
|
if(!this.multiple){
|
||||||
|
this.value = response.url
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadError(err){
|
||||||
|
this.$notify.error({
|
||||||
|
title: '上传文件错误',
|
||||||
|
message: err
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//内置函数
|
||||||
|
_isImg(fileUrl){
|
||||||
|
const imgExt = ['.jpg', '.jpeg', '.png', '.gif', '.bmp']
|
||||||
|
const fileExt = fileUrl.substring(fileUrl.lastIndexOf("."))
|
||||||
|
return imgExt.indexOf(fileExt) != -1
|
||||||
|
},
|
||||||
|
_getExt(fileUrl){
|
||||||
|
return fileUrl.substring(fileUrl.lastIndexOf(".") + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.sc-file-select {display: flex;}
|
||||||
|
.sc-file-select__files {flex: 1;}
|
||||||
|
|
||||||
|
.sc-file-select__list {height:400px;}
|
||||||
|
.sc-file-select__item {display: inline-block;float: left;margin:0 15px 25px 0;width:110px;cursor: pointer;}
|
||||||
|
.sc-file-select__item__file {width:110px;height:110px;position: relative;}
|
||||||
|
.sc-file-select__item__file .el-image {width:110px;height:110px;}
|
||||||
|
.sc-file-select__item__box {position: absolute;top:0;right:0;bottom:0;left:0;border: 2px solid var(--el-color-success);z-index: 1;display: none;}
|
||||||
|
.sc-file-select__item__box::before {content: '';position: absolute;top:0;right:0;bottom:0;left:0;background: var(--el-color-success);opacity: 0.2;display: none;}
|
||||||
|
.sc-file-select__item:hover .sc-file-select__item__box {display: block;}
|
||||||
|
.sc-file-select__item.active .sc-file-select__item__box {display: block;}
|
||||||
|
.sc-file-select__item.active .sc-file-select__item__box::before {display: block;}
|
||||||
|
.sc-file-select__item p {margin-top: 10px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;-webkit-text-overflow:ellipsis;text-align: center;}
|
||||||
|
.sc-file-select__item__checkbox {position: absolute;width: 20px;height: 20px;top:7px;right:7px;z-index: 2;background: rgba(0,0,0,0.2);border: 1px solid #fff;display: flex;flex-direction: column;align-items: center;justify-content: center;}
|
||||||
|
.sc-file-select__item__checkbox i {font-size: 14px;color: #fff;font-weight: bold;display: none;}
|
||||||
|
.sc-file-select__item__select {position: absolute;width: 20px;height: 20px;top:0px;right:0px;z-index: 2;background: var(--el-color-success);display: none;flex-direction: column;align-items: center;justify-content: center;}
|
||||||
|
.sc-file-select__item__select i {font-size: 14px;color: #fff;font-weight: bold;}
|
||||||
|
.sc-file-select__item.active .sc-file-select__item__checkbox {background: var(--el-color-success);}
|
||||||
|
.sc-file-select__item.active .sc-file-select__item__checkbox i {display: block;}
|
||||||
|
.sc-file-select__item.active .sc-file-select__item__select {display: flex;}
|
||||||
|
.sc-file-select__item__file .item-file {width:110px;height:110px;display: flex;flex-direction: column;align-items: center;justify-content: center;}
|
||||||
|
.sc-file-select__item__file .item-file i {font-size: 40px;}
|
||||||
|
.sc-file-select__item__file .item-file.item-file-doc {color: #409eff;}
|
||||||
|
|
||||||
|
.sc-file-select__item__upload {position: absolute;top:0;right:0;bottom:0;left:0;z-index: 1;background: rgba(255,255,255,0.7);display: flex;flex-direction: column;align-items: center;justify-content: center;}
|
||||||
|
|
||||||
|
.sc-file-select__side {width: 200px;margin-right: 15px;border-right: 1px solid rgba(128,128,128,0.2);display: flex;flex-flow: column;}
|
||||||
|
.sc-file-select__side-menu {flex: 1;}
|
||||||
|
.sc-file-select__side-msg {height:32px;line-height: 32px;}
|
||||||
|
|
||||||
|
.sc-file-select__top {margin-bottom: 15px;display: flex;justify-content: space-between;}
|
||||||
|
.sc-file-select__upload {display: inline-block;}
|
||||||
|
.sc-file-select__top .tips {font-size: 12px;margin-left: 10px;color: #999;}
|
||||||
|
.sc-file-select__top .tips i {font-size: 14px;margin-right: 5px;}
|
||||||
|
.sc-file-select__pagination {margin:15px 0;}
|
||||||
|
|
||||||
|
.sc-file-select__do {text-align: right;}
|
||||||
|
</style>
|
|
@ -7,8 +7,8 @@
|
||||||
<el-image v-if="fileIsImg" class="image" :src="tempImg || img" :preview-src-list="[img]" fit="cover" hide-on-click-modal append-to-body :z-index="9999"></el-image>
|
<el-image v-if="fileIsImg" class="image" :src="tempImg || img" :preview-src-list="[img]" fit="cover" hide-on-click-modal append-to-body :z-index="9999"></el-image>
|
||||||
<a v-else :href="img" class="file" target="_blank"><i class="el-icon-document"></i></a>
|
<a v-else :href="img" class="file" target="_blank"><i class="el-icon-document"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="sc-upload-uploader">
|
<div v-else class="sc-upload-uploader" @click="fileSelect && showfileSelect()">
|
||||||
<el-upload ref="upload" class="uploader" :auto-upload="!cropper" :on-change="change" :accept="accept" :action="action" :show-file-list="false" :before-upload="before" :on-success="success" :on-error="error" :http-request="request">
|
<el-upload ref="upload" class="uploader" :disabled="fileSelect" :auto-upload="!cropper" :on-change="change" :accept="accept" :action="action" :show-file-list="false" :before-upload="before" :on-success="success" :on-error="error" :http-request="request">
|
||||||
<slot>
|
<slot>
|
||||||
<div class="file-empty">
|
<div class="file-empty">
|
||||||
<i :class="icon"></i>
|
<i :class="icon"></i>
|
||||||
|
@ -24,14 +24,22 @@
|
||||||
<el-button type="primary" @click="cropperSave">确 定</el-button>
|
<el-button type="primary" @click="cropperSave">确 定</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<el-dialog title="打开" v-model="fileSelectDialogVisible" :width="880" destroy-on-close>
|
||||||
|
<sc-file-select @submit="fileSelectSubmit">
|
||||||
|
<template #do>
|
||||||
|
<el-button @click="fileSelectDialogVisible=false" >取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</sc-file-select>
|
||||||
|
</el-dialog>
|
||||||
<el-input v-model="img" style="display:none"></el-input>
|
<el-input v-model="img" style="display:none"></el-input>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
import config from "@/config/upload"
|
import config from "@/config/upload"
|
||||||
import scCropper from '@/components/scCropper';
|
const scCropper = defineAsyncComponent(() => import('@/components/scCropper'))
|
||||||
|
const scFileSelect = defineAsyncComponent(() => import('@/components/scFileSelect'))
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -44,13 +52,15 @@
|
||||||
maxSize: { type: Number, default: config.maxSize },
|
maxSize: { type: Number, default: config.maxSize },
|
||||||
title: { type: String, default: "" },
|
title: { type: String, default: "" },
|
||||||
icon: { type: String, default: "el-icon-plus" },
|
icon: { type: String, default: "el-icon-plus" },
|
||||||
|
fileSelect: { type: Boolean, default: false },
|
||||||
cropper: { type: Boolean, default: false },
|
cropper: { type: Boolean, default: false },
|
||||||
compress: {type: Number, default: 1},
|
compress: {type: Number, default: 1},
|
||||||
aspectRatio: {type: Number, default: NaN},
|
aspectRatio: {type: Number, default: NaN},
|
||||||
onSuccess: { type: Function, default: () => { return true } }
|
onSuccess: { type: Function, default: () => { return true } }
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
scCropper
|
scCropper,
|
||||||
|
scFileSelect
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -64,7 +74,8 @@
|
||||||
},
|
},
|
||||||
cropperDialogVisible: false,
|
cropperDialogVisible: false,
|
||||||
cropperImg: "",
|
cropperImg: "",
|
||||||
cropperUploadFile: null
|
cropperUploadFile: null,
|
||||||
|
fileSelectDialogVisible: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch:{
|
watch:{
|
||||||
|
@ -81,6 +92,13 @@
|
||||||
this.img = this.modelValue;
|
this.img = this.modelValue;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showfileSelect(){
|
||||||
|
this.fileSelectDialogVisible = true
|
||||||
|
},
|
||||||
|
fileSelectSubmit(val){
|
||||||
|
this.img = val
|
||||||
|
this.fileSelectDialogVisible = false
|
||||||
|
},
|
||||||
cropperSave(){
|
cropperSave(){
|
||||||
var uploadFile = this.$refs.upload.uploadFiles[0].raw
|
var uploadFile = this.$refs.upload.uploadFiles[0].raw
|
||||||
this.$refs.cropper.getCropFile(file => {
|
this.$refs.cropper.getCropFile(file => {
|
||||||
|
|
|
@ -21,20 +21,29 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="sc-upload-uploader">
|
<div class="sc-upload-uploader" @click="fileSelect && showfileSelect()">
|
||||||
<el-upload ref="upload" class="uploader" :action="action" :accept="accept" multiple :show-file-list="false" :file-list="defaultFileList" :before-upload="before" :on-progress="progress" :on-success="success" :on-change="change" :on-remove="remove" :on-error="error" :http-request="request">
|
<el-upload ref="upload" class="uploader" :disabled="fileSelect" :action="action" :accept="accept" multiple :show-file-list="false" :file-list="defaultFileList" :before-upload="before" :on-progress="progress" :on-success="success" :on-change="change" :on-remove="remove" :on-error="error" :http-request="request">
|
||||||
<div class="file-empty">
|
<div class="file-empty">
|
||||||
<i :class="icon"></i>
|
<i :class="icon"></i>
|
||||||
<h4 v-if="title">{{title}}</h4>
|
<h4 v-if="title">{{title}}</h4>
|
||||||
</div>
|
</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</div>
|
</div>
|
||||||
|
<el-dialog title="打开" v-model="fileSelectDialogVisible" :width="880" destroy-on-close>
|
||||||
|
<sc-file-select multiple @submit="fileSelectSubmit">
|
||||||
|
<template #do>
|
||||||
|
<el-button @click="fileSelectDialogVisible=false" >取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</sc-file-select>
|
||||||
|
</el-dialog>
|
||||||
<el-input v-model="value" style="display:none"></el-input>
|
<el-input v-model="value" style="display:none"></el-input>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
import config from "@/config/upload";
|
import config from "@/config/upload";
|
||||||
|
const scFileSelect = defineAsyncComponent(() => import('@/components/scFileSelect'))
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -44,13 +53,18 @@
|
||||||
accept: { type: String, default: "image/gif, image/jpeg, image/png" },
|
accept: { type: String, default: "image/gif, image/jpeg, image/png" },
|
||||||
maxSize: { type: Number, default: config.maxSize },
|
maxSize: { type: Number, default: config.maxSize },
|
||||||
title: { type: String, default: "" },
|
title: { type: String, default: "" },
|
||||||
icon: { type: String, default: "el-icon-plus" }
|
icon: { type: String, default: "el-icon-plus" },
|
||||||
|
fileSelect: { type: Boolean, default: false }
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
scFileSelect
|
||||||
},
|
},
|
||||||
data(){
|
data(){
|
||||||
return {
|
return {
|
||||||
value: "",
|
value: "",
|
||||||
defaultFileList: [],
|
defaultFileList: [],
|
||||||
fileList: []
|
fileList: [],
|
||||||
|
fileSelectDialogVisible: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch:{
|
watch:{
|
||||||
|
@ -95,6 +109,14 @@
|
||||||
this.value = this.modelValue
|
this.value = this.modelValue
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
showfileSelect(){
|
||||||
|
this.fileSelectDialogVisible = true
|
||||||
|
},
|
||||||
|
fileSelectSubmit(val){
|
||||||
|
const newval = [...this.modelValue.split(","),...val].join(",")
|
||||||
|
this.$emit('update:modelValue', newval);
|
||||||
|
this.fileSelectDialogVisible = false
|
||||||
|
},
|
||||||
//默认值转换为数组
|
//默认值转换为数组
|
||||||
toArr(str){
|
toArr(str){
|
||||||
var _arr = [];
|
var _arr = [];
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import API from "@/api";
|
||||||
|
|
||||||
|
//文件选择器配置
|
||||||
|
|
||||||
|
export default {
|
||||||
|
apiObj: API.common.upload,
|
||||||
|
menuApiObj: API.common.file.menu,
|
||||||
|
listApiObj: API.common.file.list,
|
||||||
|
successCode: 200,
|
||||||
|
maxSize: 30,
|
||||||
|
max: 99,
|
||||||
|
uploadParseData: function (res) {
|
||||||
|
return {
|
||||||
|
id: res.data.id,
|
||||||
|
fileName: res.data.fileName,
|
||||||
|
url: res.data.src
|
||||||
|
}
|
||||||
|
},
|
||||||
|
listParseData: function (res) {
|
||||||
|
return {
|
||||||
|
rows: res.data.rows,
|
||||||
|
total: res.data.total,
|
||||||
|
msg: res.message,
|
||||||
|
code: res.code
|
||||||
|
}
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
page: 'page',
|
||||||
|
pageSize: 'pageSize',
|
||||||
|
keyword: 'keyword',
|
||||||
|
menuKey: 'groupId'
|
||||||
|
},
|
||||||
|
menuProps: {
|
||||||
|
key: 'id',
|
||||||
|
label: 'label',
|
||||||
|
children: 'children'
|
||||||
|
},
|
||||||
|
fileProps: {
|
||||||
|
key: 'id',
|
||||||
|
fileName: 'fileName',
|
||||||
|
url: 'url'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
doc: {
|
||||||
|
icon: 'sc-icon-file-word-2-fill',
|
||||||
|
color: '#409eff'
|
||||||
|
},
|
||||||
|
docx: {
|
||||||
|
icon: 'sc-icon-file-word-2-fill',
|
||||||
|
color: '#409eff'
|
||||||
|
},
|
||||||
|
xls: {
|
||||||
|
icon: 'sc-icon-file-excel-2-fill',
|
||||||
|
color: '#67C23A'
|
||||||
|
},
|
||||||
|
xlsx: {
|
||||||
|
icon: 'sc-icon-file-excel-2-fill',
|
||||||
|
color: '#67C23A'
|
||||||
|
},
|
||||||
|
ppt: {
|
||||||
|
icon: 'sc-icon-file-ppt-2-fill',
|
||||||
|
color: '#F56C6C'
|
||||||
|
},
|
||||||
|
pptx: {
|
||||||
|
icon: 'sc-icon-file-ppt-2-fill',
|
||||||
|
color: '#F56C6C'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
<template>
|
||||||
|
<el-main>
|
||||||
|
<el-row :gutter="15">
|
||||||
|
<el-col :lg="18">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<sc-file-select v-model="file" :multiple="multiple" :hideUpload="hideUpload" :max="99" @submit="submit">
|
||||||
|
<template #do>
|
||||||
|
<el-button>自定义插槽</el-button>
|
||||||
|
</template>
|
||||||
|
</sc-file-select>
|
||||||
|
</el-card>
|
||||||
|
<el-card shadow="never" header="已集成的上传组件">
|
||||||
|
<p>
|
||||||
|
<sc-upload v-model="upload" title="单选" file-select></sc-upload>
|
||||||
|
</p>
|
||||||
|
<p style="margin-top: 15px;">
|
||||||
|
<sc-upload-multiple v-model="upload2" title="多选" file-select></sc-upload-multiple>
|
||||||
|
</p>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :lg="6">
|
||||||
|
<el-card shadow="never" header="参数和方法">
|
||||||
|
<el-button type="primary" @click="multiple = !multiple">切换multiple</el-button>
|
||||||
|
<el-button type="primary" @click="hideUpload = !hideUpload">切换hideUpload</el-button>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import scFileSelect from '@/components/scFileSelect'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'fileselect',
|
||||||
|
components: {
|
||||||
|
scFileSelect
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
file: '',
|
||||||
|
multiple: false,
|
||||||
|
hideUpload: false,
|
||||||
|
upload: '',
|
||||||
|
upload2: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit(value){
|
||||||
|
console.log(value)
|
||||||
|
this.$message("返回值请查看F12控制台console.log()")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue