Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
fanxb 2022-07-18 10:51:14 +08:00
commit 6e983f8949
16 changed files with 220 additions and 45 deletions

View File

@ -25,7 +25,7 @@ renamer 的开源实现版本BS 应用,支持全平台部署使用
```bash ```bash
# 管理/mnt/vdisk目录中的文件通过8089端口访问服务 # 管理/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 运行: - docker-compose 运行:
@ -40,6 +40,8 @@ version: "3.6"
environment: environment:
# 指定启动端口 # 指定启动端口
- PORT=11004 - PORT=11004
# 指定认证token不设置此项无需认证
- TOKEN=123456
volumes: volumes:
# 关键把想要管理的文件夹映射到容器的data目录中即可在程序中选择data目录进行重命名操作 # 关键把想要管理的文件夹映射到容器的data目录中即可在程序中选择data目录进行重命名操作
- /mnt/vdisk:/data - /mnt/vdisk:/data

View File

@ -25,4 +25,25 @@ router["GET /file/path/exist"] = async function (ctx: Context) {
ctx.body = await FileService.checkExist(ctx.query.path as string); 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; export default router;

View File

@ -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<Array<SavePath>> {
let res = await SqliteHelper.pool.all('select id,name,content from path_save');
return res;
}
/**
*
* @param obj
* @returns
*/
static async addOne(obj: SavePath): Promise<number> {
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<void> {
let res = await SqliteHelper.pool.run('delete from path_save where id=?', id);
if (res.changes == 0) {
throw ErrorHelper.Error404("数据不存在");
}
}
}

View File

@ -0,0 +1,12 @@
export default class SavePath {
id: number;
/**
*/
name: string;
/**
json序列化后
*/
content: string;
}

View File

@ -4,6 +4,8 @@ import * as fs from 'fs-extra';
import ProcessHelper from '../util/ProcesHelper'; import ProcessHelper from '../util/ProcesHelper';
import FileObj from '../vo/FileObj'; 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"]); 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); 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 * @param a str

View File

@ -0,0 +1,7 @@
-- 路径收藏表
CREATE TABLE path_save (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
-- 路径内容
content TEXT NOT NULL DEFAULT ''
);

View File

@ -43,27 +43,29 @@ export default class InsertRule implements RuleInterface {
deal(file: FileObj): void { deal(file: FileObj): void {
let str = this.ignorePostfix ? file.realName : file.name; 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) { switch (this.type) {
case "front": case "front":
str = this.insertContent + str; str = this.insertContent + season + str;
break; break;
case "backend": case "backend":
str = str + this.insertContent; str = str + this.insertContent + season;
break; break;
case "at": case "at":
let index = this.atIsRightToleft ? str.length - this.atInput + 1 : this.atInput - 1; 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; break;
case "replace": case "replace":
str = this.insertContent; str = this.insertContent + season;
break; break;
} }
if (this.autoSeason) {
let patternRes = path.basename(file.path).replace(/[ ]+/, "").toLocaleLowerCase().match(pattern);
if (patternRes[2]) {
str += patternRes[2];
}
}
if (this.ignorePostfix) { if (this.ignorePostfix) {
file.realName = str; file.realName = str;

View File

@ -12,7 +12,7 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"dayjs": "^1.10.7", "dayjs": "^1.10.7",
"element-plus": "^1.2.0-beta.5", "element-plus": "^2.2.5",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0" "vue-router": "^4.0.0-0"
}, },

View File

@ -14,7 +14,7 @@ export default {
data() { data() {
return { return {
activeIndex: "dealCenter", activeIndex: "dealCenter",
version: "0.6", version: "0.8",
}; };
}, },
async created() { async created() {

View File

@ -11,9 +11,11 @@
<div class="fileList"> <div class="fileList">
<div> <div>
<el-input style="display: inline-block; width: 150px" type="text" size="small" placeholder="关键词过滤" v-model="filterText" clearable /> <el-input style="display: inline-block; width: 150px" type="text" size="small" placeholder="关键词过滤" v-model="filterText" clearable />
<el-button type="primary" @click="selectAll(true)" size="mini">全选</el-button> <el-button type="primary" @click="selectAll(true)" size="small">全选</el-button>
<el-button type="primary" @click="selectAll(false)" size="mini">全不选</el-button> <el-button type="primary" @click="selectAll(false)" size="small">全不选</el-button>
<el-button type="primary" @click="refresh" size="mini">刷新</el-button> <el-button type="primary" @click="refresh" size="small">刷新</el-button>
<el-button v-if="curSavePathId" type="warning" @click="cancelSavePath" size="small">取消收藏</el-button>
<el-button v-else type="primary" @click="showSave = true" size="small">收藏路径</el-button>
</div> </div>
<div v-for="(item, index) in filterFileList" :key="index"> <div v-for="(item, index) in filterFileList" :key="index">
<span class="folder" v-if="item.isFolder" @click="fileClick(item)">{{ item.name }}</span> <span class="folder" v-if="item.isFolder" @click="fileClick(item)">{{ item.name }}</span>
@ -24,6 +26,11 @@
<div> <div>
<el-button type="primary" @click="submit">确定</el-button> <el-button type="primary" @click="submit">确定</el-button>
</div> </div>
<el-dialog title="保存路径" v-model="showSave" width="40em">
<el-input type="text" v-model="saveName" placeholder="输入名称" />
<el-button type="primary" @click="savePath" style="padding-top: 1em">提交</el-button>
</el-dialog>
</div> </div>
</template> </template>
@ -38,6 +45,9 @@ export default {
pathList: [], // pathList: [], //
loading: false, // loading: false, //
filterText: "", // filterText: "", //
showSave: false, //
saveName: "",
savePathList: [], //
}; };
}, },
computed: { computed: {
@ -45,16 +55,25 @@ export default {
let text = this.filterText.trim(); let text = this.filterText.trim();
return text === "" ? this.fileList : this.fileList.filter((item) => item.name.indexOf(text) > -1); 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"); async created() {
await this.breadcrumbClick(-1); await this.breadcrumbClick(this.pathList.length - 1);
await this.refreshSavePathList();
}, },
methods: { methods: {
async refresh() { async refresh() {
await this.breadcrumbClick(this.pathList.length - 1); await this.breadcrumbClick(this.pathList.length - 1);
}, },
//
async refreshSavePathList() {
this.savePathList = await HttpUtil.get("/file/path");
},
// //
async breadcrumbClick(index) { async breadcrumbClick(index) {
this.loading = true; this.loading = true;
@ -84,15 +103,17 @@ export default {
}, },
//index //index
createPath(index) { createPath(index) {
console.log("当前路径为:", this.pathList);
let path; let path;
if (index == -1) { if (index == -1) {
path = ""; path = "";
this.pathList = []; this.pathList = [];
} else { } else {
this.pathList = this.pathList.slice(0, index + 1); this.pathList = this.pathList.slice(0, index + 1);
let str = this.pathList.join(this.isWindows ? "\\" : "/") + (this.isWindows ? "\\" : "/"); let str = this.pathList.join(window.isWindows ? "\\" : "/") + (window.isWindows ? "\\" : "/");
path = this.isWindows ? str : "/" + str; path = window.isWindows ? str : "/" + str;
} }
console.log("构建出的路径为:", path);
return path; return path;
}, },
// //
@ -102,11 +123,30 @@ export default {
this.$message({ message: "未选择文件", type: "warning" }); this.$message({ message: "未选择文件", type: "warning" });
return; return;
} }
this.$emit("addData", chosedFiles); this.$emit("addData", JSON.parse(JSON.stringify(chosedFiles)));
this.fileList.forEach((item) => (item.checked = false)); this.fileList.forEach((item) => (item.checked = false));
this.fileList = [...this.fileList]; this.fileList = [...this.fileList];
this.filterText = ""; 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);
},
}, },
}; };
</script> </script>

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="main"> <div class="main">
<el-menu style="width: 8em" mode="vertical" :default-active="currentIndex" @select="menuChange"> <el-menu style="width: 8em" mode="vertical" :default-active="currentIndex" @select="menuChange">
<el-menu-item :disabled="editRule" index="insert">插入</el-menu-item> <el-menu-item :disabled="editRule != null" index="insert">插入</el-menu-item>
<el-menu-item :disabled="editRule" index="delete">删除</el-menu-item> <el-menu-item :disabled="editRule != null" index="delete">删除</el-menu-item>
<!-- <el-menu-item index="replace">替换</el-menu-item> --> <!-- <el-menu-item index="replace">替换</el-menu-item> -->
<el-menu-item :disabled="editRule" index="serialization">序列化</el-menu-item> <el-menu-item :disabled="editRule != null" index="serialization">序列化</el-menu-item>
</el-menu> </el-menu>
<div class="rule"> <div class="rule">
<insert-rule ref="rule" :editRule="editRule" v-if="currentIndex == 'insert'" /> <insert-rule ref="rule" :editRule="editRule" v-if="currentIndex == 'insert'" />

