From 04c89ffadd65d62af387553e923dfe382959fb12 Mon Sep 17 00:00:00 2001 From: fanxb Date: Mon, 28 Jun 2021 18:07:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=9F=BA=E6=9C=AC=E5=8F=AF=E4=BD=BF?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openRenamerBackend/api/RenamerApi.ts | 22 +++++++ openRenamerBackend/service/RenamerService.ts | 32 ++++++++-- openRenamerBackend/vo/FileObj.ts | 21 ++++++- openRenamerBackend/vo/rules/DeleteRule.ts | 44 +++++++++++++- openRenamerBackend/vo/rules/InsertRule.ts | 31 +++++++++- openRenamerBackend/vo/rules/RuleInterface.ts | 2 +- .../vo/rules/SerializationRule.ts | 37 +++++++++++- .../src/components/rules/DeleteRule.vue | 2 +- openRenamerFront/src/views/home/Home.vue | 60 ++++++++++++++++--- 9 files changed, 230 insertions(+), 21 deletions(-) create mode 100644 openRenamerBackend/api/RenamerApi.ts diff --git a/openRenamerBackend/api/RenamerApi.ts b/openRenamerBackend/api/RenamerApi.ts new file mode 100644 index 0000000..1152043 --- /dev/null +++ b/openRenamerBackend/api/RenamerApi.ts @@ -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; diff --git a/openRenamerBackend/service/RenamerService.ts b/openRenamerBackend/service/RenamerService.ts index 0210986..13893ff 100644 --- a/openRenamerBackend/service/RenamerService.ts +++ b/openRenamerBackend/service/RenamerService.ts @@ -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, ruleList): Promise> { - let obj = new RuleObj({}); - return null; + static async preview(fileList: Array, ruleList: Array): Promise> { + let ruleObjs = ruleList.map(item => new RuleObj(item)); + let newNameSet: Set = new Set(); + 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, changedFileList: Array) { + 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); + } } diff --git a/openRenamerBackend/vo/FileObj.ts b/openRenamerBackend/vo/FileObj.ts index 1ee7ba4..41aaa1c 100644 --- a/openRenamerBackend/vo/FileObj.ts +++ b/openRenamerBackend/vo/FileObj.ts @@ -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; diff --git a/openRenamerBackend/vo/rules/DeleteRule.ts b/openRenamerBackend/vo/rules/DeleteRule.ts index 5f24bcf..aacd042 100644 --- a/openRenamerBackend/vo/rules/DeleteRule.ts +++ b/openRenamerBackend/vo/rules/DeleteRule.ts @@ -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; + } } diff --git a/openRenamerBackend/vo/rules/InsertRule.ts b/openRenamerBackend/vo/rules/InsertRule.ts index 7f1d92c..9f04d58 100644 --- a/openRenamerBackend/vo/rules/InsertRule.ts +++ b/openRenamerBackend/vo/rules/InsertRule.ts @@ -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; } } \ No newline at end of file diff --git a/openRenamerBackend/vo/rules/RuleInterface.ts b/openRenamerBackend/vo/rules/RuleInterface.ts index b921ae5..84a6b0f 100644 --- a/openRenamerBackend/vo/rules/RuleInterface.ts +++ b/openRenamerBackend/vo/rules/RuleInterface.ts @@ -2,5 +2,5 @@ import FileObj from "../FileObj"; export default interface RuleInterface { - deal(file: FileObj): string; + deal(file: FileObj): void; } \ No newline at end of file diff --git a/openRenamerBackend/vo/rules/SerializationRule.ts b/openRenamerBackend/vo/rules/SerializationRule.ts index 7c7cb0a..1df7114 100644 --- a/openRenamerBackend/vo/rules/SerializationRule.ts +++ b/openRenamerBackend/vo/rules/SerializationRule.ts @@ -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; } } \ No newline at end of file diff --git a/openRenamerFront/src/components/rules/DeleteRule.vue b/openRenamerFront/src/components/rules/DeleteRule.vue index fe6870c..a61be36 100644 --- a/openRenamerFront/src/components/rules/DeleteRule.vue +++ b/openRenamerFront/src/components/rules/DeleteRule.vue @@ -56,7 +56,7 @@ 直到末尾 diff --git a/openRenamerFront/src/views/home/Home.vue b/openRenamerFront/src/views/home/Home.vue index c6f6ad9..d9915ed 100644 --- a/openRenamerFront/src/views/home/Home.vue +++ b/openRenamerFront/src/views/home/Home.vue @@ -4,6 +4,7 @@ >新增文件 预览 + 重命名