|
@@ -9,7 +9,7 @@
|
|
|
<div class="content-top">
|
|
|
<el-row>
|
|
|
<el-button type="primary" size="small" @click="pickDir()">添加文件路径</el-button>
|
|
|
- <el-input readonly ref="search-input" size="small" placeholder="搜索目录路径" v-model="searchDir" style="width:400px;" prefix-icon="el-icon-folder"></el-input>
|
|
|
+ <el-input readonly ref="search-input" size="small" placeholder="搜索目录路径" v-model="searchDir" style="width:460px;" prefix-icon="el-icon-folder"></el-input>
|
|
|
<el-checkbox v-model="subFolder" size="mini">搜索多级子文件夹</el-checkbox>
|
|
|
</el-row>
|
|
|
|
|
@@ -23,15 +23,28 @@
|
|
|
<div class="content-right">
|
|
|
|
|
|
<div class="handle-item">
|
|
|
- <b>检索方式:</b>
|
|
|
- <el-select size="mini" style="width: 160px;" v-model="findType" placeholder="请选择检索方式">
|
|
|
+ <b>检索类型:</b>
|
|
|
+ <el-select size="mini" style="width: 170px;" v-model="findType" placeholder="请选择检索类型">
|
|
|
<el-option value="1" label="按文件名检索"></el-option>
|
|
|
+ <el-option value="5" label="按文件夹名检索"></el-option>
|
|
|
<el-option value="2" label="按创建时间检索"></el-option>
|
|
|
<el-option value="3" label="按修改时间检索"></el-option>
|
|
|
+ <el-option value="4" label="按文件类型检索"></el-option>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
|
|
|
- <template v-if="findType == '1'">
|
|
|
+ <template v-if="findType == '1' || findType == '5'">
|
|
|
+ <b>检索方式:</b>
|
|
|
+ <el-select size="mini" style="width: 170px;" v-model="handleData.rule" placeholder="请选择检索方式">
|
|
|
+ <el-option value="1" label="精确(名称相同)"></el-option>
|
|
|
+ <el-option value="2" label="模糊(包含名称)"></el-option>
|
|
|
+ <el-option value="3" label="精确到格式(名称和后缀都相同)"></el-option>
|
|
|
+ </el-select>
|
|
|
+ <!-- <el-radio-group class="line-radio" v-model="handleData.rule" size="mini">
|
|
|
+ <el-radio label="1">精确(文件名相同)</el-radio>
|
|
|
+ <el-radio label="2">模糊(包含文件名)</el-radio>
|
|
|
+ <el-radio label="3">精确到格式(文件名和后缀都相同)</el-radio>
|
|
|
+ </el-radio-group> -->
|
|
|
<div class="handle-item" style="margin-bottom: 5px;">
|
|
|
<p><b>文件名检索清单:</b><span style="color: #F56C6C; font-size: 12px;">(一行填一个,首尾空格清除)</span></p>
|
|
|
</div>
|
|
@@ -40,28 +53,51 @@
|
|
|
名称2
|
|
|
名称3" v-model="handleData.findText"></el-input>
|
|
|
</template>
|
|
|
- <template v-else>
|
|
|
+ <template v-else-if="findType == '2' || findType == '3'">
|
|
|
<div class="handle-item">
|
|
|
<b>开始时间:</b>
|
|
|
- <el-date-picker type="datetime" v-model="handleData.startTime" placeholder="开始时间" style="width:160px;" size="mini"></el-date-picker>
|
|
|
+ <el-date-picker type="datetime" v-model="handleData.startTime" placeholder="开始时间" style="width:170px;" size="mini"></el-date-picker>
|
|
|
</div>
|
|
|
<div class="handle-item">
|
|
|
<b>结束时间:</b>
|
|
|
- <el-date-picker type="datetime" v-model="handleData.endTime" placeholder="结束时间" style="width:160px;" size="mini"></el-date-picker>
|
|
|
+ <el-date-picker type="datetime" v-model="handleData.endTime" placeholder="结束时间" style="width:170px;" size="mini"></el-date-picker>
|
|
|
</div>
|
|
|
- <div class="find-textarea" style="height: calc(100% - 258px);">
|
|
|
-
|
|
|
+ </template>
|
|
|
+ <template v-else-if="findType == '4'">
|
|
|
+ <div class="handle-item">
|
|
|
+ <b>文件类型:</b>
|
|
|
+ <el-select size="mini" style="width: 170px;" v-model="handleData.suffixType" placeholder="请选择文件类型">
|
|
|
+ <el-option value="1" label="文本文档"></el-option>
|
|
|
+ <el-option value="2" label="图像文件"></el-option>
|
|
|
+ <el-option value="3" label="音频文件"></el-option>
|
|
|
+ <el-option value="4" label="视频文件"></el-option>
|
|
|
+ <el-option value="5" label="压缩文件"></el-option>
|
|
|
+ <el-option value="6" label="数据库文件"></el-option>
|
|
|
+ <el-option value="10" label="自定义后缀文件"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="handle-item" v-if="handleData.suffixType == '10'">
|
|
|
+ <b>后缀名称:</b>
|
|
|
+ <el-input size="small" placeholder="自定义后缀(不包含.)" v-model="handleData.suffix" style="width:170px"></el-input>
|
|
|
</div>
|
|
|
+
|
|
|
+ <el-popover placement="bottom" popper-class="popper-open" trigger="hover">
|
|
|
+ <div style="text-align: left;">
|
|
|
+ <p>文本文档:{{suffixList[0]}}</p>
|
|
|
+ <p>图像文件:{{suffixList[1]}}</p>
|
|
|
+ <p>音频文件:{{suffixList[2]}}</p>
|
|
|
+ <p>视频文件:{{suffixList[3]}}</p>
|
|
|
+ <p>压缩文件:{{suffixList[4]}}</p>
|
|
|
+ <p>数据库文件:{{suffixList[5]}}</p>
|
|
|
+ <p>以上文件类型只做后缀名匹配</p>
|
|
|
+ </div>
|
|
|
+ <span slot="reference" class="i-tips" style="margin-top: 20px;">查看支持的文件类型</span>
|
|
|
+ </el-popover>
|
|
|
</template>
|
|
|
|
|
|
- <div style="position: relative; margin: 10px 0;">
|
|
|
+ <div style="position: relative; margin: 10px 0;" >
|
|
|
<el-button type="danger" size="mini" style="position: absolute; right: 0; top: 0;" :loading="searchLoading" @click="search()">搜索</el-button>
|
|
|
- <div style="padding: 10px; font-weight: 600;">检索方式:</div>
|
|
|
- <el-radio-group class="line-radio" v-model="handleData.rule" size="small">
|
|
|
- <el-radio label="1">精确(文件名相同)</el-radio>
|
|
|
- <el-radio label="2">模糊(包含文件名)</el-radio>
|
|
|
- <el-radio label="3">精确到格式(文件名和格式都相同)</el-radio>
|
|
|
- </el-radio-group>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
@@ -80,7 +116,9 @@
|
|
|
:loading-config="{icon: 'vxe-icon-indicator roll', text: '任务处理中...'}" :row-config="{isHover: true}"
|
|
|
:edit-config="{trigger: 'click', mode: 'cell'}" :data="fileList" :scroll-y="{enabled: true}">
|
|
|
<vxe-column type="seq" width="60" title="编号" align="center"></vxe-column>
|
|
|
- <vxe-column field="match" title="匹配词" width="150" min-width="120" align="center"></vxe-column>
|
|
|
+ <vxe-column field="match" title="匹配词" v-if="findType == '1' || findType == '5'" width="150" min-width="120" align="center"></vxe-column>
|
|
|
+ <vxe-column field="rangeTime" title="时间" v-else-if="findType == '2' || findType == '3'" width="150" min-width="120" align="center"></vxe-column>
|
|
|
+ <vxe-column field="match" title="类型" v-else-if="findType == '4'" width="150" min-width="120" align="center"></vxe-column>
|
|
|
<vxe-column field="path" title="文件位置/名称">
|
|
|
<template #default="{ row }">
|
|
|
<img v-if="row.isDirectory" src="../assets/image/folder.png" style="width: 20px; vertical-align: middle;"/>
|
|
@@ -155,9 +193,9 @@
|
|
|
</div>
|
|
|
<div class="handle-item">
|
|
|
<label v-if="handleData.type != '1'" class="handle-label"><el-link icon="el-icon-warning" :underline="false" type="danger"></el-link></label>
|
|
|
- <el-link style="font-weight: 600;" v-if="handleData.type == '2'" :underline="false" type="danger">当前为"剪切"操作,剪切后文件无法恢复原来位置,您可以做好备份后操作。</el-link>
|
|
|
- <el-link style="font-weight: 600;" v-if="handleData.type == '3'" :underline="false" type="danger">当前为"删除"操作,删除后文件无法恢复原来位置,您可以做好备份后操作。</el-link>
|
|
|
- <el-link style="font-weight: 600;" v-if="handleData.type == '4'" :underline="false" type="danger">当前为"覆盖"操作,覆盖后原文件将无法恢复,您可以做好备份后操作。</el-link>
|
|
|
+ <el-link style="font-weight: 600;" v-if="handleData.type == '2'" :underline="false" type="danger">当前为"剪切"操作,剪切后文件无法恢复原来位置,请做好备份后操作。</el-link>
|
|
|
+ <el-link style="font-weight: 600;" v-if="handleData.type == '3'" :underline="false" type="danger">当前为"删除"操作,删除后文件无法恢复原来位置,请做好备份后操作。</el-link>
|
|
|
+ <el-link style="font-weight: 600;" v-if="handleData.type == '4'" :underline="false" type="danger">当前为"覆盖"操作,覆盖后原文件将无法恢复,请做好备份后操作。</el-link>
|
|
|
</div>
|
|
|
|
|
|
<el-button type="danger" style="position: absolute; top: 40px; right: 10px;" @click="exportFile()" :loading="exportLoading">开始处理</el-button>
|
|
@@ -214,8 +252,10 @@ export default {
|
|
|
type: '1',
|
|
|
rule: '1',
|
|
|
findText: '',
|
|
|
- startTime: '',
|
|
|
- endTime: '',
|
|
|
+ startTime: new Date(),
|
|
|
+ endTime: new Date(),
|
|
|
+ suffixType: '1',
|
|
|
+ suffix: ''
|
|
|
},
|
|
|
findType: '1',
|
|
|
exportLoading: false,
|
|
@@ -231,6 +271,15 @@ export default {
|
|
|
|
|
|
execlimit: 5,
|
|
|
xlsxLoading: false,
|
|
|
+
|
|
|
+ suffixList: [
|
|
|
+ ['txt', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'pdf', 'csv'],
|
|
|
+ ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp', 'bmp', 'tif', 'tiff', 'psd', 'raw', 'heif', 'heic', 'eps', 'ai', 'ico'],
|
|
|
+ ['mp3', 'aac', 'm4a', 'flac', 'alac', 'wav', 'waf', 'aiff', 'ogg', 'amr', 'ape', 'wma'],
|
|
|
+ ['mp4', 'mkv', 'avi', 'mov', 'webm', 'mxf', 'flv', 'ts', 'm3u8', '3gp', 'wmv', 'rm', 'rmvb', 'vob'],
|
|
|
+ ['zip', 'rar', '7z'],
|
|
|
+ ['sql', 'db', 'sqlite', 'mdb', 'accdb', 'mdf', 'accdb', 'dbf']
|
|
|
+ ],
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
@@ -295,6 +344,10 @@ export default {
|
|
|
type: '1',
|
|
|
rule: '1',
|
|
|
findText: '',
|
|
|
+ startTime: new Date(),
|
|
|
+ endTime: new Date(),
|
|
|
+ suffixType: '1',
|
|
|
+ suffix: ''
|
|
|
};
|
|
|
this.fileList = [];
|
|
|
}).catch(() => {
|
|
@@ -335,8 +388,13 @@ export default {
|
|
|
this.$message({message: '请输入要查找的文件搜索清单' , type: 'error'});
|
|
|
return false;
|
|
|
}
|
|
|
- if(this.findType != '1' && !this.handleData.startTime && !this.handleData.endTime){ // 根据时间搜索
|
|
|
- this.$message({message: '请选择搜索的时间范围' , type: 'error'});
|
|
|
+
|
|
|
+ if(this.findType == '2' || this.findType == '3'){ //按照时间搜索
|
|
|
+ this.timeSearch();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if(this.findType == '4'){ //按照文件类型匹配
|
|
|
+ this.typeSearch();
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -345,63 +403,101 @@ export default {
|
|
|
this.searchLoading = true;
|
|
|
setTimeout(() => {
|
|
|
this.searchLoading = false;
|
|
|
- }, 2000)
|
|
|
+ }, 5000)
|
|
|
let findText = this.handleData.findText.split('\n');
|
|
|
let searchDir = this.searchDir.replace(/\\/g, '/');
|
|
|
- let paramArr = []; // 匹配规则1
|
|
|
- let paramArr2 = []; // 匹配规则2 - 文件名称中带.
|
|
|
- for(let i=0; i< findText.length; i++){
|
|
|
- if(findText[i].trim()){
|
|
|
- if(findText[i].indexOf('.') > -1){
|
|
|
- paramArr2.push(this.filterReg(findText[i].trim()));
|
|
|
- }else{
|
|
|
- paramArr.push(this.filterReg(findText[i].trim()));
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- let params = paramArr.join(',');
|
|
|
- let params2 = paramArr2.join(',');
|
|
|
let ruleStr = [];
|
|
|
let subStr = '/';
|
|
|
if(this.subFolder){ // 是否匹配子文件夹内文件
|
|
|
subStr = '/**/'
|
|
|
}
|
|
|
- switch(this.handleData.rule){
|
|
|
- case '1': //相同文件名
|
|
|
- if(paramArr.length > 0){
|
|
|
- ruleStr.push(searchDir + subStr + '{' + params + ',<}?(.[!.]+)');
|
|
|
- }
|
|
|
- if(paramArr2.length > 0){
|
|
|
- ruleStr.push(searchDir + subStr + '{' + params2 + ',<}.[!.]+');
|
|
|
- }
|
|
|
- break;
|
|
|
- case '2': //包含文件名
|
|
|
- if(paramArr.length > 0){
|
|
|
- ruleStr.push(searchDir + subStr + '*{' + params + ',<}*.[!.]+');
|
|
|
- ruleStr.push(searchDir + subStr + '{' + params + ',<}');
|
|
|
- ruleStr.push(searchDir + subStr + '[!.]+{' + params + ',<}');
|
|
|
- ruleStr.push(searchDir + subStr + '{' + params + ',<}[!.]+');
|
|
|
- ruleStr.push(searchDir + subStr + '[!.]+{' + params + ',<}[!.]+');
|
|
|
- }
|
|
|
- if(paramArr2.length > 0){
|
|
|
- ruleStr.push(searchDir + subStr + '*{' + params2 + ',<}*.[!.]+');
|
|
|
- }
|
|
|
- break;
|
|
|
- case '3': //文件名格式相同
|
|
|
- if(paramArr.length > 0){
|
|
|
- ruleStr.push(searchDir + subStr + '{' + params + ',<}');
|
|
|
+
|
|
|
+ let paramArr = []; // 匹配规则1
|
|
|
+ let paramArr2 = []; // 匹配规则2 - 文件名称中带.
|
|
|
+ let paramArr3 = []; // 匹配规则3 - 文件夹
|
|
|
+ if(this.findType == '1'){
|
|
|
+ for(let i=0; i< findText.length; i++){
|
|
|
+ if(findText[i].trim()){
|
|
|
+ if(findText[i].indexOf('.') > -1){
|
|
|
+ paramArr2.push(this.filterReg(findText[i].trim()));
|
|
|
+ }else{
|
|
|
+ paramArr.push(this.filterReg(findText[i].trim()));
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
- if(paramArr2.length > 0){
|
|
|
- ruleStr.push(searchDir + subStr + '{' + params2 + ',<}');
|
|
|
+ }
|
|
|
+ let params = paramArr.join(',');
|
|
|
+ let params2 = paramArr2.join(',');
|
|
|
+ switch(this.handleData.rule){
|
|
|
+ case '1': //相同文件名
|
|
|
+ if(paramArr.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}?(.[!.]+)');
|
|
|
+ }
|
|
|
+ if(paramArr2.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params2 + ',<}.[!.]+');
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case '2': //包含文件名
|
|
|
+ if(paramArr.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '*{' + params + ',<}*.[!.]+');
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}');
|
|
|
+ ruleStr.push(searchDir + subStr + '[!.]+{' + params + ',<}');
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}[!.]+');
|
|
|
+ ruleStr.push(searchDir + subStr + '[!.]+{' + params + ',<}[!.]+');
|
|
|
+ }
|
|
|
+ if(paramArr2.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '*{' + params2 + ',<}*.[!.]+');
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case '3': //文件名格式相同
|
|
|
+ if(paramArr.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}');
|
|
|
+ }
|
|
|
+ if(paramArr2.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params2 + ',<}');
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }else if(this.findType == '5'){
|
|
|
+ for(let i=0; i< findText.length; i++){
|
|
|
+ if(findText[i].trim()){
|
|
|
+ paramArr3.push(this.filterReg(findText[i].trim()));
|
|
|
}
|
|
|
- break;
|
|
|
+ }
|
|
|
+ let params = paramArr3.join(',');
|
|
|
+ switch(this.handleData.rule){
|
|
|
+ case '1': //相同文件名
|
|
|
+ if(paramArr3.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}');
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case '2': //包含文件名
|
|
|
+ if(paramArr3.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '*{' + params + ',<}*');
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case '3': //文件名格式相同
|
|
|
+ if(paramArr3.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}');
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
console.log('----验证规则----', ruleStr);
|
|
|
try{
|
|
|
- const files = await fg(ruleStr, { dot: true, onlyFiles:true, objectMode: true,markDirectories: true});
|
|
|
+ let obj = {
|
|
|
+ dot: true, onlyFiles:true, objectMode: true,markDirectories: true
|
|
|
+ };
|
|
|
+ if(this.findType == '5'){
|
|
|
+ obj = {
|
|
|
+ dot: true, onlyDirectories:true, objectMode: true,markDirectories: true,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ const files = await fg(ruleStr, obj);
|
|
|
let regExp = new RegExp(paramArr.join('|'));
|
|
|
let regExp2 = new RegExp(paramArr2.join('|'));
|
|
|
+ let regExp3 = new RegExp(paramArr3.join('|'));
|
|
|
this.fileList = [];
|
|
|
files.map(item => {
|
|
|
let isDirectory = item.dirent.isDirectory();
|
|
@@ -412,10 +508,21 @@ export default {
|
|
|
title = filename;
|
|
|
suffix = '';
|
|
|
}
|
|
|
- let res = regExp.exec(filename);
|
|
|
- if(!res){
|
|
|
- res = regExp2.exec(filename);
|
|
|
+ if(this.findType == '5'){
|
|
|
+ suffix = '';
|
|
|
}
|
|
|
+ let res = '';
|
|
|
+ if(this.findType == '1'){
|
|
|
+ res = regExp.exec(filename);
|
|
|
+ if(!res){
|
|
|
+ res = regExp2.exec(filename);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(this.findType == '5'){
|
|
|
+ res = regExp3.exec(filename);
|
|
|
+ }
|
|
|
+
|
|
|
this.fileList.push({
|
|
|
title: title,
|
|
|
isDirectory: isDirectory,
|
|
@@ -435,6 +542,152 @@ export default {
|
|
|
}
|
|
|
|
|
|
})();
|
|
|
+ },
|
|
|
+ // 按照时间搜索
|
|
|
+ timeSearch(){
|
|
|
+ if(!this.handleData.startTime && !this.handleData.endTime){ // 根据时间搜索
|
|
|
+ this.$message({message: '请选择搜索的时间范围' , type: 'error'});
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ (async () => {
|
|
|
+ let startTime = new Date().getTime();
|
|
|
+ this.searchLoading = true;
|
|
|
+ setTimeout(() => {
|
|
|
+ this.searchLoading = false;
|
|
|
+ }, 5000);
|
|
|
+
|
|
|
+ let searchDir = this.searchDir.replace(/\\/g, '/');
|
|
|
+ let ruleStr = [];
|
|
|
+ let subStr = '/';
|
|
|
+ if(this.subFolder){ // 是否匹配子文件夹内文件
|
|
|
+ subStr = '/**/'
|
|
|
+ }
|
|
|
+ ruleStr.push(searchDir + subStr + '*');
|
|
|
+ console.log('----验证规则----', ruleStr);
|
|
|
+ try{
|
|
|
+ const fsPromises = fs.promises;
|
|
|
+ const files = await fg(ruleStr, { dot: true, onlyFiles:true, suppressErrors: true});
|
|
|
+ this.fileList = [];
|
|
|
+ const BATCH_SIZE = 1000;
|
|
|
+ const matchedFiles = [];
|
|
|
+ for (let i = 0; i < files.length; i += BATCH_SIZE) {
|
|
|
+ const batch = files.slice(i, i + BATCH_SIZE);
|
|
|
+ const statsPromises = batch.map(file => fsPromises.stat(file).catch(() => null));
|
|
|
+ const statsResults = await Promise.all(statsPromises);
|
|
|
+ statsResults.forEach((stats, index) => {
|
|
|
+ if (!stats) return;
|
|
|
+ let rangeTime = stats.birthtime;
|
|
|
+ if(this.findType == '2'){ //创建时间
|
|
|
+ rangeTime = stats.birthtime
|
|
|
+ }else if(this.findType == '3'){ //修改时间
|
|
|
+ rangeTime = stats.mtime;
|
|
|
+ }
|
|
|
+
|
|
|
+ let ruleFlag = false;
|
|
|
+ if(this.handleData.startTime && !this.handleData.endTime && rangeTime >= this.handleData.startTime){
|
|
|
+ ruleFlag = true;
|
|
|
+ }else if(!this.handleData.startTime && this.handleData.endTime && rangeTime <= this.handleData.endTime){
|
|
|
+ ruleFlag = true;
|
|
|
+ }else if (rangeTime >= this.handleData.startTime && rangeTime <= this.handleData.endTime) {
|
|
|
+ ruleFlag = true;
|
|
|
+ }
|
|
|
+ if(ruleFlag){
|
|
|
+ let filename = batch[index].substr(batch[index].lastIndexOf('/')+1);;
|
|
|
+ let title = filename.substr(0, filename.lastIndexOf('.'));
|
|
|
+ let suffix = filename.substr(filename.lastIndexOf('.'));
|
|
|
+ this.fileList.push({
|
|
|
+ title: title,
|
|
|
+ isDirectory: false,
|
|
|
+ suffix: suffix, // 带.
|
|
|
+ name: filename,
|
|
|
+ match: '-',
|
|
|
+ path: batch[index],
|
|
|
+ rangeTime: this.$utils.formatTime(rangeTime),
|
|
|
+ status: '1'
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ this.searchLoading = false;
|
|
|
+ let endTime = new Date().getTime();
|
|
|
+ this.times = endTime - startTime;
|
|
|
+ // console.log('----查找结果----', files);
|
|
|
+ }catch(e){
|
|
|
+ this.showError(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ })();
|
|
|
+ },
|
|
|
+ // 按照文件类型匹配
|
|
|
+ typeSearch(){
|
|
|
+ if(this.handleData.suffixType == '10' && this.handleData.suffix.trim() == ''){
|
|
|
+ this.$message({message: '请输入需要搜索的后缀名' , type: 'error'});
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ (async () => {
|
|
|
+ let startTime = new Date().getTime();
|
|
|
+ this.searchLoading = true;
|
|
|
+ setTimeout(() => {
|
|
|
+ this.searchLoading = false;
|
|
|
+ }, 5000)
|
|
|
+ let searchDir = this.searchDir.replace(/\\/g, '/');
|
|
|
+
|
|
|
+
|
|
|
+ let ruleStr = [];
|
|
|
+ let subStr = '/';
|
|
|
+ if(this.subFolder){ // 是否匹配子文件夹内文件
|
|
|
+ subStr = '/**/'
|
|
|
+ }
|
|
|
+ let params = '';
|
|
|
+ if(this.handleData.suffixType != '10'){
|
|
|
+ let suffixIndex = Number(this.handleData.suffixType) - 1;
|
|
|
+ params = this.suffixList[suffixIndex].join(',');
|
|
|
+ }
|
|
|
+
|
|
|
+ let customSuffix = '*.{' + params + '}';
|
|
|
+ if(this.handleData.suffixType == '10' && this.handleData.suffix.trim()){
|
|
|
+ customSuffix = '*.' + this.handleData.suffix.trimEnd();
|
|
|
+ }
|
|
|
+
|
|
|
+ ruleStr.push(searchDir + subStr + customSuffix);
|
|
|
+
|
|
|
+ console.log('----验证规则----', ruleStr);
|
|
|
+ try{
|
|
|
+ const files = await fg(ruleStr, { dot: true, caseSensitiveMatch: false, onlyFiles:true, objectMode: true,markDirectories: true});
|
|
|
+ this.fileList = [];
|
|
|
+ files.map(item => {
|
|
|
+ let isDirectory = false;
|
|
|
+ let filename = item.name;
|
|
|
+ let title = filename.substr(0, filename.lastIndexOf('.'));
|
|
|
+ let suffix = filename.substr(filename.lastIndexOf('.'));
|
|
|
+ if(filename.indexOf('.') < 0){
|
|
|
+ title = filename;
|
|
|
+ suffix = '';
|
|
|
+ }
|
|
|
+ this.fileList.push({
|
|
|
+ title: title,
|
|
|
+ isDirectory: isDirectory,
|
|
|
+ suffix: suffix, // 带.
|
|
|
+ name: filename,
|
|
|
+ match: suffix,
|
|
|
+ path: item.path,
|
|
|
+ status: '1'
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.searchLoading = false;
|
|
|
+ let endTime = new Date().getTime();
|
|
|
+ this.times = endTime - startTime;
|
|
|
+ // console.log('----查找结果----', files);
|
|
|
+ }catch(e){
|
|
|
+ this.showError(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ })();
|
|
|
+
|
|
|
|
|
|
},
|
|
|
// 导出检索结果
|
|
@@ -561,14 +814,29 @@ export default {
|
|
|
item.status = '3'
|
|
|
}catch(e){
|
|
|
let str = e.toString();
|
|
|
+
|
|
|
+ if(str.indexOf('busy or locked') > -1){
|
|
|
+ this.$notify.error({
|
|
|
+ title: '提示',
|
|
|
+ message: '文件被系统或其他进程占用,无法剪切'+item.path
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
if(str.indexOf('already exists') > -1){
|
|
|
newFilePath = newPath + middlePath + item.title + '重复文件' + uuidv4().substr(0, 18) + i.toString() + item.suffix;
|
|
|
- fse.move(item.path, newFilePath).then(() => {
|
|
|
- item.status = '3';
|
|
|
- }).catch(err => {
|
|
|
- item.status = '6';
|
|
|
- })
|
|
|
+ try{
|
|
|
+ fse.move(item.path, newFilePath).then(() => {
|
|
|
+ item.status = '3';
|
|
|
+ }).catch(err => {
|
|
|
+ item.status = '6';
|
|
|
+ })
|
|
|
+ }catch(e){
|
|
|
+ console.log(e.toString());
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -577,6 +845,13 @@ export default {
|
|
|
fse.remove(item.path).then(() => {
|
|
|
item.status = '4';
|
|
|
}).catch(err => {
|
|
|
+ let str = err.toString();
|
|
|
+ if(str.indexOf('busy or locked') > -1){
|
|
|
+ this.$notify.error({
|
|
|
+ title: '提示',
|
|
|
+ message: '文件被系统或其他进程占用,无法删除'+item.path
|
|
|
+ });
|
|
|
+ }
|
|
|
item.status = '6';
|
|
|
})
|
|
|
}
|
|
@@ -881,7 +1156,7 @@ export default {
|
|
|
}
|
|
|
|
|
|
.find-textarea{
|
|
|
- height: calc(100% - 216px);
|
|
|
+ height: calc(100% - 160px);
|
|
|
|
|
|
textarea{
|
|
|
height: 100%;
|