View File

@ -9,7 +9,7 @@
<el-radio style="margin-top: 1em" v-model="ruleObj.data.type" label="front">前缀</el-radio> <el-radio style="margin-top: 1em" v-model="ruleObj.data.type" label="front">前缀</el-radio>
<el-radio style="margin-top: 1em" v-model="ruleObj.data.type" label="backend">后缀</el-radio> <el-radio style="margin-top: 1em" v-model="ruleObj.data.type" label="backend">后缀</el-radio>
<el-radio style="margin-top: 1em" v-model="ruleObj.data.type" label="at" <el-radio style="margin-top: 1em" v-model="ruleObj.data.type" label="at"
>位置:<el-input-number size="mini" v-model="ruleObj.data.atInput" /> >位置:<el-input-number size="small" v-model="ruleObj.data.atInput" />
&nbsp;&nbsp; &nbsp;&nbsp;
<el-switch v-model="ruleObj.data.atIsRightToleft" :min="1" active-text="从右到左" inactive-text="从左到右" /> <el-switch v-model="ruleObj.data.atIsRightToleft" :min="1" active-text="从右到左" inactive-text="从左到右" />
</el-radio> </el-radio>

View File

@ -24,7 +24,7 @@
<el-radio style="margin-top: 1em" v-model="ruleObj.data.insertType" label="front">前缀</el-radio> <el-radio style="margin-top: 1em" v-model="ruleObj.data.insertType" label="front">前缀</el-radio>
<el-radio style="margin-top: 1em" v-model="ruleObj.data.insertType" label="backend">后缀</el-radio> <el-radio style="margin-top: 1em" v-model="ruleObj.data.insertType" label="backend">后缀</el-radio>
<el-radio style="margin-top: 1em" v-model="ruleObj.data.insertType" label="at" <el-radio style="margin-top: 1em" v-model="ruleObj.data.insertType" label="at"
>位置:<el-input-number size="mini" :min="1" :disabled="ruleObj.data.insertType !== 'at'" v-model="ruleObj.data.insertValue" /> >位置:<el-input-number size="small" :min="1" :disabled="ruleObj.data.insertType !== 'at'" v-model="ruleObj.data.insertValue" />
</el-radio> </el-radio>
</div> </div>
</div> </div>

