|
@@ -31,7 +31,7 @@
|
|
|
<!-- 特殊字符匹配问题!!!! -->
|
|
|
|
|
|
<div style="position: relative; margin: 10px 0;">
|
|
|
- <el-button type="danger" size="small" style="position: absolute; right: 0; top: 0;" :loading="searchLoading" @click="search()">搜索</el-button>
|
|
|
+ <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>
|
|
@@ -54,42 +54,42 @@
|
|
|
: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="编号"></vxe-column>
|
|
|
- <vxe-column field="match" title="匹配词" width="150"></vxe-column>
|
|
|
- <vxe-column field="path" title="文件位置"></vxe-column>
|
|
|
- <vxe-column field="status" title="操作" width="80">
|
|
|
+ <vxe-column field="match" title="匹配词" width="100"></vxe-column>
|
|
|
+ <vxe-column field="path" title="文件位置/名称"></vxe-column>
|
|
|
+ <vxe-column field="status" title="操作" width="70" align="center">
|
|
|
<template #default="{ rowIndex }">
|
|
|
- <el-link icon="el-icon-s-release" type="warning" @click="delFile(rowIndex)">忽略</el-link>
|
|
|
+ <el-link icon="el-icon-s-release" type="warning" @click="delFile(rowIndex)" style="font-size: 13px;">忽略</el-link>
|
|
|
</template>
|
|
|
</vxe-column>
|
|
|
- <vxe-column field="status" title="状态" width="100">
|
|
|
+ <vxe-column field="status" title="状态" width="90" align="center">
|
|
|
<template #default="{ row }">
|
|
|
<template v-if="row.status == '1'">
|
|
|
- <i class="el-icon-info" style="font-size: 16px; color: #999;"></i>
|
|
|
- <span>待操作</span>
|
|
|
+ <i class="el-icon-info" style="font-size: 13px; color: #999;"></i>
|
|
|
+ <span style="font-size: 13px;">待操作</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '2'">
|
|
|
- <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
- <span>复制成功</span>
|
|
|
+ <i class="el-icon-success" style="font-size: 13px; color: #19be6b;"></i>
|
|
|
+ <span style="font-size: 13px;">复制成功</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '3'">
|
|
|
- <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
- <span>剪切成功</span>
|
|
|
+ <i class="el-icon-success" style="font-size: 13px; color: #19be6b;"></i>
|
|
|
+ <span style="font-size: 13px;">剪切成功</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '4'">
|
|
|
- <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
- <span>删除成功</span>
|
|
|
+ <i class="el-icon-success" style="font-size: 13px; color: #19be6b;"></i>
|
|
|
+ <span style="font-size: 13px;">删除成功</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '5'">
|
|
|
- <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
- <span>覆盖成功</span>
|
|
|
+ <i class="el-icon-success" style="font-size: 13px; color: #19be6b;"></i>
|
|
|
+ <span style="font-size: 13px;">覆盖成功</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '6'">
|
|
|
- <i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
|
|
|
- <span>处理失败</span>
|
|
|
+ <i class="el-icon-error" style="font-size: 13px; color: #ed4014;"></i>
|
|
|
+ <span style="font-size: 13px;">处理失败</span>
|
|
|
</template>
|
|
|
<template v-if="row.status == '7'">
|
|
|
- <i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
|
|
|
- <span>覆盖失败</span>
|
|
|
+ <i class="el-icon-error" style="font-size: 13px; color: #ed4014;"></i>
|
|
|
+ <span style="font-size: 13px;">覆盖失败</span>
|
|
|
</template>
|
|
|
</template>
|
|
|
</vxe-column>
|
|
@@ -99,10 +99,13 @@
|
|
|
<div style="position: relative; margin-top: 20px;">
|
|
|
<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-input :title="downloadDir" ref="upload-input" readonly size="small" placeholder="选择存储位置" v-model="downloadDir" style="width:291px;" prefix-icon="el-icon-folder"></el-input>
|
|
|
+ <el-button type="primary" size="small" slot="reference" @click="pickPath()">选择</el-button>
|
|
|
<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>
|
|
|
+ <!-- <i class="el-icon-folder-opened" slot="reference" style="padding-left: 5px; cursor: pointer; font-size: 22px; vertical-align: middle;" @click="openFolder()"></i> -->
|
|
|
+ <el-button type="primary" size="small" slot="reference" @click="openFolder()">打开</el-button>
|
|
|
</el-popover>
|
|
|
+ <el-checkbox style="margin-left: 20px;" v-model="macthWords" size="mini">匹配词分类存储</el-checkbox>
|
|
|
</div>
|
|
|
<div class="handle-item" v-if="handleData.type == '4'">
|
|
|
<label class="handle-label">覆盖文件:</label>
|
|
@@ -171,8 +174,8 @@ export default {
|
|
|
imgUrl: this.$api.imgUrl,
|
|
|
menuIndex: '1', // 重命名类型 1 or 2
|
|
|
fileList: [], // 文件列表
|
|
|
- downloadDir: os.userInfo().homedir + separator + "Downloads",
|
|
|
- searchDir: '', //'D:\\桌面\\images',
|
|
|
+ downloadDir: '', //os.userInfo().homedir + separator + "Downloads",
|
|
|
+ searchDir: '', //'D:\\桌面\\images',
|
|
|
coverFile: '',
|
|
|
handleData: {
|
|
|
type: '1',
|
|
@@ -184,24 +187,18 @@ export default {
|
|
|
tabLoading: false,
|
|
|
times: 0,
|
|
|
subFolder: true,
|
|
|
+ macthWords: false,
|
|
|
|
|
|
dowloadModel: false,
|
|
|
finishModel: false,
|
|
|
loadingModal: false,
|
|
|
|
|
|
- execlimit: 10,
|
|
|
+ execlimit: 10000,
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
|
this.$refs.updateRef.updateSoft(true);
|
|
|
|
|
|
- let __dirname = os.userInfo().homedir;
|
|
|
- if(fs.existsSync(__dirname + separator + "Desktop")){
|
|
|
- this.downloadDir = __dirname + separator + "Desktop";
|
|
|
- } else{
|
|
|
- this.downloadDir = __dirname + separator + "Downloads";
|
|
|
- }
|
|
|
-
|
|
|
// 打开浏览器
|
|
|
const { shell } = require('electron');
|
|
|
const links = document.querySelectorAll('a[href]');
|
|
@@ -238,12 +235,8 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
// 打开自定义目录
|
|
|
- openFolder(str){
|
|
|
+ openFolder(){
|
|
|
let path = this.downloadDir;
|
|
|
- if(!fs.existsSync(path + separator + pjson.softInfo.softName)){
|
|
|
- fs.mkdirSync(path + separator + pjson.softInfo.softName);
|
|
|
- }
|
|
|
- path = path + separator + pjson.softInfo.softName;
|
|
|
electronApi.call('showItemInfolder',[path+'\\tty.tty'])
|
|
|
},
|
|
|
// 清除列表
|
|
@@ -291,7 +284,7 @@ export default {
|
|
|
// 搜索
|
|
|
search(){
|
|
|
if(!this.searchDir){
|
|
|
- this.$message({message: '请选择搜索目录' , type: 'error'});
|
|
|
+ this.$message({message: '请先选择搜索目录' , type: 'error'});
|
|
|
return false;
|
|
|
}
|
|
|
if(!this.handleData.findText){
|
|
@@ -306,13 +299,20 @@ export default {
|
|
|
}, 2000)
|
|
|
let findText = this.handleData.findText.split('\n');
|
|
|
let searchDir = this.searchDir.replace(/\\/g, '/');
|
|
|
- let paramArr = [];
|
|
|
+ let paramArr = []; // 匹配规则1
|
|
|
+ let paramArr2 = []; // 匹配规则2 - 带后缀名的文件,带.
|
|
|
for(let i=0; i< findText.length; i++){
|
|
|
if(findText[i].trim()){
|
|
|
- paramArr.push(this.filterReg(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){ // 是否匹配子文件夹内文件
|
|
@@ -320,34 +320,31 @@ export default {
|
|
|
}
|
|
|
switch(this.handleData.rule){
|
|
|
case '1': //相同文件名
|
|
|
- if(paramArr.length > 1){
|
|
|
- ruleStr.push(searchDir + subStr + '{'+params+'}.[!.]+');
|
|
|
- ruleStr.push(searchDir + subStr + '{'+params+'}');
|
|
|
- }else{
|
|
|
- ruleStr.push(searchDir + subStr + params+'.[!.]+');
|
|
|
- ruleStr.push(searchDir + subStr + params);
|
|
|
+ if(paramArr.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}?(.[!.]+)');
|
|
|
+ }
|
|
|
+ if(paramArr2.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params2 + ',<}.[!.]+');
|
|
|
}
|
|
|
break;
|
|
|
case '2': //包含文件名
|
|
|
- if(paramArr.length > 1){
|
|
|
- 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 + '}[!.]+');
|
|
|
- }else{
|
|
|
- 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(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 > 1){
|
|
|
- ruleStr.push(searchDir + subStr + '{'+params+'}');
|
|
|
- }else{
|
|
|
- ruleStr.push(searchDir + subStr + ''+params);
|
|
|
+ if(paramArr.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params + ',<}');
|
|
|
+ }
|
|
|
+ if(paramArr2.length > 0){
|
|
|
+ ruleStr.push(searchDir + subStr + '{' + params2 + ',<}');
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
@@ -355,6 +352,7 @@ export default {
|
|
|
try{
|
|
|
const files = await fg(ruleStr, { dot: 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);
|
|
@@ -365,6 +363,9 @@ export default {
|
|
|
suffix = '';
|
|
|
}
|
|
|
let res = regExp.exec(filename);
|
|
|
+ if(!res[0]){
|
|
|
+ res = regExp2.exec(filename);
|
|
|
+ }
|
|
|
this.fileList.push({
|
|
|
title: title,
|
|
|
suffix: suffix, // 带.
|
|
@@ -406,15 +407,19 @@ export default {
|
|
|
size = this.execlimit;
|
|
|
}
|
|
|
|
|
|
- if(!fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)){
|
|
|
- fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
|
|
|
+ if(this.handleData.type != '4' && !this.downloadDir){
|
|
|
+ this.$notify.error({
|
|
|
+ title: '提示',
|
|
|
+ message: '请选择文件存储位置后再操作!'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
}
|
|
|
- let newPath = this.downloadDir + separator + pjson.softInfo.softName;
|
|
|
+ let newPath = this.downloadDir;
|
|
|
|
|
|
if(this.handleData.type == '4' && !this.coverFile){
|
|
|
this.$notify.error({
|
|
|
title: '提示',
|
|
|
- message: '请选择覆盖文件后再操作'
|
|
|
+ message: '请选择覆盖文件后再操作!'
|
|
|
});
|
|
|
return false;
|
|
|
}
|
|
@@ -425,7 +430,25 @@ export default {
|
|
|
for(let i = 0; i < this.fileList.length; i++){
|
|
|
if(i < size){
|
|
|
let item = this.fileList[i];
|
|
|
- let newFilePath = newPath + separator + item.name;
|
|
|
+ let middlePath = separator;
|
|
|
+ if(this.macthWords){
|
|
|
+ middlePath = separator + item.match + separator;
|
|
|
+ try{
|
|
|
+ fse.ensureDirSync(newPath + separator + item.match);
|
|
|
+ }catch(e){
|
|
|
+ let str = e.toString();
|
|
|
+ if(str.indexOf('already exists') > -1 && str.indexOf(item.match) > -1){
|
|
|
+ this.$notify.error({
|
|
|
+ title: '提示',
|
|
|
+ message: '无法创建目录'+newPath + separator + item.match+',因为同名文件或目录已存在!'
|
|
|
+ });
|
|
|
+ this.tabLoading = false;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ let newFilePath = newPath + middlePath + item.name;
|
|
|
try {
|
|
|
if(this.handleData.type == '1'){ // 复制
|
|
|
try{
|
|
@@ -434,7 +457,7 @@ export default {
|
|
|
}catch(e){
|
|
|
let str = e.toString();
|
|
|
if(str.indexOf('already exists') > -1 && str.indexOf(item.name) > -1){
|
|
|
- newFilePath = newPath + separator + item.title + '重复文件' + uuidv4().substr(0, 18) + i.toString() + item.suffix;
|
|
|
+ newFilePath = newPath + middlePath + item.title + '重复文件' + uuidv4().substr(0, 18) + i.toString() + item.suffix;
|
|
|
fse.copy(item.path, newFilePath).then(() => {
|
|
|
item.status = '2';
|
|
|
}).catch(err => {
|
|
@@ -451,7 +474,7 @@ export default {
|
|
|
}catch(e){
|
|
|
let str = e.toString();
|
|
|
if(str.indexOf('already exists') > -1){
|
|
|
- newFilePath = newPath + separator + item.title + '重复文件' + uuidv4().substr(0, 18) + i.toString() + item.suffix;
|
|
|
+ newFilePath = newPath + middlePath + item.title + '重复文件' + uuidv4().substr(0, 18) + i.toString() + item.suffix;
|
|
|
fse.move(item.path, newFilePath).then(() => {
|
|
|
item.status = '3';
|
|
|
}).catch(err => {
|