|
@@ -10,10 +10,11 @@
|
|
|
<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-checkbox v-model="subFolder" border size="mini">搜索多级子文件夹</el-checkbox>
|
|
|
</el-row>
|
|
|
|
|
|
<el-row type="flex" style="align-items: center;">
|
|
|
- <el-button type="info" size="small" style="margin-left: 20px;">重置</el-button>
|
|
|
+ <el-button type="info" size="small" style="margin-left: 20px;" @click="clearList()">重置</el-button>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
|
|
@@ -57,8 +58,8 @@
|
|
|
<vxe-column field="match" title="匹配词" width="150"></vxe-column>
|
|
|
<vxe-column field="path" title="文件位置"></vxe-column>
|
|
|
<vxe-column field="status" title="操作" width="80">
|
|
|
- <template #default="{ row }">
|
|
|
- <el-link icon="el-icon-s-release" type="warning">忽略</el-link>
|
|
|
+ <template #default="{ rowIndex }">
|
|
|
+ <el-link icon="el-icon-s-release" type="warning" @click="delFile(rowIndex)">忽略</el-link>
|
|
|
</template>
|
|
|
</vxe-column>
|
|
|
<vxe-column field="status" title="状态" width="100">
|
|
@@ -69,19 +70,23 @@
|
|
|
</template>
|
|
|
<template v-if="row.status == '2'">
|
|
|
<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
- <span>处理成功</span>
|
|
|
+ <span>复制成功</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '3'">
|
|
|
- <i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
|
|
|
- <span>修改失败</span>
|
|
|
+ <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
+ <span>剪切成功</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '4'">
|
|
|
- <i class="el-icon-warning" style="font-size: 16px; color: #ff9900;"></i>
|
|
|
- <span>文件被修改</span>
|
|
|
+ <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
+ <span>删除成功</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '5'">
|
|
|
- <i class="el-icon-warning" style="font-size: 16px; color: #ff9900;"></i>
|
|
|
- <span>文件已存在</span>
|
|
|
+ <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
+ <span>覆盖成功</span>
|
|
|
+ </template>
|
|
|
+ <template v-if="row.status == '6'">
|
|
|
+ <i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
|
|
|
+ <span>处理失败</span>
|
|
|
</template>
|
|
|
</template>
|
|
|
</vxe-column>
|
|
@@ -89,13 +94,18 @@
|
|
|
</div>
|
|
|
|
|
|
<div style="position: relative; margin-top: 20px;">
|
|
|
- <div class="handle-item">
|
|
|
+ <div class="handle-item" v-if="handleData.type != '4'">
|
|
|
<label class="handle-label">存储位置:</label>
|
|
|
- <el-input :title="downloadDir" ref="upload-input" size="small" @focus="pickPath" placeholder="请选择输出目录" v-model="downloadDir" readonly style="width:300px;" prefix-icon="el-icon-folder"></el-input>
|
|
|
- <el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="打开保存目录">
|
|
|
+ <el-input :title="downloadDir" ref="upload-input" size="small" @focus="pickPath" placeholder="请选择存储位置" v-model="downloadDir" readonly style="width:300px;" prefix-icon="el-icon-folder"></el-input>
|
|
|
+ <el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="打开存储位置">
|
|
|
<i class="el-icon-folder-opened" slot="reference" style="padding-left: 5px; cursor: pointer; font-size: 22px; vertical-align: middle;" @click="openFolder()"></i>
|
|
|
</el-popover>
|
|
|
</div>
|
|
|
+ <div class="handle-item" v-if="handleData.type == '4'">
|
|
|
+ <label class="handle-label">覆盖文件:</label>
|
|
|
+ <el-input :title="coverFile" ref="cover-input" size="small" @focus="pickFile" placeholder="点击选择覆盖文件" v-model="coverFile" readonly style="width:300px;" prefix-icon="el-icon-document"></el-input>
|
|
|
+ <el-link :underline="false" type="danger" style="font-size: 12px;"> (覆盖文件的名称格式需和搜索结果保持一致,否则将无法覆盖)</el-link>
|
|
|
+ </div>
|
|
|
<div class="handle-item">
|
|
|
<label class="handle-label">操作方式:</label>
|
|
|
<el-radio-group v-model="handleData.type" size="small">
|
|
@@ -105,10 +115,15 @@
|
|
|
<el-radio label="4" border>覆盖</el-radio>
|
|
|
</el-radio-group>
|
|
|
</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 v-if="handleData.type == '2'" :underline="false" type="danger">当前为"剪切"操作,剪切后文件无法恢复原来位置,您可以做好备份后操作。</el-link>
|
|
|
+ <el-link v-if="handleData.type == '3'" :underline="false" type="danger">当前为"删除"操作,删除后文件无法恢复原来位置,您可以做好备份后操作。</el-link>
|
|
|
+ <el-link v-if="handleData.type == '4'" :underline="false" type="danger">当前为"覆盖"操作,覆盖后原文件将无法恢复,您可以做好备份后操作。</el-link>
|
|
|
+ </div>
|
|
|
|
|
|
- <el-button type="danger" style="position: absolute; bottom: 20px; right: 10px;" @click="exportFile()" :loading="exportLoading">开始处理</el-button>
|
|
|
+ <el-button type="danger" style="position: absolute; top: 40px; right: 10px;" @click="exportFile()" :loading="exportLoading">开始处理</el-button>
|
|
|
</div>
|
|
|
-
|
|
|
</div>
|
|
|
|
|
|
|
|
@@ -133,6 +148,7 @@ import electronApi from '@/utils/electronApi';
|
|
|
import softUpdate from './update.vue';
|
|
|
import softHeader from './header.vue';
|
|
|
import pjson from '/package.json'
|
|
|
+import fse from 'fs-extra'
|
|
|
const fg = require('fast-glob');
|
|
|
|
|
|
let separator = '';
|
|
@@ -155,6 +171,7 @@ export default {
|
|
|
fileList: [], // 文件列表
|
|
|
downloadDir: os.userInfo().homedir + separator + "Downloads",
|
|
|
searchDir: '',
|
|
|
+ coverFile: '',
|
|
|
handleData: {
|
|
|
type: '1',
|
|
|
rule: '1',
|
|
@@ -164,6 +181,7 @@ export default {
|
|
|
searchLoading: false,
|
|
|
tabLoading: false,
|
|
|
times: 0,
|
|
|
+ subFolder: true,
|
|
|
|
|
|
dowloadModel: false,
|
|
|
finishModel: false,
|
|
@@ -223,20 +241,38 @@ export default {
|
|
|
},
|
|
|
// 清除列表
|
|
|
clearList() {
|
|
|
-
|
|
|
+ this.$confirm('确认重置参数并清空搜索结果?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ this.searchDir = '';
|
|
|
+ this.handleData = {
|
|
|
+ type: '1',
|
|
|
+ rule: '1',
|
|
|
+ findText: '',
|
|
|
+ };
|
|
|
+ this.fileList = [];
|
|
|
+ }).catch(() => {
|
|
|
+
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 忽略文件
|
|
|
+ delFile(rowIndex){
|
|
|
+ this.fileList.splice(rowIndex, 1);
|
|
|
},
|
|
|
async pickFile(){
|
|
|
+ this.$refs['cover-input'].blur();
|
|
|
const spinLoad = this.$loading();
|
|
|
- await electronApi.call('pickFile', ['*',true]).then(async(files) =>{
|
|
|
+ await electronApi.call('pickFile', ['*', false]).then(async(files) =>{
|
|
|
if(files.length > 0){
|
|
|
-
|
|
|
+ this.coverFile = files[0];
|
|
|
}
|
|
|
spinLoad.close();
|
|
|
}).catch(err => {
|
|
|
spinLoad.close();
|
|
|
});
|
|
|
},
|
|
|
-
|
|
|
// 软件更新
|
|
|
updateSoft(){
|
|
|
this.$refs.updateRef.updateSoft();
|
|
@@ -248,11 +284,11 @@ export default {
|
|
|
// 搜索
|
|
|
search(){
|
|
|
if(!this.searchDir){
|
|
|
- this.$message({message: '请选择搜索目录' , type: 'warning'});
|
|
|
+ this.$message({message: '请选择搜索目录' , type: 'error'});
|
|
|
return false;
|
|
|
}
|
|
|
if(!this.handleData.findText){
|
|
|
- this.$message({message: '请输入要查找的文件搜索清单' , type: 'warning'});
|
|
|
+ this.$message({message: '请输入要查找的文件搜索清单' , type: 'error'});
|
|
|
return false;
|
|
|
}
|
|
|
(async () => {
|
|
@@ -271,38 +307,43 @@ export default {
|
|
|
}
|
|
|
let params = paramArr.join(',');
|
|
|
let ruleStr = '';
|
|
|
+ let subStr = '/';
|
|
|
+ if(this.subFolder){ // 是否匹配子文件夹内文件
|
|
|
+ subStr = '/**/'
|
|
|
+ }
|
|
|
switch(this.handleData.rule){
|
|
|
case '1': //相同文件名
|
|
|
if(paramArr.length > 1){
|
|
|
- ruleStr = searchDir + '/**/{'+params+'}.*';
|
|
|
+ ruleStr = searchDir + subStr + '{'+params+'}.[!.]+';
|
|
|
}else{
|
|
|
- ruleStr = searchDir + '/**/'+params+'.[!.]+';
|
|
|
+ ruleStr = searchDir + subStr + params+'.[!.]+';
|
|
|
}
|
|
|
break;
|
|
|
case '2': //包含文件名
|
|
|
if(paramArr.length > 1){
|
|
|
- ruleStr = searchDir + '/**/*{'+params+'}*.*';
|
|
|
+ ruleStr = searchDir + subStr + '*{'+params+'}*.[!.]+';
|
|
|
}else{
|
|
|
- ruleStr = searchDir + '/**/*'+params+'*.*';
|
|
|
+ ruleStr = searchDir + subStr + '*'+params+'*.[!.]+';
|
|
|
}
|
|
|
break;
|
|
|
case '3': //文件名格式相同
|
|
|
if(paramArr.length > 1){
|
|
|
- ruleStr = searchDir + '/**/{'+params+'}';
|
|
|
+ ruleStr = searchDir + subStr + '{'+params+'}';
|
|
|
}else{
|
|
|
- ruleStr = searchDir + '/**/'+params;
|
|
|
+ ruleStr = searchDir + subStr + ''+params;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
console.log('----验证规则----', ruleStr);
|
|
|
try{
|
|
|
- const files = await fg([ruleStr], { dot: false });
|
|
|
+ const files = await fg([ruleStr], { dot: true });
|
|
|
let regExp = new RegExp(paramArr.join('|'));
|
|
|
this.fileList = [];
|
|
|
files.map(item => {
|
|
|
let filename = item.substr(item.lastIndexOf('/')+1);
|
|
|
let res = regExp.exec(filename);
|
|
|
this.fileList.push({
|
|
|
+ name: filename,
|
|
|
match: res,
|
|
|
path: item,
|
|
|
status: '1'
|
|
@@ -322,7 +363,7 @@ export default {
|
|
|
// 导出
|
|
|
exportFile(flag) {
|
|
|
let authority = this.$refs.headerRef.authority;
|
|
|
- if (this.handleData.findText) {
|
|
|
+ if (this.fileList.length > 0) {
|
|
|
if (!authority.isAuthority && !flag) { // 非会员点击转换弹出提示框
|
|
|
this.$refs.headerRef.memberModel = true;
|
|
|
this.$refs.headerRef.isClick = true;
|
|
@@ -330,21 +371,66 @@ export default {
|
|
|
} else {
|
|
|
this.$refs.headerRef.memberModel = false;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
this.exportLoading = true;
|
|
|
setTimeout(() => {
|
|
|
this.exportLoading = false;
|
|
|
- }, 1000);
|
|
|
+ }, 3000);
|
|
|
|
|
|
let size = 999999999;
|
|
|
if(!authority.isAuthority){
|
|
|
- size = 5;
|
|
|
+ size = 5000;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ if(!fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)){
|
|
|
+ fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
|
|
|
+ }
|
|
|
+ let newPath = this.downloadDir + separator + pjson.softInfo.softName;
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ for(let i = 0; i < this.fileList.length; i++){
|
|
|
+ if(i < size){
|
|
|
+ let item = this.fileList[i];
|
|
|
+ let newFilePath = newPath + separator + item.name;
|
|
|
+ try {
|
|
|
+ if(this.handleData.type == '1'){ // 复制
|
|
|
+ // fse.copySync(item.path, newFilePath);
|
|
|
+ // item.status = '2';
|
|
|
+
|
|
|
+ fse.copy(item.path, newFilePath).then(() => {
|
|
|
+ console.log('复制成功!')
|
|
|
+ item.status = '2';
|
|
|
+ }).catch(err => {
|
|
|
+ console.error('复制失败', err)
|
|
|
+ item.status = '6';
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if(this.handleData.type == '2'){ // 剪切
|
|
|
+ fse.moveSync(item.path, newFilePath);
|
|
|
+ item.status = '3'
|
|
|
+ }
|
|
|
+
|
|
|
+ if(this.handleData.type == '3'){ // 删除
|
|
|
+ fse.removeSync(item.path);
|
|
|
+ item.status = '4'
|
|
|
+ }
|
|
|
+
|
|
|
+ if(this.handleData.type == '4'){ // 覆盖
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (err) {
|
|
|
+ console.error(err);
|
|
|
+ item.status = '6';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 100);
|
|
|
+
|
|
|
}
|
|
|
},
|
|
|
+
|
|
|
// 是否包含特殊字符
|
|
|
containsAnyChar(str, charsArray) {
|
|
|
for (let i = 0; i < charsArray.length; i++) {
|