View File

@ -9,9 +9,10 @@
<div class="fileList"> <div class="fileList">
<div> <div>
文件列表 文件列表
<el-button type="primary" @click="dialogVisible = true" size="small">新增</el-button> <el-button type="primary" @click="showFileAdd" size="small">新增</el-button>
<el-button type="primary" size="mini" @click="selectAllFiles">反选</el-button> <el-button type="primary" size="small" @click="selectAllFiles">反选</el-button>
<el-button type="danger" size="mini" @click="deleteCheckedFiles">删除</el-button> <el-button type="danger" size="small" @click="deleteCheckedFiles">删除</el-button>
收藏路径:<el-button v-for="item in savePathList" :key="item.id" @click="clickSavePath(item)" type="primary" text>{{ item.name }}</el-button>
</div> </div>
<div class="fileBlock"> <div class="fileBlock">
<!-- 左侧原始文件名 --> <!-- 左侧原始文件名 -->
@ -44,7 +45,7 @@
<!-- 新增文件弹窗 --> <!-- 新增文件弹窗 -->
<el-dialog title="新增文件" v-model="dialogVisible" width="70%"> <el-dialog title="新增文件" v-model="dialogVisible" width="70%">
<file-chose @addData="addData" /> <file-chose ref="fileChose" :curSavePath="curSavePath" @addData="addData" @refreshSavePathList="refreshSavePathList" />
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@ -75,9 +76,14 @@ export default {
changedFileList: [], // changedFileList: [], //
needPreview: false, // needPreview: false, //
applicationRule: null, // applicationRule: null, //
savePathList: [], //
curSavePath: null, //
}; };
}, },
async created() {
this.savePathList = await HttpUtil.get("/file/path");
window.isWindows = await HttpUtil.get("/file/isWindows");
},
methods: { methods: {
// //
async addData(data) { async addData(data) {
@ -160,6 +166,20 @@ export default {
this.needPreview = true; this.needPreview = true;
await this.showResult(); 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");
},
}, },
}; };

