gaoshp
2024-06-16 5be78f8d80e78ad76f5f322a0ea1f47105fffe6f
src/components/scFileSelect/index.vue
@@ -3,15 +3,17 @@
 * @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}}
@@ -26,13 +28,17 @@
      <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>
            </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">
@@ -47,7 +53,8 @@
                  </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 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,9 +63,12 @@
                        <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>
@@ -67,7 +77,8 @@
            </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>
@@ -243,41 +254,211 @@
</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>