feat:自动化配置完成

This commit is contained in:
fanxb 2023-01-10 23:15:39 +08:00
parent 977da05608
commit f9a546cb97
9 changed files with 575 additions and 372 deletions

View File

@ -24,6 +24,13 @@ router["POST /config/update"] = async function (ctx: Context) {
ctx.body = await service.updateVal(ctx.request.body.code, ctx.request.body.val); ctx.body = await service.updateVal(ctx.request.body.code, ctx.request.body.val);
}; };
/**
*
*/
router["POST /config/insertOrUpdate"] = async function (ctx: Context) {
ctx.body = await service.insertOrReplace(ctx.request.body);
};
export default router; export default router;

View File

@ -1,9 +1,10 @@
<template> <template>
<div class="app"> <div class="app">
<el-menu :default-active="activeIndex" mode="horizontal" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" router> <el-menu :default-active="activeIndex" mode="horizontal" background-color="#545c64" text-color="#fff"
active-text-color="#ffd04b" router>
<el-menu-item index="/">重命名</el-menu-item> <el-menu-item index="/">重命名</el-menu-item>
<!-- <el-menu-item index="/auto">自动化</el-menu-item> <el-menu-item index="/auto">自动化</el-menu-item>
<el-sub-menu index="/download"> <!-- <el-sub-menu index="/download">
<template #title>bt下载</template> <template #title>bt下载</template>
<el-menu-item index="/download/center">下载中心</el-menu-item> <el-menu-item index="/download/center">下载中心</el-menu-item>
<el-menu-item index="/download/config">配置</el-menu-item> <el-menu-item index="/download/config">配置</el-menu-item>
@ -12,7 +13,8 @@
<div class="content"> <div class="content">
<router-view /> <router-view />
</div> </div>
<div class="footer">版本{{ version }}&nbsp;&nbsp;开源地址:<a href="https://github.com/FleyX/open-renamer">open-renamer</a></div> <div class="footer">版本{{ version }}&nbsp;&nbsp;开源地址:<a
href="https://github.com/FleyX/open-renamer">open-renamer</a></div>
</div> </div>
</template> </template>
@ -20,20 +22,20 @@
import httpUtil from "./utils/HttpUtil"; import httpUtil from "./utils/HttpUtil";
export default { export default {
name: "Home", name: "Home",
data() { data () {
return { return {
version: "1.2", version: "1.2",
activeIndex: location.pathname, activeIndex: location.pathname,
}; };
}, },
async created() { async created () {
let token = localStorage.getItem("token"); let token = localStorage.getItem("token");
window.token = token; window.token = token;
await httpUtil.get("/file/isWindows"); window.isWindows = await httpUtil.get("/file/isWindows");
console.log(this.$route); console.log(this.$route);
console.log(this.activeIndex); console.log(this.activeIndex);
}, },
async mounted() { async mounted () {
console.log(this.$route); console.log(this.$route);
console.log(location); console.log(location);
}, },
@ -48,6 +50,7 @@ body {
margin: 0; margin: 0;
background-color: #e8e8e5; background-color: #e8e8e5;
} }
#app { #app {
font-family: Avenir, Helvetica, Arial, sans-serif; font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;

View File

@ -10,16 +10,20 @@
<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="关键词过滤"
<el-button type="primary" @click="selectAll(true)" size="small">全选</el-button> v-model="filterText" clearable />
<el-button type="primary" @click="selectAll(false)" size="small">全不选</el-button> <template v-if="type == 'file'">
<el-button type="primary" @click="refresh" size="small">刷新</el-button> <el-button type="primary" @click="selectAll(true)" size="small">全选</el-button>
<el-button v-if="curSavePathId" type="warning" @click="cancelSavePath" size="small">取消收藏</el-button> <el-button type="primary" @click="selectAll(false)" size="small">全不选</el-button>
<el-button v-else type="primary" @click="showSave = true" size="small">收藏路径</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>
</template>
</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>
<el-checkbox style="height: 1.4em" v-model="item.checked" v-else>{{ item.name }}</el-checkbox> <el-checkbox style="height: 1.4em" v-model="item.checked" v-else-if="type == 'file'">{{ item.name
}}</el-checkbox>
</div> </div>
</div> </div>
@ -39,8 +43,8 @@ import HttpUtil from "../utils/HttpUtil";
import Bus from "../utils/Bus"; import Bus from "../utils/Bus";
export default { export default {
name: "FileChose", name: "FileChose",
props: ["curChoosePath"], props: ["curChoosePath", "type"],
data() { data () {
return { return {
isWindows: false, isWindows: false,
fileList: [], // fileList: [], //
@ -53,24 +57,24 @@ export default {
}; };
}, },
computed: { computed: {
filterFileList() { filterFileList () {
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() { curSavePathId () {
let curPath = JSON.stringify(this.pathList); let curPath = JSON.stringify(this.pathList);
let targetList = this.savePathList.filter((item) => item.content == curPath); let targetList = this.savePathList.filter((item) => item.content == curPath);
return targetList.length > 0 ? targetList[0].id : null; return targetList.length > 0 ? targetList[0].id : null;
}, },
}, },
watch: { watch: {
async curChoosePath(newVal) { async curChoosePath (newVal) {
console.log("变更路径:", newVal); console.log("变更路径:", newVal);
this.pathList = newVal; this.pathList = newVal;
await this.breadcrumbClick(this.pathList.length - 1); await this.breadcrumbClick(this.pathList.length - 1);
}, },
}, },
async created() { async created () {
if (this.curChoosePath && this.curChoosePath.length > 0) { if (this.curChoosePath && this.curChoosePath.length > 0) {
this.pathList = this.curChoosePath; this.pathList = this.curChoosePath;
} }
@ -80,15 +84,15 @@ export default {
}, },
methods: { methods: {
async refresh() { async refresh () {
await this.breadcrumbClick(this.pathList.length - 1); await this.breadcrumbClick(this.pathList.length - 1);
}, },
// //
async refreshSavePathList() { async refreshSavePathList () {
this.savePathList = await HttpUtil.get("/file/path"); this.savePathList = await HttpUtil.get("/file/path");
}, },
// //
async breadcrumbClick(index) { async breadcrumbClick (index) {
this.loading = true; this.loading = true;
try { try {
let path = this.createPath(index); let path = this.createPath(index);
@ -105,7 +109,7 @@ export default {
return false; return false;
}, },
// //
fileClick(item) { fileClick (item) {
if (item.isFolder) { if (item.isFolder) {
this.pathList.push(item.name); this.pathList.push(item.name);
this.breadcrumbClick(this.pathList.length); this.breadcrumbClick(this.pathList.length);
@ -114,11 +118,11 @@ export default {
} }
}, },
// //
selectAll(status) { selectAll (status) {
this.filterFileList.filter((item) => !item.isFolder).forEach((item) => (item.checked = status)); this.filterFileList.filter((item) => !item.isFolder).forEach((item) => (item.checked = status));
}, },
//index //index
createPath(index) { createPath (index) {
console.log("当前路径为:", this.pathList); console.log("当前路径为:", this.pathList);
let path; let path;
if (index == -1) { if (index == -1) {
@ -133,19 +137,25 @@ export default {
return path; return path;
}, },
// //
submit() { submit () {
let chosedFiles = this.fileList.filter((item) => item.checked); if (this.type === 'file') {
if (chosedFiles.length == 0) { let chosedFiles = this.fileList.filter((item) => item.checked);
this.$message({ message: "未选择文件", type: "warning" }); if (chosedFiles.length == 0) {
return; this.$message({ message: "未选择文件", type: "warning" });
return;
}
this.$emit("addData", JSON.parse(JSON.stringify(chosedFiles)));
this.fileList.forEach((item) => (item.checked = false));
this.fileList = [...this.fileList];
} else if (this.type === 'folder') {
//
this.$emit("folderChose", this.createPath(this.pathList.length - 1));
} }
this.$emit("addData", JSON.parse(JSON.stringify(chosedFiles)));
this.fileList.forEach((item) => (item.checked = false));
this.fileList = [...this.fileList];
this.filterText = ""; this.filterText = "";
}, },
// //
async savePath() { async savePath () {
await HttpUtil.post("/file/path/save", null, { name: this.saveName, content: JSON.stringify(this.pathList) }); await HttpUtil.post("/file/path/save", null, { name: this.saveName, content: JSON.stringify(this.pathList) });
Bus.$emit("refreshSavePathList"); Bus.$emit("refreshSavePathList");
this.saveName = ""; this.saveName = "";
@ -153,7 +163,7 @@ export default {
this.$message.success("操作成功"); this.$message.success("操作成功");
}, },
// //
async cancelSavePath() { async cancelSavePath () {
await HttpUtil.delete("/file/path/delete", { id: this.curSavePathId }); await HttpUtil.delete("/file/path/delete", { id: this.curSavePathId });
Bus.$emit("refreshSavePathList"); Bus.$emit("refreshSavePathList");
this.$message.success("操作成功"); this.$message.success("操作成功");
@ -166,6 +176,7 @@ export default {
.main { .main {
height: 65vh; height: 65vh;
} }
.fileList { .fileList {
padding: 1em; padding: 1em;
text-align: left; text-align: left;

View File

@ -0,0 +1,22 @@
<template>
<el-tooltip effect="dark" :content="message" :placement="placement ? placement : 'top'">
<el-icon>
<InfoFilled />
</el-icon>
</el-tooltip>
</template>
<script setup>
import { InfoFilled } from "@element-plus/icons-vue";
import { ref, reactive, onMounted, computed, defineProps } from "vue";
defineProps({
message: String,
placement: String
})
</script>
<style lang="less" scoped>
</style>

View File

@ -1,116 +1,121 @@
<template> <template>
<div> <div>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="primary" @click="showEditAddModal = true">新增模板</el-button> <el-button type="primary" @click="showEditAddModal = true">新增模板</el-button>
</div> </div>
<el-table :data="applicationRuleList" style="width: 100%"> <el-table :data="applicationRuleList" style="width: 100%">
<el-table-column prop="createdDate" label="创建时间" width="130" :formatter="formatDateTime" /> <el-table-column prop="createdDate" label="创建时间" width="130" :formatter="formatDateTime" />
<el-table-column prop="updatedDate" label="更新时间" width="130" :formatter="formatDateTime" /> <el-table-column prop="updatedDate" label="更新时间" width="130" :formatter="formatDateTime" />
<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="250"> <el-table-column label="操作" width="250">
<template #default="scope"> <template #default="scope">
<el-button text type="primary" style="margin-left: 0" size="small" @click="ruleTemplateAction('chose', scope.row)">选择</el-button> <el-button text type="primary" style="margin-left: 0" size="small"
<el-button text type="primary" style="margin-left: 0" size="small" @click="ruleTemplateAction('edit', scope.row)">编辑</el-button> @click="ruleTemplateAction('chose', scope.row)">选择</el-button>
<el-button text type="warning" style="margin-left: 0" size="small" @click="ruleTemplateAction('delete', scope.row)">删除</el-button> <el-button text type="primary" style="margin-left: 0" size="small"
<el-button v-if="defaultTemplateId != scope.row.id" text type="primary" size="small" @click="ruleTemplateAction('default', scope.row)" @click="ruleTemplateAction('edit', scope.row)">编辑</el-button>
>设为默认</el-button <el-button text type="warning" style="margin-left: 0" size="small"
> @click="ruleTemplateAction('delete', scope.row)">删除</el-button>
</template> <el-button v-if="defaultTemplateId != scope.row.id" text type="primary" size="small"
</el-table-column> @click="ruleTemplateAction('default', scope.row)">设为默认</el-button>
</el-table> </template>
</div> </el-table-column>
<el-dialog :title="curEdit != null ? '修改' : '新增模板'" v-model="showEditAddModal" width="40em" @close="closeAddEdit" append-to-body> </el-table>
<el-form-item label="名称"> </div>
<el-input v-model="templateForm.name"></el-input> <el-dialog :title="curEdit != null ? '修改' : '新增模板'" v-model="showEditAddModal" width="40em" @close="closeAddEdit"
</el-form-item> append-to-body>
<el-form-item label="描述"> <el-form-item label="名称">
<el-input v-model="templateForm.comment"></el-input> <el-input v-model="templateForm.name"></el-input>
</el-form-item> </el-form-item>
<template #footer> <el-form-item label="描述">
<span class="dialog-footer"> <el-input v-model="templateForm.comment"></el-input>
<el-button @click="saveTemplateDilalogShow = false">取消</el-button> </el-form-item>
<el-button type="primary" @click="templateSubmit">提交</el-button> <template #footer>
</span> <span class="dialog-footer">
</template> <el-button @click="saveTemplateDilalogShow = false">取消</el-button>
</el-dialog> <el-button type="primary" @click="templateSubmit">提交</el-button>
</template> </span>
</template>
<script> </el-dialog>
import HttpUtil from "../../../utils/HttpUtil"; </template>
import dayjs from "dayjs";
export default { <script>
name: "ApplicationRuleList", import HttpUtil from "@/utils/HttpUtil";
props: ["curId"], import dayjs from "dayjs";
emits: ["templateUpdate"], export default {
data() { name: "ApplicationRuleList",
return { props: ["curId"],
applicationRuleList: [], emits: ["templateUpdate"],
curEdit: null, data () {
defaultTemplateId: null, return {
showEditAddModal: false, applicationRuleList: [],
templateForm: { curEdit: null,
name: "", defaultTemplateId: null,
comment: "", showEditAddModal: false,
}, templateForm: {
}; name: "",
}, comment: "",
async created() { },
await this.init(); };
}, },
methods: { async created () {
async init() { await this.init();
this.defaultTemplateId = parseInt(await HttpUtil.get("/config/code?code=defaultTempleteId")); },
this.applicationRuleList = await HttpUtil.get("/applicationRule"); methods: {
}, async init () {
formatDateTime(row, column, value) { this.defaultTemplateId = parseInt(await HttpUtil.get("/config/code?code=defaultTempleteId"));
return dayjs(value).format("YYYY-MM-DD"); this.applicationRuleList = await HttpUtil.get("/applicationRule");
}, },
// formatDateTime (row, column, value) {
async ruleTemplateAction(action, rowData) { return dayjs(value).format("YYYY-MM-DD");
if (action === "chose") { },
await this.$emit("templateUpdate", rowData); //
} else if (action === "default") { async ruleTemplateAction (action, rowData) {
let body = { code: "defaultTempleteId", val: rowData.id.toString() }; if (action === "chose") {
await HttpUtil.post("/config/update", null, body); await this.$emit("templateUpdate", rowData);
this.defaultTemplateId = rowData.id; } else if (action === "default") {
} else if (action === "edit") { let body = { code: "defaultTempleteId", val: rowData.id.toString() };
this.curEdit = rowData; await HttpUtil.post("/config/update", null, body);
this.templateForm.name = rowData.name; this.defaultTemplateId = rowData.id;
this.templateForm.comment = rowData.comment; } else if (action === "edit") {
this.showEditAddModal = true; this.curEdit = rowData;
} else { this.templateForm.name = rowData.name;
if (this.curId == rowData.id) { this.templateForm.comment = rowData.comment;
this.$message({ message: "当前模板使用中,无法删除", type: "warning" }); this.showEditAddModal = true;
return; } else {
} if (this.curId == rowData.id) {
await HttpUtil.delete("/applicationRule/" + rowData.id); this.$message({ message: "当前模板使用中,无法删除", type: "warning" });
await this.init(); return;
} }
}, await HttpUtil.delete("/applicationRule/" + rowData.id);
// await this.init();
async templateSubmit() { }
let body; },
if (this.curEdit) { //
body = JSON.parse(JSON.stringify(this.curEdit)); async templateSubmit () {
body.name = this.templateForm.name; let body;
body.comment = this.templateForm.comment; if (this.curEdit) {
} else { body = JSON.parse(JSON.stringify(this.curEdit));
body = this.templateForm; body.name = this.templateForm.name;
body.content = "[]"; body.comment = this.templateForm.comment;
} } else {
await HttpUtil.post("/applicationRule", null, body); body = this.templateForm;
await this.init(); body.content = "[]";
this.closeAddEdit(); }
this.$message.success("操作成功"); await HttpUtil.post("/applicationRule", null, body);
}, await this.init();
closeAddEdit() { this.closeAddEdit();
this.curEdit = null; this.$message.success("操作成功");
this.showEditAddModal = false; },
this.templateForm = { name: "", templte: "" }; closeAddEdit () {
}, this.curEdit = null;
}, this.showEditAddModal = false;
}; this.templateForm = { name: "", templte: "" };
</script> },
},
<style></style> };
</script>
<style>
</style>

View File

@ -1,180 +1,195 @@
<template> <template>
<div class="main"> <div class="main">
<div class="menu"> <div class="menu">
<el-button type="warning" size="small" @click="block">禁用/启用</el-button> <el-button v-if="rules == undefined" type="warning" size="small" @click="block">禁用/启用</el-button>
<el-button type="danger" size="small" @click="deleteRule">删除</el-button> <el-button type="danger" size="small" @click="deleteRule">删除</el-button>
<el-button type="primary" size="small" @click="templateSubmit">保存</el-button> <template v-if="rules == undefined">
<el-button type="primary" size="small" @click="ruleTemplateShow = true">选择模板</el-button> <el-button type="primary" size="small" @click="templateSubmit">保存</el-button>
<template v-if="checkedRules.length == 1"> <el-button type="primary" size="small" @click="ruleTemplateShow = true">选择模板</el-button>
<el-button type="primary" size="small" @click="editClick"> </template>
<el-tooltip effect="dark" content="编辑规则" placement="top"> <template v-if="checkedRules.length == 1">
<el-icon><edit /></el-icon> <el-button type="primary" size="small" @click="editClick">
</el-tooltip> <el-tooltip effect="dark" content="编辑规则" placement="top">
</el-button> <el-icon>
<el-button type="primary" size="small" @click="move('top')"> <edit />
<el-tooltip effect="dark" content="上移规则" placement="top"> </el-icon>
<el-icon><top /></el-icon> </el-tooltip>
</el-tooltip> </el-button>
</el-button> <el-button type="primary" size="small" @click="move('top')">
<el-button type="primary" size="small" @click="move('bottom')"> <el-tooltip effect="dark" content="上移规则" placement="top">
<el-tooltip effect="dark" content="下移规则" placement="top" <el-icon>
><el-icon><bottom /></el-icon <top />
></el-tooltip> </el-icon>
</el-button> </el-tooltip>
</template> </el-button>
</div> <el-button type="primary" size="small" @click="move('bottom')">
<div class="ruleBlock"> <el-tooltip effect="dark" content="下移规则" placement="top"><el-icon>
<el-checkbox v-model="item.checked" v-for="(item, index) in ruleList" :key="index" @dblclick="editClick(item)"> <bottom />
<s v-if="item.blocked">{{ item.message }}</s> </el-icon></el-tooltip>
<span v-else>{{ item.message }}</span> </el-button>
</el-checkbox> </template>
<div style="padding-top: 0.5em"> </div>
<el-button type="primary" size="small" text @click="addRuleDialogShow = true">+ 新增规则</el-button> <div class="ruleBlock">
</div> <el-checkbox v-model="item.checked" v-for="(item, index) in ruleList" :key="index" @dblclick="editClick(item)">
</div> <s v-if="item.blocked">{{ item.message }}</s>
<el-dialog title="新增规则" v-model="addRuleDialogShow" width="70%" @close="ruleDialogClose"> <span v-else>{{ item.message }}</span>
<rule :editRule="editRule" @ruleAdd="ruleAdd" v-if="addRuleDialogShow" /> </el-checkbox>
</el-dialog> <div style="padding-top: 0.5em">
<el-dialog title="模板管理" v-model="ruleTemplateShow" width="70%"> <el-button type="primary" size="small" text @click="addRuleDialogShow = true">+ 新增规则</el-button>
<application-rule-list v-if="ruleTemplateShow" :curId="chosedTemplate.id" @templateUpdate="templateUpdate" /> </div>
</el-dialog> </div>
</div> <el-dialog title="新增规则" v-model="addRuleDialogShow" width="70%" @close="ruleDialogClose">
</template> <rule :editRule="editRule" @ruleAdd="ruleAdd" v-if="addRuleDialogShow" />
</el-dialog>
<script> <el-dialog title="模板管理" v-model="ruleTemplateShow" width="70%">
import Rule from "../../../components/Rule"; <application-rule-list v-if="ruleTemplateShow" :curId="chosedTemplate.id" @templateUpdate="templateUpdate" />
import ApplicationRuleList from "./ApplicationRuleList"; </el-dialog>
import HttpUtil from "../../../utils/HttpUtil"; </div>
import { Top, Bottom, Edit } from "@element-plus/icons-vue"; </template>
export default {
name: "RuleBlock", <script>
components: { import Rule from "@/components/Rule";
Rule, import ApplicationRuleList from "./ApplicationRuleList";
ApplicationRuleList, import HttpUtil from "@/utils/HttpUtil";
Edit, import { Top, Bottom, Edit } from "@element-plus/icons-vue";
Top, export default {
Bottom, name: "RuleBlock",
}, props: ["rules"],
data() { components: {
return { Rule,
addRuleDialogShow: false, // ApplicationRuleList,
ruleTemplateShow: false, // Edit,
ruleList: [], Top,
editRule: null, // Bottom,
chosedTemplate: null, },
}; data () {
}, return {
computed: { addRuleDialogShow: false, //
// ruleTemplateShow: false, //
checkedRules() { ruleList: [],
return this.ruleList.filter((item) => item.checked); editRule: null, //
}, chosedTemplate: null,
}, };
async created() { },
this.chosedTemplate = await HttpUtil.get("/applicationRule/default"); computed: {
this.ruleList = JSON.parse(this.chosedTemplate.content); //
await this.ruleUpdate(); checkedRules () {
}, return this.ruleList.filter((item) => item.checked);
methods: { },
// },
ruleUpdate() { async created () {
let temp = this.ruleList.filter((item) => !item.blocked); //
this.$emit("ruleUpdate", temp); if (this.rules != undefined) {
}, this.ruleList = JSON.parse(JSON.stringify(this.rules));
// } else {
async templateSubmit() { this.chosedTemplate = await HttpUtil.get("/applicationRule/default");
this.chosedTemplate.content = JSON.stringify(this.ruleList); this.ruleList = JSON.parse(this.chosedTemplate.content);
await HttpUtil.post("/applicationRule", null, this.chosedTemplate); await this.ruleUpdate();
this.$message.success("操作成功"); }
}, },
// methods: {
async templateUpdate(newVal) { //
this.ruleList = JSON.parse(newVal.content); ruleUpdate () {
this.ruleUpdate(); let temp = this.ruleList.filter((item) => !item.blocked);
this.ruleTemplateShow = false; this.$emit("ruleUpdate", temp);
}, },
// //
async ruleAdd(data) { async templateSubmit () {
if (this.editRule != null) { this.chosedTemplate.content = JSON.stringify(this.ruleList);
let index = this.ruleList.indexOf(this.editRule); await HttpUtil.post("/applicationRule", null, this.chosedTemplate);
this.ruleList.splice(index, 1, data); this.$message.success("操作成功");
this.editRule = null; },
} else { //
this.ruleList.push(data); async templateUpdate (newVal) {
} this.ruleList = JSON.parse(newVal.content);
data.checked = false; this.ruleUpdate();
this.ruleUpdate(); this.ruleTemplateShow = false;
this.addRuleDialogShow = false; },
}, //
/// async ruleAdd (data) {
async block() { if (this.editRule != null) {
this.ruleList let index = this.ruleList.indexOf(this.editRule);
.filter((item) => item.checked) this.ruleList.splice(index, 1, data);
.forEach((item) => { this.editRule = null;
item.blocked = !item.blocked; } else {
item.checked = false; this.ruleList.push(data);
}); }
await this.ruleUpdate(); data.checked = false;
}, this.ruleUpdate();
// this.addRuleDialogShow = false;
async deleteRule() { },
this.ruleList = this.ruleList.filter((item) => !item.checked); ///
this.ruleUpdate(); async block () {
}, this.ruleList
// .filter((item) => item.checked)
editClick(rule) { .forEach((item) => {
this.editRule = rule && rule.data ? rule : this.checkedRules[0]; item.blocked = !item.blocked;
this.addRuleDialogShow = true; item.checked = false;
}, });
// await this.ruleUpdate();
async move(type) { },
let index = this.ruleList.indexOf(this.checkedRules[0]); //
let newIndex; async deleteRule () {
if (type == "top") { this.ruleList = this.ruleList.filter((item) => !item.checked);
if (index == 0) { this.ruleUpdate();
return; },
} //
newIndex = index - 1; editClick (rule) {
} else { this.editRule = rule && rule.data ? rule : this.checkedRules[0];
if (index == this.ruleList.length - 1) { this.addRuleDialogShow = true;
return; },
} //
newIndex = index + 1; async move (type) {
} let index = this.ruleList.indexOf(this.checkedRules[0]);
let temp = this.checkedRules[0]; let newIndex;
this.ruleList[index] = this.ruleList[newIndex]; if (type == "top") {
this.ruleList[newIndex] = temp; if (index == 0) {
this.ruleList = [...this.ruleList]; return;
await this.ruleUpdate(); }
}, newIndex = index - 1;
// } else {
ruleDialogClose() { if (index == this.ruleList.length - 1) {
this.editRule = null; return;
this.addRuleDialogShow = false; }
}, newIndex = index + 1;
}, }
}; let temp = this.checkedRules[0];
</script> this.ruleList[index] = this.ruleList[newIndex];
this.ruleList[newIndex] = temp;
<style lang="less" scoped> this.ruleList = [...this.ruleList];
.main { await this.ruleUpdate();
text-align: left; },
padding: 5px; //
.menu { ruleDialogClose () {
display: flex; this.editRule = null;
justify-content: left; this.addRuleDialogShow = false;
align-items: center; },
} },
.ruleBlock { };
text-align: left; </script>
display: flex;
flex-direction: column; <style lang="less" scoped>
align-items: baseline; .main {
} text-align: left;
.choseTemplate { padding: 5px;
text-align: center;
padding-top: 2em; .menu {
padding-bottom: 2em; display: flex;
} justify-content: left;
} align-items: center;
</style> }
.ruleBlock {
text-align: left;
display: flex;
flex-direction: column;
align-items: baseline;
}
.choseTemplate {
text-align: center;
padding-top: 2em;
padding-bottom: 2em;
}
}
</style>

View File

@ -0,0 +1,138 @@
<template>
<div>
<el-form label-width="100px">
<el-form-item label="剧集目录">
<div style="text-align:left">
<template v-for="(item, index) in body.paths" :key="item">
<el-tag closable @close="closePath(index, 'folder')">{{ item }}</el-tag> <br />
</template>
<div style="display:flex;align-items:center">
<el-button type="primary" link @click="showFolderDialog = true">+新增目录</el-button>
<tips message="添加剧集的上级目录,比如'/美剧'目录下就是美剧的剧集文件夹" />
</div>
</div>
</el-form-item>
<el-form-item label="忽略文件">
<div style="text-align:left;display:flex;align-items:center">
<template v-for="(item, index) in body.ignorePaths" :key="item">
<el-tag closable @close="closePath(index, 'ignore')">{{ item }}</el-tag> <br />
</template>
<el-input v-if="ignoreInputVisible" v-model="ignoreInput" class="ml-1 w-20" size="small"
@keyup.enter="addIngoreFile" @blur="addIngoreFile" />
<el-button v-else class="button-new-tag ml-1" size="small" @click="ignoreInputVisible = true">
+ 忽略
</el-button>
<tips message="名字匹配的文件/文件夹将会忽略处理" />
</div>
</el-form-item>
<el-form-item label="忽略特典">
<el-switch v-model="body.ignoreSeason0" class="ml-2"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" />
<tips message="season 0/特典通常命名不规范,建议手动处理" />
</el-form-item>
<el-form-item label="删除小文件">
<el-switch v-model="body.deleteSmallVideo" class="ml-2"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" />
<tips message="删除小于2M的视频文件此类文件通常为广告" />
</el-form-item>
<el-form-item label="规则">
<RuleBlock :rules="body.rules" @ruleUpdate="ruleUpdate" />
</el-form-item>
</el-form>
<el-button type="primary" @click="submit"> 保存自动化配置 </el-button>
<el-dialog title="选择目录" v-model="showFolderDialog" width="70%">
<file-chose ref="fileChose" type="folder" @folderChose="folderChose" />
</el-dialog>
</div>
</template>
<script setup>
import FileChose from "@/components/FileChose.vue";
import RuleBlock from "@/components/rules/RuleBlock.vue";
import Tips from '@/components/Tips.vue';
import { ElMessage, ElMessageBox } from 'element-plus'
import { ref, reactive, onMounted, computed, defineProps } from "vue";
import http from "@/utils/HttpUtil";
//
let body = reactive({
paths: [],
version: 1,
ignoreSeason0: true,
ignorePaths: [],
deleteSmallVideo: true,
rules: []
});
let showFolderDialog = ref(false);
let ignoreInputVisible = ref(false);
let ignoreInput = ref("");
onMounted(async () => {
let res = await http.post("/config/multCode", null, ['autoConfig', 'firstUse']);
if (res.autoConfig == undefined && res.firstUse == undefined) {
await http.post("/config/insertOrUpdate", null, { code: "firstUse", val: "1" });
await ElMessageBox.alert("似乎是首次使用自动化,是否需要查看使用文档?", "提示", {
confirmButtonText: "是",
cancelButtonText: "否",
showCancelButton: true
});
alert("跳转到自动化使用文档");
return;
}
if (res.autoConfig != undefined) {
body = reactive(JSON.parse(res.autoConfig));
}
});
//
async function folderChose (data) {
if (body.paths.indexOf(data) > -1) {
ElMessage({ type: 'warning', message: "路径已存在" });
return;
}
body.paths.push(data);
showFolderDialog.value = false;
}
//
async function addIngoreFile () {
if (body.ignorePaths.indexOf(ignoreInput) > -1) {
ElMessage({ type: 'warning', message: "名称已存在" });
return;
}
body.ignorePaths.push(ignoreInput.value);
ignoreInput.value = "";
ignoreInputVisible.value = false;
}
//
async function closePath (index, type) {
(type === 'folder' ? body.paths : body.ignorePaths).splice(index, 1);
}
//
function ruleUpdate (rules) {
body.rules = rules;
}
//
async function submit () {
await http.post("/config/insertOrUpdate", null, { code: "autoConfig", val: JSON.stringify(body), description: "自动化配置" });
ElMessage({ type: 'success', message: "保存成功" });
}
</script>
<style lang="less" scoped>
.item {
display: flex;
text-align: left;
padding-bottom: 0.5em;
.left {
width: 6em;
font-weight: 600;
}
.right {
flex: 1;
}
}
</style>

View File

@ -1,12 +1,12 @@
<template> <template>
<div>自动化</div>
<div> <div>
<el-button type="primary" @click="submit"> 保存自动化配置 </el-button> <edit-form />
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, reactive, onMounted, computed } from "vue"; import { ref, reactive, onMounted, computed } from "vue";
import editForm from "./components/editForm.vue";
import http from "@/utils/HttpUtil"; import http from "@/utils/HttpUtil";
// //
const qbBody = reactive({ const qbBody = reactive({
@ -32,7 +32,7 @@ onMounted(async () => {
downloadConfig = reactive(await http.post("/config/multCode", null, ["qbAddress", "qbUsername", "qbPassword"])); downloadConfig = reactive(await http.post("/config/multCode", null, ["qbAddress", "qbUsername", "qbPassword"]));
}); });
async function submit() { async function submit () {
let res = await http.post(""); let res = await http.post("");
} }
</script> </script>
@ -42,10 +42,12 @@ async function submit() {
display: flex; display: flex;
text-align: left; text-align: left;
padding-bottom: 0.5em; padding-bottom: 0.5em;
.left { .left {
width: 6em; width: 6em;
font-weight: 600; font-weight: 600;
} }
.right { .right {
flex: 1; flex: 1;
} }

View File

@ -2,38 +2,35 @@
<div v-loading="loading" element-loading-text="后台处理中,请稍候"> <div v-loading="loading" element-loading-text="后台处理中,请稍候">
<br /> <br />
<el-button type="success" @click="submit" size="default">开始重命名</el-button> <el-button type="success" @click="submit" size="default">开始重命名</el-button>
<el-divider content-position="left"><div class="head-text">规则设置</div></el-divider> <el-divider content-position="left">
<div class="head-text">规则设置</div>
</el-divider>
<!-- 规则列表 --> <!-- 规则列表 -->
<rule-block @ruleUpdate="ruleUpdate" /> <rule-block @ruleUpdate="ruleUpdate" />
<el-divider content-position="left"><div class="head-text">文件预览</div></el-divider> <el-divider content-position="left">
<div class="head-text">文件预览</div>
</el-divider>
<!-- 文件预览列表 --> <!-- 文件预览列表 -->
<div class="fileList"> <div class="fileList">
<div> <div>
<el-button type="primary" @click="showFileAdd" size="small">新增</el-button> <el-button type="primary" @click="showFileAdd" size="small">新增</el-button>
收藏路径:<el-tag 收藏路径:<el-tag v-for="item in savePathList" :round="true" class="savePath" closable :key="item.id"
v-for="item in savePathList" @click="clickSavePath(item)" @close="deleteSavePath(item)" text>{{ item.name }}</el-tag>
:round="true"
class="savePath"
closable
:key="item.id"
@click="clickSavePath(item)"
@close="deleteSavePath(item)"
text
>{{ item.name }}</el-tag
>
</div> </div>
<div> <div>
<el-button type="primary" size="small" @click="selectAllFiles">反选</el-button> <el-button type="primary" size="small" @click="selectAllFiles">反选</el-button>
<el-button type="danger" size="small" @click="deleteCheckedFiles">删除</el-button> <el-button type="danger" size="small" @click="deleteCheckedFiles">删除</el-button>
<el-button type="primary" size="small" @click="moveIndex('top')"> <el-button type="primary" size="small" @click="moveIndex('top')">
<el-tooltip effect="dark" content="上移规则" placement="top"> <el-tooltip effect="dark" content="上移规则" placement="top">
<el-icon><top /></el-icon> <el-icon>
<top />
</el-icon>
</el-tooltip> </el-tooltip>
</el-button> </el-button>
<el-button type="primary" size="small" @click="moveIndex('bottom')"> <el-button type="primary" size="small" @click="moveIndex('bottom')">
<el-tooltip effect="dark" content="下移规则" placement="top" <el-tooltip effect="dark" content="下移规则" placement="top"><el-icon>
><el-icon><bottom /></el-icon <bottom />
></el-tooltip> </el-icon></el-tooltip>
</el-button> </el-button>
</div> </div>
<div class="fileBlock"> <div class="fileBlock">
@ -55,7 +52,8 @@
<!-- 新增文件弹窗 --> <!-- 新增文件弹窗 -->
<el-dialog title="新增文件" v-model="dialogVisible" width="70%"> <el-dialog title="新增文件" v-model="dialogVisible" width="70%">
<file-chose ref="fileChose" :curChoosePath="curChoosePath" @addData="addData" @refreshSavePathList="refreshSavePathList" /> <file-chose ref="fileChose" type="file" :curChoosePath="curChoosePath" @addData="addData"
@refreshSavePathList="refreshSavePathList" />
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@ -65,7 +63,7 @@
import { Top, Bottom } from "@element-plus/icons-vue"; import { Top, Bottom } from "@element-plus/icons-vue";
import HttpUtil from "../../utils/HttpUtil"; import HttpUtil from "../../utils/HttpUtil";
import FileChose from "@/components/FileChose"; import FileChose from "@/components/FileChose";
import RuleBlock from "./components/RuleBlock.vue"; import RuleBlock from "@/components/rules/RuleBlock.vue";
import Bus from "../../utils/Bus"; import Bus from "../../utils/Bus";
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"]);
@ -78,7 +76,7 @@ export default {
Top, Top,
Bottom, Bottom,
}, },
data() { data () {
return { return {
loading: false, // loading: false, //
dialogVisible: false, // dialogVisible: false, //
@ -93,14 +91,14 @@ export default {
}; };
}, },
computed: {}, computed: {},
async created() { async created () {
this.savePathList = await HttpUtil.get("/file/path"); this.savePathList = await HttpUtil.get("/file/path");
window.isWindows = await HttpUtil.get("/file/isWindows"); window.isWindows = await HttpUtil.get("/file/isWindows");
Bus.$on("refreshSavePathList", this.refreshSavePathList); Bus.$on("refreshSavePathList", this.refreshSavePathList);
}, },
methods: { methods: {
// //
async addData(data) { async addData (data) {
data.forEach((item) => (item.checked = false)); data.forEach((item) => (item.checked = false));
this.fileList.push(...data); this.fileList.push(...data);
this.fileList = [...this.fileList.sort((a, b) => compareStr(a.name, b.name))]; this.fileList = [...this.fileList.sort((a, b) => compareStr(a.name, b.name))];
@ -108,13 +106,13 @@ export default {
this.needPreview = true; this.needPreview = true;
await this.showResult(); await this.showResult();
}, },
async ruleUpdate(rules) { async ruleUpdate (rules) {
this.ruleList = rules; this.ruleList = rules;
this.needPreview = true; this.needPreview = true;
await this.showResult(); await this.showResult();
}, },
// //
async showResult() { async showResult () {
this.changedFileList = []; this.changedFileList = [];
if (!this.checkRuleAndFile()) { if (!this.checkRuleAndFile()) {
return; return;
@ -130,7 +128,7 @@ export default {
this.loading = false; this.loading = false;
}, },
// //
async submit() { async submit () {
if (!this.checkRuleAndFile()) { if (!this.checkRuleAndFile()) {
return; return;
} }
@ -151,17 +149,17 @@ export default {
} }
}, },
// //
async deleteCheckedFiles() { async deleteCheckedFiles () {
this.fileList = this.fileList.filter((item) => !item.checked); this.fileList = this.fileList.filter((item) => !item.checked);
this.needPreview = true; this.needPreview = true;
await this.showResult(); await this.showResult();
}, },
// //
selectAllFiles() { selectAllFiles () {
this.fileList.forEach((item) => (item.checked = !item.checked)); this.fileList.forEach((item) => (item.checked = !item.checked));
}, },
// //
checkRuleAndFile() { checkRuleAndFile () {
if (this.fileList.length == 0) { if (this.fileList.length == 0) {
this.$message({ message: "请选择文件", type: "warning" }); this.$message({ message: "请选择文件", type: "warning" });
return false; return false;
@ -173,7 +171,7 @@ export default {
return true; return true;
}, },
// //
async moveIndex(type) { async moveIndex (type) {
let temps = this.fileList.filter((item) => item.checked == true); let temps = this.fileList.filter((item) => item.checked == true);
if (temps.length == 0) { if (temps.length == 0) {
this.$message({ type: "warning", message: "未选中文件,无法移动" }); this.$message({ type: "warning", message: "未选中文件,无法移动" });
@ -208,20 +206,20 @@ export default {
this.timer = null; this.timer = null;
}, 1000); }, 1000);
}, },
showFileAdd() { showFileAdd () {
this.dialogVisible = true; this.dialogVisible = true;
}, },
// //
async clickSavePath(item) { async clickSavePath (item) {
this.curChoosePath = JSON.parse(item.content); this.curChoosePath = JSON.parse(item.content);
this.dialogVisible = true; this.dialogVisible = true;
}, },
async deleteSavePath(item) { async deleteSavePath (item) {
console.log(item); console.log(item);
await HttpUtil.delete("/file/path/delete", { id: item.id }); await HttpUtil.delete("/file/path/delete", { id: item.id });
Bus.$emit("refreshSavePathList"); Bus.$emit("refreshSavePathList");
}, },
async refreshSavePathList() { async refreshSavePathList () {
this.savePathList = await HttpUtil.get("/file/path"); this.savePathList = await HttpUtil.get("/file/path");
}, },
}, },
@ -232,10 +230,10 @@ export default {
* @param a str * @param a str
* @param b str * @param b str
*/ */
function compareStr(a, b) { function compareStr (a, b) {
let an = a.length; let an = a.length;
let bn = b.length; let bn = b.length;
for (let i = 0; i < an; ) { for (let i = 0; i < an;) {
let charA = readChar(a, i, an); let charA = readChar(a, i, an);
let charB = readChar(b, i, bn); let charB = readChar(b, i, bn);
if (charB.length == 0) { if (charB.length == 0) {
@ -257,7 +255,7 @@ function compareStr(a, b) {
* @param a a * @param a a
* @param n 数字长度 * @param n 数字长度
*/ */
function readChar(a, i, n) { function readChar (a, i, n) {
let res = ""; let res = "";
for (; i < n; i++) { for (; i < n; i++) {
let char = a.charAt(i); let char = a.charAt(i);
@ -282,6 +280,7 @@ function readChar(a, i, n) {
cursor: pointer; cursor: pointer;
margin-right: 0.5em; margin-right: 0.5em;
} }
.fileList { .fileList {
margin-top: 20px; margin-top: 20px;
text-align: left; text-align: left;
@ -289,6 +288,7 @@ function readChar(a, i, n) {
.fileBlock { .fileBlock {
margin-top: 20px; margin-top: 20px;
display: flex; display: flex;
.oneLine { .oneLine {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;