From 6d985902de6aa8891081de7dce41fa1f7ca85bf6 Mon Sep 17 00:00:00 2001 From: fanxb Date: Thu, 7 Apr 2022 16:35:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=96=87=E4=BB=B6=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=95=B0=E5=AD=97=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 ++++++--- openRenamerBackend/service/FileService.ts | 53 ++++++++++++++++++++++- openRenamerFront/src/views/home/Home.vue | 53 +++++++++++++++++++++++ 3 files changed, 119 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6caf4ce..1d19b64 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,22 @@ # open-renamer +![](https://qiniupic.fleyx.com/blog/202204071632882.png) + renamer 的开源实现版本,BS 应用,支持全平台部署使用 已打包镜像到 dockerhub 中:[hub.docker.com](https://hub.docker.com/r/fleyx/open-renamer) +已实现如下三种处理规则: + +- 插入 +- 删除 +- 序列化 + +特点: + +- 不限制规则数量 +- 支持将规则保存为模板,方便下次使用 +- 全平台支持,可直接部署在 nas 中,通过浏览器访问 + ## 运行方式: 推荐通过 docker 部署到 nas 中,即可管理 nas 媒体文件 @@ -34,9 +48,3 @@ version: "3.6" # 使用宿主机网络.即可通过"宿主机ip:11004"访问程序 network_mode: host ``` - -已实现如下三种处理规则: - -- 插入 -- 删除 -- 序列化 diff --git a/openRenamerBackend/service/FileService.ts b/openRenamerBackend/service/FileService.ts index d38fea9..b7e0b16 100644 --- a/openRenamerBackend/service/FileService.ts +++ b/openRenamerBackend/service/FileService.ts @@ -5,6 +5,8 @@ import * as fs from 'fs-extra'; import ProcessHelper from '../util/ProcesHelper'; import FileObj from '../vo/FileObj'; +let numberSet = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]); + class FileService { static async readPath(pathStr: string, showHidden: boolean): Promise> { pathStr = decodeURIComponent(pathStr); @@ -46,13 +48,62 @@ class FileService { console.error(e); } } - folderList.sort((a, b) => a.name.localeCompare(b.name)).push(...files.sort((a, b) => a.name.localeCompare(b.name))); + folderList.sort((a, b) => FileService.compareStr(a.name, b.name)).push(...files.sort((a, b) => FileService.compareStr(a.name, b.name))); return folderList; } static async checkExist(pathStr: string) { return await fs.pathExists(pathStr); } + + /** + * 数字字母混合排序 + * @param a str + * @param b str + */ + static compareStr(a: string, b: string) { + let an = a.length; + let bn = b.length; + for (let i = 0; i < an;) { + let charA = FileService.readChar(a, i, an); + let charB = FileService.readChar(b, i, bn); + if (charB.length == 0) { + return 1; + } + if (charA !== charB) { + //读取字符串不相等说明可以得到排序结果 + //如果都为数字,按照数字的比较方法,否则按照字符串比较 + return numberSet.has(charA.charAt(0)) && numberSet.has(charB.charAt(0)) ? Number(charA) - Number(charB) : charA.localeCompare(charB); + } + i += charA.length; + } + //排到最后都没分结果说明相等 + return 0; + } + + /** + * 读取字符,如果字符为数字就读取整个数字 + * @param a a + * @param n 数字长度 + */ + static readChar(a: string, i: number, n: number) { + let res = ""; + for (; i < n; i++) { + let char = a.charAt(i); + if (numberSet.has(char)) { + //如果当前字符是数字,添加到结果中 + res += char; + } else { + //如果不为数字,但是为第一个字符,直接返回,否则返回res + if (res.length == 0) { + return char; + } else { + return res; + } + } + } + return res; + } } export default FileService; diff --git a/openRenamerFront/src/views/home/Home.vue b/openRenamerFront/src/views/home/Home.vue index 95e0129..84a0969 100644 --- a/openRenamerFront/src/views/home/Home.vue +++ b/openRenamerFront/src/views/home/Home.vue @@ -55,6 +55,9 @@ import { ArrowDownBold, ArrowUpBold } from "@element-plus/icons"; import HttpUtil from "../../utils/HttpUtil"; import FileChose from "@/components/FileChose"; import RuleBlock from "./components/RuleBlock.vue"; + +let numberSet = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]); + export default { name: "Home", components: { @@ -80,6 +83,7 @@ export default { async addData(data) { data.forEach((item) => (item.checked = false)); this.fileList.push(...data); + this.fileList = [...this.fileList.sort((a, b) => compareStr(a.name, b.name))]; this.dialogVisible = false; this.needPreview = true; await this.showResult(); @@ -158,6 +162,55 @@ export default { }, }, }; + +/** + * 数字字母混合排序 + * @param a str + * @param b str + */ +function compareStr(a, b) { + let an = a.length; + let bn = b.length; + for (let i = 0; i < an; ) { + let charA = readChar(a, i, an); + let charB = readChar(b, i, bn); + if (charB.length == 0) { + return 1; + } + if (charA !== charB) { + //读取字符串不相等说明可以得到排序结果 + //如果都为数字,按照数字的比较方法,否则按照字符串比较 + return numberSet.has(charA.charAt(0)) && numberSet.has(charB.charAt(0)) ? Number(charA) - Number(charB) : charA.localeCompare(charB); + } + i += charA.length; + } + //排到最后都没分结果说明相等 + return 0; +} + +/** + * 读取字符,如果字符为数字就读取整个数字 + * @param a a + * @param n 数字长度 + */ +function readChar(a, i, n) { + let res = ""; + for (; i < n; i++) { + let char = a.charAt(i); + if (numberSet.has(char)) { + //如果当前字符是数字,添加到结果中 + res += char; + } else { + //如果不为数字,但是为第一个字符,直接返回,否则返回res + if (res.length == 0) { + return char; + } else { + return res; + } + } + } + return res; +}