|
@@ -1,7 +1,7 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
- <el-container style="user-select: none; height: 100vh;">
|
|
|
- <el-header height="45px" style="background-color: #fafafa; padding: 0 10px;">
|
|
|
+ <el-container style="height: 100vh;">
|
|
|
+ <el-header height="45px" style="user-select: none; background-color: #fafafa; padding: 0 10px;">
|
|
|
<soft-header ref="headerRef" @update-soft="updateSoft()" @export-file="exportFile"></soft-header>
|
|
|
</el-header>
|
|
|
<el-main ref="el-main" style="background-color: #fafafa; position: relative;">
|
|
@@ -21,14 +21,38 @@
|
|
|
<div class="soft-content">
|
|
|
<!-- 设置区域 -->
|
|
|
<div class="content-right">
|
|
|
- <div class="handle-item" style="margin-bottom: 5px;">
|
|
|
- <p><b>文件名检索清单:</b><span style="color: #F56C6C; font-size: 12px;">(一行填一个,首尾空格清除)</span></p>
|
|
|
+
|
|
|
+ <div class="handle-item">
|
|
|
+ <b>检索方式:</b>
|
|
|
+ <el-select size="mini" style="width: 160px;" v-model="findType" placeholder="请选择检索方式">
|
|
|
+ <el-option value="1" label="按文件名检索"></el-option>
|
|
|
+ <el-option value="2" label="按创建时间检索"></el-option>
|
|
|
+ <el-option value="3" label="按修改时间检索"></el-option>
|
|
|
+ </el-select>
|
|
|
</div>
|
|
|
- <el-input class="find-textarea" type="textarea" placeholder="查找文件名清单,多个请换行显示:
|
|
|
- 名称1
|
|
|
- 名称2
|
|
|
- 名称3" v-model="handleData.findText"></el-input>
|
|
|
- <!-- 特殊字符匹配问题!!!! -->
|
|
|
+
|
|
|
+ <template v-if="findType == '1'">
|
|
|
+ <div class="handle-item" style="margin-bottom: 5px;">
|
|
|
+ <p><b>文件名检索清单:</b><span style="color: #F56C6C; font-size: 12px;">(一行填一个,首尾空格清除)</span></p>
|
|
|
+ </div>
|
|
|
+ <el-input class="find-textarea" type="textarea" placeholder="查找文件名清单,多个请换行显示:
|
|
|
+ 名称1
|
|
|
+ 名称2
|
|
|
+ 名称3" v-model="handleData.findText"></el-input>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div class="handle-item">
|
|
|
+ <b>开始时间:</b>
|
|
|
+ <el-date-picker type="datetime" v-model="handleData.startTime" placeholder="开始时间" style="width:160px;" 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>
|
|
|
+ </div>
|
|
|
+ <div class="find-textarea" style="height: calc(100% - 258px);">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
|
|
|
<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>
|
|
@@ -42,11 +66,13 @@
|
|
|
</div>
|
|
|
|
|
|
<div class="content-left" v-loading="searchLoading">
|
|
|
- <div class="handle-item" style="margin-bottom: 5px;">
|
|
|
+ <div class="handle-item" style="margin-bottom: 5px; display: flex; flex-wrap: nowrap; justify-content: space-between;">
|
|
|
<p>
|
|
|
<b>文件名检索结果:</b>
|
|
|
<span style="color: #F56C6C; font-size: 12px;" >共有 {{fileList.length}} 个文件,搜索耗时 {{times / 1000}} 秒</span>
|
|
|
</p>
|
|
|
+
|
|
|
+ <el-button size="mini" :disabled="fileList.length == 0" title="检索结果导出到excel表格中" :loading="xlsxLoading" @click="exportXlsx()">导出检索结果</el-button>
|
|
|
</div>
|
|
|
<div class="table-scroll">
|
|
|
<vxe-table ref="xTable" :column-config="{resizable: true}" size="mini"
|
|
@@ -55,7 +81,13 @@
|
|
|
: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="path" title="文件位置/名称"></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;"/>
|
|
|
+ <img v-else src="../assets/image/file.png" style="width: 20px; vertical-align: middle;"/>
|
|
|
+ <span>{{row.path}}</span>
|
|
|
+ </template>
|
|
|
+ </vxe-column>
|
|
|
<vxe-column field="status" title="操作" width="50" min-width="50" max-width="50" align="center">
|
|
|
<template #default="{ rowIndex }">
|
|
|
<el-link type="warning" @click="delFile(rowIndex)" style="font-size: 12px;">忽略</el-link>
|
|
@@ -154,6 +186,7 @@ import softHeader from './header.vue';
|
|
|
import pjson from '/package.json';
|
|
|
import fse from 'fs-extra';
|
|
|
const fg = require('fast-glob');
|
|
|
+import xlsx from 'node-xlsx';
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
|
|
let separator = '';
|
|
@@ -181,7 +214,10 @@ export default {
|
|
|
type: '1',
|
|
|
rule: '1',
|
|
|
findText: '',
|
|
|
+ startTime: '',
|
|
|
+ endTime: '',
|
|
|
},
|
|
|
+ findType: '1',
|
|
|
exportLoading: false,
|
|
|
searchLoading: false,
|
|
|
tabLoading: false,
|
|
@@ -194,11 +230,19 @@ export default {
|
|
|
loadingModal: false,
|
|
|
|
|
|
execlimit: 5,
|
|
|
+ xlsxLoading: false,
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
|
this.$refs.updateRef.updateSoft(true);
|
|
|
|
|
|
+ let __dirname = os.userInfo().homedir;
|
|
|
+ if(fs.existsSync(__dirname + separator + "Desktop")){
|
|
|
+ this.handleData.newPath = __dirname + separator + "Desktop"
|
|
|
+ } else{
|
|
|
+ this.handleData.newPath = __dirname + separator + "Downloads"
|
|
|
+ }
|
|
|
+
|
|
|
// 打开浏览器
|
|
|
const { shell } = require('electron');
|
|
|
const links = document.querySelectorAll('a[href]');
|
|
@@ -287,10 +331,15 @@ export default {
|
|
|
this.$message({message: '请先选择搜索目录' , type: 'error'});
|
|
|
return false;
|
|
|
}
|
|
|
- if(!this.handleData.findText){
|
|
|
+ if(!this.handleData.findText && this.findType == '1'){
|
|
|
this.$message({message: '请输入要查找的文件搜索清单' , type: 'error'});
|
|
|
return false;
|
|
|
}
|
|
|
+ if(this.findType != '1' && !this.handleData.startTime && !this.handleData.endTime){ // 根据时间搜索
|
|
|
+ this.$message({message: '请选择搜索的时间范围' , type: 'error'});
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
(async () => {
|
|
|
let startTime = new Date().getTime();
|
|
|
this.searchLoading = true;
|
|
@@ -300,7 +349,7 @@ export default {
|
|
|
let findText = this.handleData.findText.split('\n');
|
|
|
let searchDir = this.searchDir.replace(/\\/g, '/');
|
|
|
let paramArr = []; // 匹配规则1
|
|
|
- let paramArr2 = []; // 匹配规则2 - 带后缀名的文件,带.
|
|
|
+ let paramArr2 = []; // 匹配规则2 - 文件名称中带.
|
|
|
for(let i=0; i< findText.length; i++){
|
|
|
if(findText[i].trim()){
|
|
|
if(findText[i].indexOf('.') > -1){
|
|
@@ -350,12 +399,13 @@ export default {
|
|
|
}
|
|
|
console.log('----验证规则----', ruleStr);
|
|
|
try{
|
|
|
- const files = await fg(ruleStr, { dot: true });
|
|
|
+ const files = await fg(ruleStr, { dot: true, onlyFiles:true, objectMode: true,markDirectories: true});
|
|
|
let regExp = new RegExp(paramArr.join('|'));
|
|
|
let regExp2 = new RegExp(paramArr2.join('|'));
|
|
|
this.fileList = [];
|
|
|
files.map(item => {
|
|
|
- let filename = item.substr(item.lastIndexOf('/')+1);
|
|
|
+ let isDirectory = item.dirent.isDirectory();
|
|
|
+ let filename = item.name;//item.substr(item.lastIndexOf('/')+1);
|
|
|
let title = filename.substr(0, filename.lastIndexOf('.'));
|
|
|
let suffix = filename.substr(filename.lastIndexOf('.'));
|
|
|
if(filename.indexOf('.') < 0){
|
|
@@ -363,15 +413,16 @@ export default {
|
|
|
suffix = '';
|
|
|
}
|
|
|
let res = regExp.exec(filename);
|
|
|
- if(!res[0]){
|
|
|
+ if(!res){
|
|
|
res = regExp2.exec(filename);
|
|
|
}
|
|
|
this.fileList.push({
|
|
|
title: title,
|
|
|
+ isDirectory: isDirectory,
|
|
|
suffix: suffix, // 带.
|
|
|
name: filename,
|
|
|
match: res,
|
|
|
- path: item,
|
|
|
+ path: item.path,
|
|
|
status: '1'
|
|
|
});
|
|
|
});
|
|
@@ -386,6 +437,43 @@ export default {
|
|
|
})();
|
|
|
|
|
|
},
|
|
|
+ // 导出检索结果
|
|
|
+ exportXlsx(){
|
|
|
+ this.xlsxLoading = true;
|
|
|
+ let filename = '文件检索结果' + new Date().getTime() +'.xlsx';
|
|
|
+ let sheet1 = [['编号','匹配词','文件位置/名称','类型']];
|
|
|
+ let sheet2 = [];
|
|
|
+
|
|
|
+ let findText = this.handleData.findText.split('\n');
|
|
|
+ for(let i = 0; i < this.fileList.length; i++){
|
|
|
+ let item = this.fileList[i];
|
|
|
+ let info = [i+1, item.match, item.path, item.isDirectory ? '文件夹' : '文件'];
|
|
|
+ sheet1.push(info);
|
|
|
+
|
|
|
+ if(findText.indexOf(item.match[0]) > -1){ // 匹配到了
|
|
|
+ let removeIndex = findText.indexOf(item.match[0]);
|
|
|
+ findText.splice(removeIndex, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ findText.map(fitem => {
|
|
|
+ sheet2.push([fitem]);
|
|
|
+ })
|
|
|
+
|
|
|
+ let buffer = xlsx.build([
|
|
|
+ {
|
|
|
+ name: '检索成功',
|
|
|
+ data: sheet1
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '未检索',
|
|
|
+ data: sheet2
|
|
|
+ }
|
|
|
+ ]);
|
|
|
+ fs.writeFileSync(this.handleData.newPath + separator + filename, buffer, {'flag':'w'});
|
|
|
+ this.xlsxLoading = false;
|
|
|
+ this.$message({message: '文件导出成功!', type: 'success'});
|
|
|
+ electronApi.call('showItemInfolder',[this.handleData.newPath + separator + filename])
|
|
|
+ },
|
|
|
// 导出
|
|
|
exportFile(flag) {
|
|
|
let authority = this.$refs.headerRef.authority;
|
|
@@ -793,7 +881,7 @@ export default {
|
|
|
}
|
|
|
|
|
|
.find-textarea{
|
|
|
- height: calc(100% - 187px);
|
|
|
+ height: calc(100% - 216px);
|
|
|
|
|
|
textarea{
|
|
|
height: 100%;
|