feat:基本可使用
This commit is contained in:
parent
25423fd464
commit
04c89ffadd
22
openRenamerBackend/api/RenamerApi.ts
Normal file
22
openRenamerBackend/api/RenamerApi.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { Context } from "koa";
|
||||
import RenamerService from "../service/RenamerService";
|
||||
|
||||
const router = {};
|
||||
|
||||
/**
|
||||
* 预览文件修改后的状态
|
||||
*/
|
||||
router["POST /renamer/preview"] = async function (ctx: Context) {
|
||||
ctx.body = await RenamerService.preview(ctx.request.body.fileList, ctx.request.body.ruleList);
|
||||
};
|
||||
|
||||
/**
|
||||
* 预览文件修改后的状态
|
||||
*/
|
||||
router["POST /renamer/submit"] = async function (ctx: Context) {
|
||||
ctx.body = await RenamerService.rename(ctx.request.body.fileList, ctx.request.body.changedFileList);
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default router;
|
@ -2,15 +2,37 @@ import config from '../config';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs-extra';
|
||||
|
||||
import ProcessHelper from '../util/ProcesHelper';
|
||||
import FileObj from '../vo/FileObj';
|
||||
import RuleObj from 'vo/RuleObj';
|
||||
import RuleObj from '../vo/RuleObj';
|
||||
import DeleteRule from '../vo/rules/DeleteRule';
|
||||
import RuleInterface from '../vo/rules/RuleInterface';
|
||||
|
||||
|
||||
class RenamerService {
|
||||
static async readPath(fileList: Array<FileObj>, ruleList): Promise<Array<FileObj>> {
|
||||
let obj = new RuleObj({});
|
||||
return null;
|
||||
static async preview(fileList: Array<FileObj>, ruleList: Array<any>): Promise<Array<FileObj>> {
|
||||
let ruleObjs = ruleList.map(item => new RuleObj(item));
|
||||
let newNameSet: Set<string> = new Set<string>();
|
||||
for (let i in fileList) {
|
||||
let obj = fileList[i];
|
||||
ruleObjs.forEach(item => (item.data as RuleInterface).deal(obj));
|
||||
if (newNameSet.has(obj.name)) {
|
||||
obj.errorMessage = "重名";
|
||||
}
|
||||
newNameSet.add(obj.name);
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
static async rename(fileList: Array<FileObj>, changedFileList: Array<FileObj>) {
|
||||
for (let i in fileList) {
|
||||
let old = fileList[i];
|
||||
let oldPath = path.join(fileList[i].path, fileList[i].name);
|
||||
let newPath = path.join(changedFileList[i].path, changedFileList[i].name);
|
||||
if ((await fs.pathExists(newPath))) {
|
||||
throw new Error("此路径已存在:" + newPath);
|
||||
}
|
||||
await fs.rename(oldPath, newPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +1,17 @@
|
||||
import * as pathUtil from "path";
|
||||
export default class FileObj {
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 拓展名
|
||||
*/
|
||||
expandName: string;
|
||||
/**
|
||||
* 去掉拓展名后的名字
|
||||
*/
|
||||
realName: string;
|
||||
/**
|
||||
* 所属路径
|
||||
*/
|
||||
@ -11,6 +20,10 @@ export default class FileObj {
|
||||
* 是否文件夹
|
||||
*/
|
||||
isFolder: boolean;
|
||||
/**
|
||||
* 重命名错误原因
|
||||
*/
|
||||
errorMessage: string;
|
||||
/**
|
||||
* 创建时间ms
|
||||
*/
|
||||
@ -21,8 +34,14 @@ export default class FileObj {
|
||||
updatedTime: number;
|
||||
|
||||
|
||||
constructor(name, path, isFolder, createdTime, updatedTime) {
|
||||
constructor(name: string, path, isFolder, createdTime, updatedTime) {
|
||||
this.name = name;
|
||||
this.expandName = pathUtil.extname(name);
|
||||
if (this.expandName.length > 0) {
|
||||
this.realName = name.substring(0, name.lastIndexOf("."));
|
||||
} else {
|
||||
this.realName = name;
|
||||
}
|
||||
this.path = path;
|
||||
this.isFolder = isFolder;
|
||||
this.createdTime = createdTime;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import RuleInterface from "./RuleInterface";
|
||||
import FileObj from "../FileObj";
|
||||
import path from 'path';
|
||||
|
||||
export default class DeleteRule implements RuleInterface {
|
||||
/**
|
||||
@ -29,8 +30,33 @@ export default class DeleteRule implements RuleInterface {
|
||||
|
||||
|
||||
|
||||
deal(file: FileObj): string {
|
||||
return null;
|
||||
deal(file: FileObj): void {
|
||||
if (this.type === 'deleteAll') {
|
||||
file.realName = "";
|
||||
if (!this.ignorePostfix) {
|
||||
file.expandName = "";
|
||||
}
|
||||
} else {
|
||||
let str = file.realName + (this.ignorePostfix ? "" : file.expandName);
|
||||
let startIndex = this.start.calIndex(str);
|
||||
let endIndex = this.end.calIndex(str);
|
||||
if (startIndex < 0 || endIndex < 0) {
|
||||
return;
|
||||
}
|
||||
str = str.substring(0, startIndex) + str.substring(endIndex + 1);
|
||||
if (this.ignorePostfix) {
|
||||
file.realName = str;
|
||||
} else {
|
||||
file.expandName = path.extname(str);
|
||||
if (file.expandName.length > 0) {
|
||||
file.realName = str.substring(0, str.lastIndexOf("."));
|
||||
} else {
|
||||
file.realName = str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.name = file.realName + file.expandName;
|
||||
}
|
||||
|
||||
}
|
||||
@ -49,4 +75,18 @@ class DeleteRuleItem {
|
||||
this.type = data.type;
|
||||
this.value = data.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算位置
|
||||
*/
|
||||
calIndex(str: string): number {
|
||||
if (this.type === 'location') {
|
||||
return parseInt(this.value) - 1;
|
||||
} else if (this.type === 'text') {
|
||||
return str.indexOf(this.value);
|
||||
} else if (this.type === 'end') {
|
||||
return str.length - 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import RuleInterface from "./RuleInterface";
|
||||
import FileObj from "../FileObj";
|
||||
import path from 'path';
|
||||
|
||||
export default class InsertRule implements RuleInterface {
|
||||
|
||||
@ -33,7 +34,33 @@ export default class InsertRule implements RuleInterface {
|
||||
}
|
||||
|
||||
|
||||
deal(file: FileObj): string {
|
||||
return null;
|
||||
deal(file: FileObj): void {
|
||||
let str = this.ignorePostfix ? file.realName : file.name;
|
||||
switch (this.type) {
|
||||
case "front":
|
||||
str = this.insertContent + str;
|
||||
break;
|
||||
case "backend":
|
||||
str = str + this.insertContent;
|
||||
break;
|
||||
case "at":
|
||||
let index = this.atIsRightToleft ? str.length - this.atInput + 1 : this.atInput - 1;
|
||||
str = str.substring(0, index) + this.insertContent + str.substring(index);
|
||||
break;
|
||||
case "replace":
|
||||
str = this.insertContent;
|
||||
break;
|
||||
}
|
||||
if (this.ignorePostfix) {
|
||||
file.realName = str;
|
||||
} else {
|
||||
file.expandName = path.extname(str);
|
||||
if (file.expandName.length > 0) {
|
||||
file.realName = str.substring(0, str.lastIndexOf("."));
|
||||
} else {
|
||||
file.realName = str;
|
||||
}
|
||||
}
|
||||
file.name = file.realName + file.expandName;
|
||||
}
|
||||
}
|
@ -2,5 +2,5 @@ import FileObj from "../FileObj";
|
||||
|
||||
export default interface RuleInterface {
|
||||
|
||||
deal(file: FileObj): string;
|
||||
deal(file: FileObj): void;
|
||||
}
|
@ -1,11 +1,16 @@
|
||||
import RuleInterface from "./RuleInterface";
|
||||
import FileObj from "../FileObj";
|
||||
import path from 'path';
|
||||
|
||||
export default class InsertRule implements RuleInterface {
|
||||
/**
|
||||
* 开始位置
|
||||
*/
|
||||
start: number;
|
||||
/**
|
||||
* 记录当前的值是多少
|
||||
*/
|
||||
currentIndex: number;
|
||||
/**
|
||||
* 增量
|
||||
*/
|
||||
@ -33,6 +38,7 @@ export default class InsertRule implements RuleInterface {
|
||||
|
||||
constructor(data: any) {
|
||||
this.start = data.start;
|
||||
this.currentIndex = data.start;
|
||||
this.increment = data.increment;
|
||||
this.addZero = data.addZero;
|
||||
this.numLength = data.numLength;
|
||||
@ -41,7 +47,34 @@ export default class InsertRule implements RuleInterface {
|
||||
this.ignorePostfix = data.ignorePostfix;
|
||||
}
|
||||
|
||||
deal(file: FileObj): string {
|
||||
return null;
|
||||
deal(file: FileObj): void {
|
||||
let length = this.currentIndex.toString().length;
|
||||
let numStr = (this.addZero && this.numLength > length ? "0".repeat(this.numLength - length) : "") + this.currentIndex;
|
||||
let str = this.ignorePostfix ? file.realName : file.name;
|
||||
switch (this.insertType) {
|
||||
case "front":
|
||||
str = numStr + str;
|
||||
break;
|
||||
case "backend":
|
||||
str = str + numStr;
|
||||
break;
|
||||
case "at":
|
||||
str = str.substring(0, this.insertValue - 1) + numStr + str.substring(this.insertValue - 1);
|
||||
break;
|
||||
}
|
||||
this.currentIndex += this.increment;
|
||||
|
||||
if (this.ignorePostfix) {
|
||||
file.realName = str;
|
||||
} else {
|
||||
file.expandName = path.extname(str);
|
||||
if (file.expandName.length > 0) {
|
||||
file.realName = str.substring(0, str.lastIndexOf("."));
|
||||
} else {
|
||||
file.realName = str;
|
||||
}
|
||||
}
|
||||
|
||||
file.name = file.realName + file.expandName;
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@
|
||||
<el-radio
|
||||
v-model="ruleObj.data.end.type"
|
||||
label="end"
|
||||
:disabled="untilEnd"
|
||||
:disabled="deleteAll"
|
||||
>直到末尾</el-radio
|
||||
>
|
||||
</div>
|
||||
|
@ -4,6 +4,7 @@
|
||||
>新增文件</el-button
|
||||
>
|
||||
<el-button type="primary" @click="showResult" size="small">预览</el-button>
|
||||
<el-button type="primary" @click="submit" size="small">重命名</el-button>
|
||||
<!-- 规则列表 -->
|
||||
<div class="ruleList">
|
||||
<div class="menu">
|
||||
@ -86,7 +87,8 @@ export default {
|
||||
fileList: [],
|
||||
changedFileList: [],
|
||||
ruleList: [],
|
||||
editRule: null,
|
||||
editRule: null, //当前编辑的规则
|
||||
needPreview: false, //需要点击预览
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -95,12 +97,16 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
addData(data) {
|
||||
//新增文件
|
||||
async addData(data) {
|
||||
console.log(data);
|
||||
this.fileList.push(...data);
|
||||
this.dialogVisible = false;
|
||||
this.needPreview = true;
|
||||
await this.showResult();
|
||||
},
|
||||
ruleAdd(data) {
|
||||
//新增规则
|
||||
async ruleAdd(data) {
|
||||
data.checked = false;
|
||||
data.blocked = false;
|
||||
if (this.editRule != null) {
|
||||
@ -111,16 +117,23 @@ export default {
|
||||
this.ruleList.push(data);
|
||||
}
|
||||
this.ruleDialogShow = false;
|
||||
|
||||
this.needPreview = true;
|
||||
await this.showResult();
|
||||
},
|
||||
//禁用/启用
|
||||
block() {
|
||||
async block() {
|
||||
this.ruleList
|
||||
.filter((item) => item.checked)
|
||||
.forEach((item) => (item.blocked = !item.blocked));
|
||||
this.needPreview = true;
|
||||
await this.showResult();
|
||||
},
|
||||
//删除规则
|
||||
deleteRule() {
|
||||
async deleteRule() {
|
||||
this.ruleList = this.ruleList.filter((item) => !item.checked);
|
||||
this.needPreview = true;
|
||||
await this.showResult();
|
||||
},
|
||||
//编辑规则
|
||||
editClick() {
|
||||
@ -128,9 +141,42 @@ export default {
|
||||
this.ruleDialogShow = true;
|
||||
},
|
||||
//预览结果
|
||||
showResult() {
|
||||
async showResult() {
|
||||
if (this.fileList.length == 0) {
|
||||
this.$message({ message: "请选择文件", type: "warning" });
|
||||
return;
|
||||
}
|
||||
if (this.ruleList.filter((item) => !item.blocked).length == 0) {
|
||||
this.$message({ message: "无生效规则", type: "warning" });
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
HttpUtil.post();
|
||||
let body = {
|
||||
fileList: this.fileList,
|
||||
ruleList: this.ruleList,
|
||||
};
|
||||
this.changedFileList = await HttpUtil.post(
|
||||
"/renamer/preview",
|
||||
null,
|
||||
body
|
||||
);
|
||||
this.needPreview = false;
|
||||
this.loading = false;
|
||||
},
|
||||
async submit() {
|
||||
if (this.changedFileList.filter((item) => item.errorMessage).length > 0) {
|
||||
this.$message({ message: "存在错误,无法执行操作", type: "error" });
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
let body = {
|
||||
fileList: this.fileList,
|
||||
changedFileList: this.changedFileList,
|
||||
};
|
||||
await HttpUtil.post("/renamer/submit", null, body);
|
||||
this.loading = false;
|
||||
this.$message({ message: "重命名成功", type: "success" });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user