|
@@ -189,7 +189,7 @@
|
|
|
</vxe-table>
|
|
|
<!-- 2、文件夹重命名 -->
|
|
|
<vxe-table
|
|
|
- v-show="['2', '6', '8'].indexOf(menuIndex) > -1"
|
|
|
+ v-show="['2', '6'].indexOf(menuIndex) > -1"
|
|
|
show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :loading="tabLoading"
|
|
|
:loading-config="{icon: 'vxe-icon-indicator roll', text: '文件加载中...'}" :row-config="{isHover: true}"
|
|
|
:edit-config="{trigger: 'click', mode: 'cell'}" :data="dirList" :scroll-y="{enabled: true}">
|
|
@@ -363,6 +363,60 @@
|
|
|
</template>
|
|
|
</vxe-column>
|
|
|
</vxe-table>
|
|
|
+
|
|
|
+ <!-- 8、文件夹合并和提取文件 -->
|
|
|
+ <vxe-table
|
|
|
+ v-show="menuIndex == '8'"
|
|
|
+ show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :loading="tabLoading"
|
|
|
+ :loading-config="{icon: 'vxe-icon-indicator roll', text: '文件加载中...'}" :row-config="{isHover: true}"
|
|
|
+ :edit-config="{trigger: 'click', mode: 'cell'}" :data="dirList" :scroll-y="{enabled: true}">
|
|
|
+ <vxe-column field="name" :title="'文件夹名'+'(' + dirList.length + ')'"></vxe-column>
|
|
|
+ <template #edit="{ row }">
|
|
|
+ <vxe-input v-model="row.newName" type="text" placeholder="请输入新文件夹名"></vxe-input>
|
|
|
+ </template>
|
|
|
+ </vxe-column>
|
|
|
+ <vxe-column field="path" title="文件位置" width="200"></vxe-column>
|
|
|
+ <vxe-column field="status" title="状态" width="180">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <template v-if="row.status == '1'">
|
|
|
+ <i class="el-icon-info" style="font-size: 16px; color: #999;"></i>
|
|
|
+ <span>待操作</span>
|
|
|
+ </template>
|
|
|
+ <template v-if="row.status == '2'">
|
|
|
+ <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
+ <span>处理成功</span>
|
|
|
+ </template>
|
|
|
+ <template v-if="row.status == '3'">
|
|
|
+ <i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
|
|
|
+ <span>修改失败</span>
|
|
|
+ </template>
|
|
|
+ <template v-if="row.status == '4'">
|
|
|
+ <i class="el-icon-warning" style="font-size: 16px; color: #ff9900;"></i>
|
|
|
+ <span>文件被修改</span>
|
|
|
+ </template>
|
|
|
+ <template v-if="row.status == '5'">
|
|
|
+ <i class="el-icon-warning" style="font-size: 16px; color: #ff9900;"></i>
|
|
|
+ <span>文件已存在</span>
|
|
|
+ </template>
|
|
|
+ <template v-if="row.status == '6'">
|
|
|
+ <template v-if="row.searchList && row.searchList.length > row.total">
|
|
|
+ <i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
|
|
|
+ <span>提取中<span v-if="row.searchList">,共{{row.searchList.length}}个,{{row.total}}</span></span>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
|
|
|
+ <span>提取成功<span v-if="row.searchList">,共{{row.searchList.length}}个,{{row.total}}</span></span>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </vxe-column>
|
|
|
+ <vxe-column title="操作" width="88">
|
|
|
+ <template #default="{ row, rowIndex }">
|
|
|
+ <i class="el-icon-delete cur-pointer" style="font-size: 20px;" @click="delFile(rowIndex, 'dir')"></i>
|
|
|
+ </template>
|
|
|
+ </vxe-column>
|
|
|
+ </vxe-table>
|
|
|
+
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
@@ -823,6 +877,10 @@ import xlsx from 'node-xlsx';
|
|
|
import { setTimeout } from 'timers';
|
|
|
const child = require("child_process");
|
|
|
const officegen = require('officegen');
|
|
|
+import fse from 'fs-extra';
|
|
|
+const fg = require('fast-glob');
|
|
|
+import { v4 as uuidv4 } from 'uuid';
|
|
|
+import search from '@/utils/search.js';
|
|
|
|
|
|
let separator = '';
|
|
|
if (os.platform == 'linux') {
|
|
@@ -1106,7 +1164,7 @@ export default {
|
|
|
this.fileTimeList = [];
|
|
|
this.filexlsxPath = "";
|
|
|
this.filexlsxData = [];
|
|
|
- }else if(['2', '4', '6'].indexOf(this.menuIndex) > -1){
|
|
|
+ }else if(['2', '4', '6', '8'].indexOf(this.menuIndex) > -1){
|
|
|
this.backDirList = [];
|
|
|
this.dirList = [];
|
|
|
this.dirTimeList = [];
|
|
@@ -1160,7 +1218,9 @@ export default {
|
|
|
name: dirs[i].slice(lastIndex+1),
|
|
|
newName: dirs[i].slice(lastIndex+1),
|
|
|
path: dirs[i].slice(0, lastIndex+1),
|
|
|
- status: "1"
|
|
|
+ status: "1",
|
|
|
+ searchList: [],
|
|
|
+ total: 0
|
|
|
};
|
|
|
|
|
|
if(this.dirList.length == 0){
|
|
@@ -1857,28 +1917,124 @@ export default {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ if(this.dirList.length === 0){ //长度为0 不执行任何操作
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
for(let i=0;i < this.dirList.length; i++){
|
|
|
let item = this.dirList[i];
|
|
|
|
|
|
- fs.mkdir(this.mergeData.newPath + separator + item.name, (err) => {
|
|
|
- if(err){
|
|
|
- this.dirList[i].status = '5';
|
|
|
- if(err.toString().indexOf('EBUSY') > -1){
|
|
|
- this.$notify({title: '提示', message: "文件被占用,请关闭后重试!", type: 'warning'});
|
|
|
- thisdirList[i].status = '3';
|
|
|
- }else if(err.toString().indexOf('EXIST') > -1){
|
|
|
+ if(this.mergeData.type == 'merge'){ // 合并目录
|
|
|
+ fs.mkdir(this.mergeData.newPath + separator + item.name, (err) => {
|
|
|
+ if(err){
|
|
|
+ this.dirList[i].status = '5';
|
|
|
+ if(err.toString().indexOf('EBUSY') > -1){
|
|
|
+ this.$notify({title: '提示', message: "文件被占用,请关闭后重试!", type: 'warning'});
|
|
|
+ thisdirList[i].status = '3';
|
|
|
+ }else if(err.toString().indexOf('EXIST') > -1){
|
|
|
+ this.dirList[i].status = '2';
|
|
|
+ }
|
|
|
+ }else{
|
|
|
this.dirList[i].status = '2';
|
|
|
}
|
|
|
- }else{
|
|
|
- this.dirList[i].status = '2';
|
|
|
+ });
|
|
|
+ }else if(this.mergeData.type == 'extract'){ // 提取文件
|
|
|
+ this.dirList[i].status = '6';
|
|
|
+ switch(this.mergeData.extractType){
|
|
|
+ case "1": // 全部提取
|
|
|
+ this.traverseDirectoryIteratively(i, this.mergeData.newPath, 'folder').catch(console.error);
|
|
|
+ break;
|
|
|
+ case "2": // 按类型提取
|
|
|
+
|
|
|
+ break;
|
|
|
+ case "3": // 按名称提取
|
|
|
+ (async () => {
|
|
|
+ let ruleStr = [];
|
|
|
+ let searchDir = item.path.replace(/\\/g, '/') + item.name;
|
|
|
+
|
|
|
+ if(this.mergeData.fileName.indexOf('.') > -1){
|
|
|
+ ruleStr.push(searchDir + '/**/' + '*{' + this.mergeData.fileName + ',<}*.[!.]+');
|
|
|
+ }else{
|
|
|
+ ruleStr.push(searchDir + '/**/' + '*{' + this.mergeData.fileName + ',<}*.[!.]+');
|
|
|
+ ruleStr.push(searchDir + '/**/' + '{' + this.mergeData.fileName + ',<}');
|
|
|
+ ruleStr.push(searchDir + '/**/' + '[!.]+{' + this.mergeData.fileName + ',<}');
|
|
|
+ ruleStr.push(searchDir + '/**/' + '{' + this.mergeData.fileName + ',<}[!.]+');
|
|
|
+ ruleStr.push(searchDir + '/**/' + '[!.]+{' + this.mergeData.fileName + ',<}[!.]+');
|
|
|
+ }
|
|
|
+ const files = await fg(ruleStr, { dot: true });
|
|
|
+ this.dirList[i].searchList = files;
|
|
|
+
|
|
|
+ this.traverseDirectoryIteratively(i, this.mergeData.newPath, 'files').catch(console.error);
|
|
|
+ })();
|
|
|
+ break;
|
|
|
+ case "4": // 按后缀提取
|
|
|
+ (async () => {
|
|
|
+ let ruleStr = [];
|
|
|
+ let searchDir = item.path.replace(/\\/g, '/') + item.name;
|
|
|
+ ruleStr.push(searchDir + '/**/' + '*.' + this.mergeData.suffixName);
|
|
|
+ const files = await fg(ruleStr, { dot: true });
|
|
|
+ this.dirList[i].searchList = files;
|
|
|
+ })();
|
|
|
+ break;
|
|
|
}
|
|
|
- });
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 按文件夹提取文件
|
|
|
+ async traverseDirectoryIteratively(index, newPath, type) {
|
|
|
+ const fs = require('fs').promises;
|
|
|
+ if(!this.dirList[index].total){
|
|
|
+ this.dirList[index].total = 0;
|
|
|
}
|
|
|
|
|
|
+ if(type == 'folder'){ //提取目录里面的文件
|
|
|
+ let directoryPath = this.dirList[index].path + this.dirList[index].name;
|
|
|
+ const queue = [directoryPath]; // 使用数组作为队列
|
|
|
+ const visited = new Set(); // 用于跟踪已访问的目录,防止循环引用
|
|
|
+
|
|
|
+ while (queue.length > 0) {
|
|
|
+ const currentPath = queue.shift();
|
|
|
+
|
|
|
+ if (!visited.has(currentPath)) {
|
|
|
+ visited.add(currentPath);
|
|
|
+
|
|
|
+ try {
|
|
|
+ const entries = await fs.readdir(currentPath,{ withFileTypes: true });
|
|
|
+ for (const entry of entries) {
|
|
|
+ const fullPath = path.join(currentPath, entry.name);
|
|
|
+
|
|
|
+ if (entry.isDirectory()) {
|
|
|
+ queue.push(fullPath); // 将子目录添加到队列中以便后续遍历
|
|
|
+ } else if (entry.isFile()) {
|
|
|
+ // 处理文件
|
|
|
+ console.log(`Found file: ${fullPath}`);
|
|
|
+ let targetPath = newPath + separator + entry.name;
|
|
|
+ await fs.copyFile(fullPath, targetPath);
|
|
|
+ this.dirList[index].total += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error(`Unable to scan directory: ${currentPath}, Error: ${err}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else if(type == 'files'){
|
|
|
+ try {
|
|
|
+ for (const entry of this.dirList[index].searchList) {
|
|
|
+ let filename = entry.substr(entry.lastIndexOf('/')+1);
|
|
|
+ let targetPath = newPath + separator + filename;
|
|
|
+ await fs.copyFile(entry, targetPath);
|
|
|
+ this.dirList[index].total += 1;
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ console.error(`Unable to scan directory: Error: ${err}`);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
},
|
|
|
|
|
|
- // 提取文件、文件夹名称
|
|
|
+ // 提取文件/文件夹名称
|
|
|
extratFile(authority, size){
|
|
|
let nameCont = [];
|
|
|
let list = [];
|