View File

@ -4,10 +4,10 @@
<el-table-column prop="createdDate" label="创建时间" width="180" /> <el-table-column prop="createdDate" label="创建时间" width="180" />
<el-table-column prop="name" label="名称" width="180" /> <el-table-column prop="name" label="名称" width="180" />
<el-table-column prop="comment" label="备注" /> <el-table-column prop="comment" label="备注" />
<el-table-column label="操作" width="120"> <el-table-column label="操作" width="150">
<template #default="scope"> <template #default="scope">
<el-button type="text" size="small" @click="ruleTemplateAction('chose', scope.row)">选择</el-button> <el-button text type="primary" size="small" @click="ruleTemplateAction('chose', scope.row)">选择</el-button>
<el-button type="text" size="small" @click="ruleTemplateAction('delete', scope.row)">删除</el-button> <el-button text type="warning" size="small" @click="ruleTemplateAction('delete', scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -2,12 +2,12 @@
<div class="main"> <div class="main">
<div class="menu"> <div class="menu">
<span>应用规则</span> <span>应用规则</span>
<el-button type="primary" size="mini" @click="addRuleDialogShow = true">新增</el-button> <el-button type="primary" size="small" @click="addRuleDialogShow = true">新增</el-button>
<el-button type="primary" size="mini" v-if="checkedRules.length == 1" @click="editClick">编辑</el-button> <el-button type="primary" size="small" v-if="checkedRules.length == 1" @click="editClick">编辑</el-button>
<el-button type="warning" size="mini" @click="block">禁用/启用</el-button> <el-button type="warning" size="small" @click="block">禁用/启用</el-button>
<el-button type="danger" size="mini" @click="deleteRule">删除</el-button> <el-button type="danger" size="small" @click="deleteRule">删除</el-button>
<el-button type="primary" size="mini" v-if="chosedTemplate" @click="templateSubmit">保存规则</el-button> <el-button type="primary" size="small" v-if="chosedTemplate" @click="templateSubmit">保存规则</el-button>
<el-button type="primary" size="mini" v-if="chosedTemplate == null && ruleList.length > 0" @click="saveTemplateDilalogShow = true" <el-button type="primary" size="small" v-if="chosedTemplate == null && ruleList.length > 0" @click="saveTemplateDilalogShow = true"
>存为模板</el-button >存为模板</el-button
> >
</div> </div>
@ -17,7 +17,7 @@
<span v-else>{{ item.message }}</span> <span v-else>{{ item.message }}</span>
</el-checkbox> </el-checkbox>
<div v-if="ruleList.length == 0 && chosedTemplate == null" class="choseTemplate"> <div v-if="ruleList.length == 0 && chosedTemplate == null" class="choseTemplate">
<el-button type="primary" size="mini" @click="ruleTemplateShow = true">选择模板</el-button> <el-button type="primary" size="small" @click="ruleTemplateShow = true">选择模板</el-button>
</div> </div>
</div> </div>
<!-- 弹窗 --> <!-- 弹窗 -->