diff --git a/README.md b/README.md index 55bbcc2..1dbd696 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ renamer 的开源实现版本,BS 应用,支持全平台部署使用 ```bash # 管理/mnt/vdisk目录中的文件,通过8089端口访问服务 -docker run -itd --name openRenamer -v /mnt/vdisk:/data -p 8089:8089 fleyx/open-renamer +docker run -itd --name openRenamer -v /mnt/vdisk:/data -p 8089:8089 -e PORT="8089" -e TOKEN="123456" fleyx/open-renamer ``` - docker-compose 运行: @@ -38,8 +38,10 @@ version: "3.6" # 当前用户的uid,gid,使用root可不配置此项 user: "${1000}:${1000}" environment: - # 指定启动端口 + # 指定启动端口 - PORT=11004 + # 指定认证token,不设置此项无需认证 + - TOKEN=123456 volumes: # 关键,把想要管理的文件夹映射到容器的data目录中,即可在程序中选择data目录进行重命名操作 - /mnt/vdisk:/data diff --git a/openRenamerBackend/api/FileApi.ts b/openRenamerBackend/api/FileApi.ts index 00ae486..7c85bca 100644 --- a/openRenamerBackend/api/FileApi.ts +++ b/openRenamerBackend/api/FileApi.ts @@ -14,8 +14,8 @@ router["GET /file/query"] = async function (ctx: Context) { /** *是否windows */ -router['GET /file/isWindows'] = async function (ctx:Context) { - ctx.body=config.isWindows; +router['GET /file/isWindows'] = async function (ctx: Context) { + ctx.body = config.isWindows; } /** @@ -25,4 +25,25 @@ router["GET /file/path/exist"] = async function (ctx: Context) { ctx.body = await FileService.checkExist(ctx.query.path as string); }; +/** + * 收藏路径 + */ +router["POST /file/path/save"] = async function (ctx: Context) { + ctx.body = await FileService.savePath(ctx.request.body); +}; + +/** + * 获取收藏路径 + */ +router["GET /file/path"] = async function (ctx: Context) { + ctx.body = await FileService.getSaveList(); +}; + +/** + * 获取收藏路径 + */ +router["DELETE /file/path/delete"] = async function (ctx: Context) { + ctx.body = await FileService.deleteOne(ctx.query.id); +}; + export default router; diff --git a/openRenamerBackend/dao/SavePathDao.ts b/openRenamerBackend/dao/SavePathDao.ts new file mode 100644 index 0000000..b4de79a --- /dev/null +++ b/openRenamerBackend/dao/SavePathDao.ts @@ -0,0 +1,42 @@ +import ErrorHelper from "../util/ErrorHelper"; +import SavePath from "../entity/dto/SavePath"; +import SqliteHelper from "../util/SqliteHelper"; + +export default class SavePathDao { + /** + * 查询所有 + * @param obj + * @returns + */ + static async getAll(): Promise> { + let res = await SqliteHelper.pool.all('select id,name,content from path_save'); + return res; + } + + + /** + * 新增 + * @param obj + * @returns + */ + static async addOne(obj: SavePath): Promise { + let res = await SqliteHelper.pool.run('insert into path_save(name,content) values(?,?)' + , obj.name, obj.content); + obj.id = res.lastID; + return res.lastID; + } + + + /** + * 删除 + * @param id + */ + static async delete(id: number): Promise { + let res = await SqliteHelper.pool.run('delete from path_save where id=?', id); + if (res.changes == 0) { + throw ErrorHelper.Error404("数据不存在"); + } + } + + +} \ No newline at end of file diff --git a/openRenamerBackend/entity/dto/SavePath.ts b/openRenamerBackend/entity/dto/SavePath.ts new file mode 100644 index 0000000..9c68168 --- /dev/null +++ b/openRenamerBackend/entity/dto/SavePath.ts @@ -0,0 +1,12 @@ +export default class SavePath { + id: number; + /** + 名称 + */ + name: string; + + /** + 规则内容,json序列化后 + */ + content: string; +} \ No newline at end of file diff --git a/openRenamerBackend/service/FileService.ts b/openRenamerBackend/service/FileService.ts index b7e0b16..4d4b8cf 100644 --- a/openRenamerBackend/service/FileService.ts +++ b/openRenamerBackend/service/FileService.ts @@ -4,6 +4,8 @@ import * as fs from 'fs-extra'; import ProcessHelper from '../util/ProcesHelper'; import FileObj from '../vo/FileObj'; +import SavePathDao from '../dao/SavePathDao'; +import SavePath from '../entity/dto/SavePath'; let numberSet = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]); @@ -56,6 +58,33 @@ class FileService { return await fs.pathExists(pathStr); } + /** + * 收藏路径 + * @param saveObj + * @returns + */ + static async savePath(saveObj: SavePath) { + await SavePathDao.addOne(saveObj); + return saveObj; + } + + /** + * 获取保存列表 + * @returns + */ + static async getSaveList() { + return await SavePathDao.getAll(); + } + + /** + * 删除 + * @param id + * @returns + */ + static async deleteOne(id) { + return await SavePathDao.delete(id); + } + /** * 数字字母混合排序 * @param a str diff --git a/openRenamerBackend/sqls/v002__init.sql b/openRenamerBackend/sqls/v002__init.sql new file mode 100644 index 0000000..2fe3f0d --- /dev/null +++ b/openRenamerBackend/sqls/v002__init.sql @@ -0,0 +1,7 @@ +-- 路径收藏表 +CREATE TABLE path_save ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + -- 路径内容 + content TEXT NOT NULL DEFAULT '' +); \ No newline at end of file diff --git a/openRenamerBackend/vo/rules/InsertRule.ts b/openRenamerBackend/vo/rules/InsertRule.ts index 16ac837..df7ae7c 100644 --- a/openRenamerBackend/vo/rules/InsertRule.ts +++ b/openRenamerBackend/vo/rules/InsertRule.ts @@ -43,27 +43,29 @@ export default class InsertRule implements RuleInterface { deal(file: FileObj): void { let str = this.ignorePostfix ? file.realName : file.name; + let season = ''; + if (this.autoSeason) { + let patternRes = path.basename(file.path).replace(/[ ]+/, "").toLocaleLowerCase().match(pattern); + if (patternRes && patternRes[2]) { + season = patternRes[2]; + } + } switch (this.type) { case "front": - str = this.insertContent + str; + str = this.insertContent + season + str; break; case "backend": - str = str + this.insertContent; + str = str + this.insertContent + season; 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); + str = str.substring(0, index) + this.insertContent + season + str.substring(index); break; case "replace": - str = this.insertContent; + str = this.insertContent + season; break; } - if (this.autoSeason) { - let patternRes = path.basename(file.path).replace(/[ ]+/, "").toLocaleLowerCase().match(pattern); - if (patternRes[2]) { - str += patternRes[2]; - } - } + if (this.ignorePostfix) { file.realName = str; diff --git a/openRenamerFront/package.json b/openRenamerFront/package.json index 63f91e8..a26eb13 100644 --- a/openRenamerFront/package.json +++ b/openRenamerFront/package.json @@ -12,7 +12,7 @@ "axios": "^0.21.1", "core-js": "^3.6.5", "dayjs": "^1.10.7", - "element-plus": "^1.2.0-beta.5", + "element-plus": "^2.2.5", "vue": "^3.0.0", "vue-router": "^4.0.0-0" }, diff --git a/openRenamerFront/src/App.vue b/openRenamerFront/src/App.vue index 550b967..9f4751b 100644 --- a/openRenamerFront/src/App.vue +++ b/openRenamerFront/src/App.vue @@ -14,7 +14,7 @@ export default { data() { return { activeIndex: "dealCenter", - version: "0.6", + version: "0.8", }; }, async created() { diff --git a/openRenamerFront/src/components/FileChose.vue b/openRenamerFront/src/components/FileChose.vue index f6ee071..8d7190b 100644 --- a/openRenamerFront/src/components/FileChose.vue +++ b/openRenamerFront/src/components/FileChose.vue @@ -11,9 +11,11 @@
- 全选 - 全不选 - 刷新 + 全选 + 全不选 + 刷新 + 取消收藏 + 收藏路径
{{ item.name }} @@ -24,6 +26,11 @@
确定
+ + + + 提交 +
@@ -38,6 +45,9 @@ export default { pathList: [], //选择的路径 loading: false, //加载 filterText: "", //关键字过滤 + showSave: false, //保存路径 + saveName: "", + savePathList: [], //保存的路径 }; }, computed: { @@ -45,16 +55,25 @@ export default { let text = this.filterText.trim(); return text === "" ? this.fileList : this.fileList.filter((item) => item.name.indexOf(text) > -1); }, + curSavePathId() { + let curPath = JSON.stringify(this.pathList); + let targetList = this.savePathList.filter((item) => item.content == curPath); + return targetList.length > 0 ? targetList[0].id : null; + }, }, - async mounted() { - this.isWindows = await HttpUtil.get("/file/isWindows"); - await this.breadcrumbClick(-1); + async created() { + await this.breadcrumbClick(this.pathList.length - 1); + await this.refreshSavePathList(); }, methods: { async refresh() { await this.breadcrumbClick(this.pathList.length - 1); }, + //刷新保存的路径 + async refreshSavePathList() { + this.savePathList = await HttpUtil.get("/file/path"); + }, //点击面包蟹 async breadcrumbClick(index) { this.loading = true; @@ -84,15 +103,17 @@ export default { }, //根据index构建路径 createPath(index) { + console.log("当前路径为:", this.pathList); let path; if (index == -1) { path = ""; this.pathList = []; } else { this.pathList = this.pathList.slice(0, index + 1); - let str = this.pathList.join(this.isWindows ? "\\" : "/") + (this.isWindows ? "\\" : "/"); - path = this.isWindows ? str : "/" + str; + let str = this.pathList.join(window.isWindows ? "\\" : "/") + (window.isWindows ? "\\" : "/"); + path = window.isWindows ? str : "/" + str; } + console.log("构建出的路径为:", path); return path; }, //点击确定 @@ -102,11 +123,30 @@ export default { this.$message({ message: "未选择文件", type: "warning" }); return; } - this.$emit("addData", chosedFiles); + this.$emit("addData", JSON.parse(JSON.stringify(chosedFiles))); this.fileList.forEach((item) => (item.checked = false)); this.fileList = [...this.fileList]; this.filterText = ""; }, + //收藏路径 + async savePath() { + let res = await HttpUtil.post("/file/path/save", null, { name: this.saveName, content: JSON.stringify(this.pathList) }); + this.$emit("refreshSavePathList"); + this.refreshSavePathList(); + this.saveName = ""; + this.showSave = false; + this.$message.success("操作成功"); + }, + async cancelSavePath() { + await HttpUtil.delete("/file/path/delete", { id: this.curSavePathId }); + this.refreshSavePathList(); + this.$emit("refreshSavePathList"); + this.$message.success("操作成功"); + }, + changePath(item) { + this.pathList = JSON.parse(item.content); + this.breadcrumbClick(this.pathList.length - 1); + }, }, }; diff --git a/openRenamerFront/src/components/Rule.vue b/openRenamerFront/src/components/Rule.vue index e7e7b29..83c091e 100644 --- a/openRenamerFront/src/components/Rule.vue +++ b/openRenamerFront/src/components/Rule.vue @@ -1,10 +1,10 @@ @@ -75,9 +76,14 @@ export default { changedFileList: [], //执行修改后的文件 needPreview: false, //需要点击预览 applicationRule: null, //当前应用的应用规则模板 + savePathList: [], //收藏的路径列表 + curSavePath: null, //当前选择的收藏路径 }; }, - + async created() { + this.savePathList = await HttpUtil.get("/file/path"); + window.isWindows = await HttpUtil.get("/file/isWindows"); + }, methods: { //新增文件 async addData(data) { @@ -160,6 +166,20 @@ export default { this.needPreview = true; await this.showResult(); }, + showFileAdd() { + this.dialogVisible = true; + }, + //点击收藏路径 + clickSavePath(item) { + this.dialogVisible = true; + console.log(item); + this.$nextTick(() => { + this.$refs["fileChose"].changePath(item); + }); + }, + async refreshSavePathList() { + this.savePathList = await HttpUtil.get("/file/path"); + }, }, }; diff --git a/openRenamerFront/src/views/home/components/ApplicationRuleList.vue b/openRenamerFront/src/views/home/components/ApplicationRuleList.vue index ce531c8..a45db66 100644 --- a/openRenamerFront/src/views/home/components/ApplicationRuleList.vue +++ b/openRenamerFront/src/views/home/components/ApplicationRuleList.vue @@ -4,10 +4,10 @@ - + diff --git a/openRenamerFront/src/views/home/components/RuleBlock.vue b/openRenamerFront/src/views/home/components/RuleBlock.vue index 3e5c134..892aca6 100644 --- a/openRenamerFront/src/views/home/components/RuleBlock.vue +++ b/openRenamerFront/src/views/home/components/RuleBlock.vue @@ -2,12 +2,12 @@
@@ -17,7 +17,7 @@ {{ item.message }}
- 选择模板 + 选择模板