From 3931e2728f618d0090f129b2665bc1285c4440c3 Mon Sep 17 00:00:00 2001 From: gaoshp <291585735@qq.com> Date: 星期日, 03 十一月 2024 17:27:32 +0800 Subject: [PATCH] update --- src/components/scFileSelect/index.vue | 577 +++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 379 insertions(+), 198 deletions(-) diff --git a/src/components/scFileSelect/index.vue b/src/components/scFileSelect/index.vue index 224baed..487040e 100644 --- a/src/components/scFileSelect/index.vue +++ b/src/components/scFileSelect/index.vue @@ -3,41 +3,47 @@ * @version: 1.0 * @Author: sakuya * @Date: 2021骞�10鏈�11鏃�16:01:40 - * @LastEditors: - * @LastEditTime: + * @LastEditors: Sneed + * @LastEditTime: 2024-06-16 16:16:25 --> <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"> + <el-tree :expand-on-click-node="false" 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"> - <el-icon class="icon"><el-icon-folder /></el-icon>{{node.label}} + <el-icon class="icon"><el-icon-folder /></el-icon>{{ node.label }} </span> </template> </el-tree> </div> <div class="sc-file-select__side-msg" v-if="multiple"> - 宸查�夋嫨 <b>{{value.length}}</b> / <b>{{max}}</b> 椤� + 宸查�夋嫨 <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-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-upload">鏈湴涓婁紶</el-button> </el-upload> - <span class="tips"><el-icon><el-icon-warning /></el-icon>澶у皬涓嶈秴杩噞{maxSize}}MB</span> + <span class="tips"><el-icon><el-icon-warning /></el-icon>澶у皬涓嶈秴杩噞{ 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> + <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> + <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"> @@ -45,9 +51,10 @@ </div> <el-image :src="file.tempImg" fit="contain"></el-image> </div> - <p>{{file.name}}</p> + <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 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"> <el-icon><el-icon-check /></el-icon> @@ -56,228 +63,402 @@ <el-icon><el-icon-check /></el-icon> </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> + <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-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> + <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> + <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> + <el-button type="primary" :disabled="value.length <= 0" @click="submit">纭� 瀹�</el-button> </div> </div> </div> </template> <script> - import config from "@/config/fileSelect" +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}, +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 }, - 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 + //鑾峰彇鍒楄〃鏁版嵁 + 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 } - }, - watch: { - multiple(){ - this.value = this.multiple ? [] : '' - this.$emit('update:modelValue', JSON.parse(JSON.stringify(this.value))); + 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) }, - mounted() { - this.getMenu() + //鏍戠偣鍑讳簨浠� + groupClick(data) { + this.menuId = data.id + this.currentPage = 1 + this.keyword = null 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 + //鍒嗛〉鍒锋柊琛ㄦ牸 + 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) } - if(this.onlyImage){ - reqData.type = 'image' + } else { + if (this.value.includes(itemUrl)) { + this.value = '' + } else { + this.value = itemUrl } - 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) } + }, + 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 { + display: flex; +} - .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__files { + flex: 1; +} - .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__list { + height: 400px; +} - .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__item { + display: inline-block; + float: left; + margin: 0 15px 25px 0; + width: 110px; + cursor: pointer; +} - .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;position: relative;bottom: -0.125em;} - .sc-file-select__pagination {margin:15px 0;} +.sc-file-select__item__file { + width: 110px; + height: 110px; + position: relative; +} - .sc-file-select__do {text-align: right;} +.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; + position: relative; + bottom: -0.125em; +} + +.sc-file-select__pagination { + margin: 15px 0; +} + +.sc-file-select__do { + text-align: right; +} </style> -- Gitblit v1.9.3