feat:规则增加排序

This commit is contained in:
fanxb 2022-11-29 23:02:06 +08:00
parent cfdb36ca31
commit 25aefe2aaa
20 changed files with 418 additions and 129 deletions

View File

@ -1,6 +1,5 @@
import { Context } from "koa";
import ApplicationRuleService from "../service/ApplicationRuleService";
import config from "../config";
const router = {};
@ -11,6 +10,14 @@ router["GET /applicationRule"] = async function (ctx: Context) {
ctx.body = await ApplicationRuleService.getAll();
};
/**
*
*/
router["GET /applicationRule/default"] = async function (ctx: Context) {
;
ctx.body = await ApplicationRuleService.getDefault();
};
/**
*
*/
@ -26,4 +33,6 @@ router["DELETE /applicationRule/:id"] = async function (ctx: Context) {
ctx.body = "";
};
export default router;

View File

@ -0,0 +1,22 @@
import { Context } from "koa";
import service from "../service/GlobalService";
const router = {};
/**
*
*/
router["GET /config/code"] = async function (ctx: Context) {
ctx.body = await service.getVal(ctx.request.query.code as string);
};
/**
*
*/
router["POST /config/update"] = async function (ctx: Context) {
ctx.body = await service.updateVal(ctx.request.body.code, ctx.request.body.val);
};
export default router;

View File

@ -1,5 +1,5 @@
import ErrorHelper from "../util/ErrorHelper";
import ApplicationRule from "../entity/dto/ApplicationRule";
import ApplicationRule from "../entity/po/ApplicationRule";
import SqliteHelper from "../util/SqliteHelper";
export default class ApplicationRuleDao {
@ -13,6 +13,18 @@ export default class ApplicationRuleDao {
return res;
}
/**
* id
* @param id id
* @returns
*/
static async getById(id: number): Promise<ApplicationRule> {
let res = await SqliteHelper.pool.get('select * from application_rule where id=?', id);
return res;
}
/**
*

View File

@ -0,0 +1,50 @@
import ErrorHelper from "../util/ErrorHelper";
import SqliteHelper from "../util/SqliteHelper";
import GlobalConfig from "../entity/po/GlobalConfig";
export default class GlobalConfigDao {
/**
*
* @param obj
* @returns
*/
static async addOne(obj: GlobalConfig): Promise<void> {
await SqliteHelper.pool.run('insert into global_config(code,val,description) values(?,?,?)'
, obj.code, obj.val, obj.description);
}
/**
*
* @param code code
* @param val val
*/
static async updateOne(code: string, val: string): Promise<void> {
await SqliteHelper.pool.run('update global_config set val=? where code=?', val, code);
}
/**
*
* @param code
*/
static async deleteByCode(code: string): Promise<void> {
let res = await SqliteHelper.pool.run('delete from global_config where code=?', code);
if (res.changes == 0) {
throw ErrorHelper.Error404("数据不存在");
}
}
/**
*
* @param code
*/
static async getByCode(code: string): Promise<string> {
let res = await SqliteHelper.pool.get('select val from global_config where code=?', code);
return res ? res.val : null;
}
}

View File

@ -1,5 +1,5 @@
import ErrorHelper from "../util/ErrorHelper";
import SavePath from "../entity/dto/SavePath";
import SavePath from "../entity/po/SavePath";
import SqliteHelper from "../util/SqliteHelper";
export default class SavePathDao {

View File

@ -0,0 +1,4 @@
/**
* id
*/
export const DEFAULT_TEMPLETE_ID = "defaultTempleteId";

View File

@ -20,4 +20,12 @@ export default class ApplicationRule {
json序列化后
*/
content: string;
constructor(name: string, comment: string, content: string) {
this.createdDate = Date.now();
this.updatedDate = this.createdDate;
this.name = name;
this.comment = comment;
this.content = content;
}
}

View File

@ -0,0 +1,21 @@
export default class GlobalConfig {
/**
code
*/
code: string;
/**
json序列化后
*/
val: string;
/**
*/
description: string;
constructor(code: string, val: string, desc: string) {
this.code = code;
this.val = val;
this.description = desc;
}
}

View File

@ -1,9 +1,9 @@
import config from '../config';
import * as path from 'path';
import * as fs from 'fs-extra';
import ApplicationRule from '../entity/dto/ApplicationRule';
import ApplicationRule from '../entity/po/ApplicationRule';
import ApplicationRuleDao from '../dao/ApplicationRuleDao';
import GlobalConfigDao from '../dao/GlobalConfigDao';
import { DEFAULT_TEMPLETE_ID } from '../entity/constants/GlobalConfigCodeConstant';
import GlobalConfig from '../entity/po/GlobalConfig';
class ApplicationRuleService {
@ -28,6 +28,39 @@ class ApplicationRuleService {
await ApplicationRuleDao.delete(id);
}
/**
*
*/
static async getDefault(): Promise<ApplicationRule> {
let res: ApplicationRule;
let idStr = await GlobalConfigDao.getByCode(DEFAULT_TEMPLETE_ID);
if (idStr == null) {
let templteList = await ApplicationRuleDao.getAll();
if (templteList.length == 0) {
res = new ApplicationRule("默认模板", "此模板为系统创建", "[]");
await ApplicationRuleService.saveOrAdd(res);
} else {
res = templteList[0];
}
await GlobalConfigDao.addOne(new GlobalConfig(DEFAULT_TEMPLETE_ID, res.id.toString(), "默认模板id"));
} else {
let templteList = await ApplicationRuleDao.getAll();
if (templteList.length == 0) {
res = new ApplicationRule("默认模板", "此模板为系统创建", "[]");
await ApplicationRuleService.saveOrAdd(res);
await GlobalConfigDao.updateOne(DEFAULT_TEMPLETE_ID, res.id.toString());
} else {
let temp = templteList.filter(item => item.id.toString() === idStr);
if (temp.length > 0) {
res = temp[0];
} else {
res = templteList[0];
await GlobalConfigDao.updateOne(DEFAULT_TEMPLETE_ID, res.id.toString());
}
}
}
return res;
}
}
export default ApplicationRuleService;

View File

@ -5,7 +5,7 @@ import * as fs from 'fs-extra';
import ProcessHelper from '../util/ProcesHelper';
import FileObj from '../entity/vo/FileObj';
import SavePathDao from '../dao/SavePathDao';
import SavePath from '../entity/dto/SavePath';
import SavePath from '../entity/po/SavePath';
let numberSet = new Set(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);

View File

@ -0,0 +1,18 @@
import GlobalConfigDao from '../dao/GlobalConfigDao';
import { DEFAULT_TEMPLETE_ID } from '../entity/constants/GlobalConfigCodeConstant';
import GlobalConfig from '../entity/po/GlobalConfig';
class GlobalConfigService {
static async getVal(code: string): Promise<string> {
return GlobalConfigDao.getByCode(code);
}
static async updateVal(code: string, val: string): Promise<void> {
return GlobalConfigDao.updateOne(code, val);
}
}
export default GlobalConfigService;

View File

@ -0,0 +1,6 @@
CREATE TABLE global_config (
code TEXT(40),
val TEXT(200),
description TEXT(100) DEFAULT (''),
CONSTRAINT global_config_PK PRIMARY KEY (code)
);

View File

@ -5,7 +5,7 @@
"module": "commonjs",
"sourceMap": true,
"outDir": "./dist",
"baseUrl":".",
"baseUrl": ".",
"rootDir": "./",
"watch": false,
"strict": true,

View File

@ -40,7 +40,7 @@ class SqliteHelper {
try {
let sql = "";
for (let j = 0; j < sqlLines.length; j++) {
sql = sql + sqlLines[j];
sql = sql + " " + sqlLines[j];
if (sqlLines[j].endsWith(";")) {
await SqliteHelper.pool.run(sql);
sql = "";

View File

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

View File

@ -1,6 +1,8 @@
<template>
<div class="app">
<div class="head">菜单栏</div>
<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>
<div class="content">
<router-view />
</div>
@ -14,8 +16,8 @@ export default {
name: "Home",
data() {
return {
activeIndex: "dealCenter",
version: "1.0",
activeIndex: this.$route.hash,
};
},
async created() {
@ -32,6 +34,7 @@ body {
padding: 0;
border: 0;
margin: 0;
background-color: #e8e8e5;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
@ -46,8 +49,14 @@ body {
display: flex;
flex-direction: column;
width: 80%;
min-width: 800px;
margin: 0 auto;
background-color: white;
.content {
flex: 1;
padding: 0 10px 0 10px;
}
}
@ -63,4 +72,10 @@ body {
}
}
}
.head-text {
font-size: 1.5em;
font-weight: 600;
padding-right: 0.5em;
}
</style>

View File

@ -2,16 +2,14 @@
<div v-loading="loading" element-loading-text="后台处理中,请稍候">
<br />
<el-button type="success" @click="submit" size="default">开始重命名</el-button>
<br /><br />
<el-divider content-position="left"><div class="head-text">规则设置</div></el-divider>
<!-- 规则列表 -->
<rule-block @ruleUpdate="ruleUpdate" />
<el-divider content-position="left"><div class="head-text">文件预览</div></el-divider>
<!-- 文件预览列表 -->
<div class="fileList">
<div>
文件列表
<el-button type="primary" @click="showFileAdd" size="small">新增</el-button>
<el-button type="primary" size="small" @click="selectAllFiles">反选</el-button>
<el-button type="danger" size="small" @click="deleteCheckedFiles">删除</el-button>
收藏路径:<el-tag
v-for="item in savePathList"
:round="true"
@ -24,23 +22,27 @@
>{{ item.name }}</el-tag
>
</div>
<div>
<el-button type="primary" size="small" @click="selectAllFiles">反选</el-button>
<el-button type="danger" size="small" @click="deleteCheckedFiles">删除</el-button>
<template v-if="showMove">
<el-button type="primary" size="small" @click="moveIndex('top')">
<el-tooltip effect="dark" content="上移规则" placement="top">
<el-icon><top /></el-icon>
</el-tooltip>
</el-button>
<el-button type="primary" size="small" @click="moveIndex('bottom')">
<el-tooltip effect="dark" content="下移规则" placement="top"
><el-icon><bottom /></el-icon
></el-tooltip>
</el-button>
</template>
</div>
<div class="fileBlock">
<!-- 左侧原始文件名 -->
<div style="flex: 4">
<div v-for="(item, index) in fileList" :key="index" class="oneLine">
<el-checkbox v-model="item.checked" style="height: 1.2em">{{ item.name }}</el-checkbox>
<div style="display: flex; align-items: center; padding-right: 4em">
<ArrowDownBold
style="width: 20px; padding-left: 10px; cursor: pointer"
v-if="index < fileList.length - 1"
@click.stop.prevent="moveIndex(index + 1, index)"
/>
<ArrowUpBold
style="width: 20px; padding-left: 10px; cursor: pointer"
v-if="index > 0"
@click.stop.prevent="moveIndex(index - 1, index)"
/>
</div>
</div>
</div>
<!-- 右边的预览文件名 -->
@ -62,7 +64,7 @@
<script>
// @ is an alias to /src
import { ArrowDownBold, ArrowUpBold } from "@element-plus/icons-vue";
import { Top, Bottom } from "@element-plus/icons-vue";
import HttpUtil from "../../utils/HttpUtil";
import FileChose from "@/components/FileChose";
import RuleBlock from "./components/RuleBlock.vue";
@ -74,9 +76,9 @@ export default {
name: "Home",
components: {
FileChose,
ArrowDownBold,
ArrowUpBold,
RuleBlock,
Top,
Bottom,
},
data() {
return {
@ -89,8 +91,14 @@ export default {
applicationRule: null, //
savePathList: [], //
curChoosePath: null, //
timer: null, //
};
},
computed: {
showMove() {
return this.fileList.filter((item) => item.checked == true).length == 1;
},
},
async created() {
this.savePathList = await HttpUtil.get("/file/path");
window.isWindows = await HttpUtil.get("/file/isWindows");
@ -113,6 +121,7 @@ export default {
},
//
async showResult() {
this.changedFileList = [];
if (!this.checkRuleAndFile()) {
return;
}
@ -170,13 +179,32 @@ export default {
return true;
},
//
async moveIndex(newIndex, index) {
let temp = this.fileList[index];
async moveIndex(type) {
let temp = this.fileList.filter((item) => item.checked == true)[0];
let index = this.fileList.indexOf(temp);
let newIndex;
if (type == "top") {
if (index == 0) {
return;
}
newIndex = index - 1;
} else {
if (index == this.fileList.length - 1) {
return;
}
newIndex = index + 1;
}
this.fileList[index] = this.fileList[newIndex];
this.fileList[newIndex] = temp;
this.fileList = [...this.fileList];
this.needPreview = true;
await this.showResult();
if (this.timer != null) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
this.showResult();
this.timer = null;
}, 1000);
},
showFileAdd() {
this.dialogVisible = true;

View File

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

View File

@ -1,45 +1,42 @@
<template>
<div class="main">
<div class="menu">
<span>应用规则</span>
<el-button type="primary" size="small" @click="addRuleDialogShow = true">新增</el-button>
<el-button type="primary" size="small" v-if="checkedRules.length == 1" @click="editClick">编辑</el-button>
<el-button type="warning" size="small" @click="block">禁用/启用</el-button>
<el-button type="danger" size="small" @click="deleteRule">删除</el-button>
<el-button type="primary" size="small" v-if="chosedTemplate" @click="templateSubmit">保存规则</el-button>
<el-button type="primary" size="small" v-if="chosedTemplate == null && ruleList.length > 0" @click="saveTemplateDilalogShow = true"
>存为模板</el-button
>
<el-button type="primary" size="small" @click="templateSubmit">保存</el-button>
<el-button type="primary" size="small" @click="ruleTemplateShow = true">选择模板</el-button>
<template v-if="checkedRules.length == 1">
<el-button type="primary" size="small" @click="editClick">
<el-tooltip effect="dark" content="编辑规则" placement="top">
<el-icon><edit /></el-icon>
</el-tooltip>
</el-button>
<el-button type="primary" size="small" @click="move('top')">
<el-tooltip effect="dark" content="上移规则" placement="top">
<el-icon><top /></el-icon>
</el-tooltip>
</el-button>
<el-button type="primary" size="small" @click="move('bottom')">
<el-tooltip effect="dark" content="下移规则" placement="top"
><el-icon><bottom /></el-icon
></el-tooltip>
</el-button>
</template>
</div>
<div class="ruleBlock">
<el-checkbox v-model="item.checked" v-for="(item, index) in ruleList" :key="index" @dblclick="editClick(item)">
<s v-if="item.blocked">{{ item.message }}</s>
<span v-else>{{ item.message }}</span>
</el-checkbox>
<div v-if="ruleList.length == 0 && chosedTemplate == null" class="choseTemplate">
<el-button type="primary" size="small" @click="ruleTemplateShow = true">选择模板</el-button>
<div style="padding-top: 0.5em">
<el-button type="primary" size="small" text @click="addRuleDialogShow = true">+ 新增规则</el-button>
</div>
</div>
<!-- 弹窗 -->
<el-dialog title="新增规则" v-model="addRuleDialogShow" width="70%" @close="ruleDialogClose">
<rule :editRule="editRule" @ruleAdd="ruleAdd" v-if="addRuleDialogShow" />
</el-dialog>
<el-dialog title="选择规则模板" v-model="ruleTemplateShow" width="70%">
<application-rule-list v-if="ruleTemplateShow" v-model="chosedTemplate" @close="ruleTemplateShow = false" />
</el-dialog>
<el-dialog title="保存模板" v-model="saveTemplateDilalogShow" width="70%">
<el-form-item label="名称">
<el-input v-model="templateForm.name"></el-input>
</el-form-item>
<el-form-item label="描述">
<el-input v-model="templateForm.comment"></el-input>
</el-form-item>
<template #footer>
<span class="dialog-footer">
<el-button @click="saveTemplateDilalogShow = false">取消</el-button>
<el-button type="primary" @click="templateSubmit">提交</el-button>
</span>
</template>
<el-dialog title="模板管理" v-model="ruleTemplateShow" width="70%">
<application-rule-list v-if="ruleTemplateShow" @templateUpdate="templateUpdate" />
</el-dialog>
</div>
</template>
@ -48,24 +45,23 @@
import Rule from "../../../components/Rule";
import ApplicationRuleList from "./ApplicationRuleList";
import HttpUtil from "../../../utils/HttpUtil";
import { Top, Bottom, Edit } from "@element-plus/icons-vue";
export default {
name: "RuleBlock",
components: {
Rule,
ApplicationRuleList,
Edit,
Top,
Bottom,
},
data() {
return {
addRuleDialogShow: false, //
ruleTemplateShow: false, //
saveTemplateDilalogShow: false, //
ruleList: [],
editRule: null, //
chosedTemplate: null,
templateForm: {
name: "",
comment: "",
},
};
},
computed: {
@ -74,45 +70,29 @@ export default {
return this.ruleList.filter((item) => item.checked);
},
},
watch: {
chosedTemplate(newVal, oldVal) {
this.ruleList = JSON.parse(newVal.content);
this.ruleUpdate();
},
async created() {
this.chosedTemplate = await HttpUtil.get("/applicationRule/default");
this.ruleList = JSON.parse(this.chosedTemplate.content);
await this.ruleUpdate();
},
methods: {
//
ruleUpdate() {
this.$emit(
"ruleUpdate",
this.ruleList.filter((item) => !item.blocked)
);
},
//
saveOrUpdateTemplate() {
if (this.chosedTemplate != null) {
this.templateSubmit();
} else {
this.saveTemplateDilalogShow = true;
}
let temp = this.ruleList.filter((item) => !item.blocked);
this.$emit("ruleUpdate", temp);
},
//
async templateSubmit() {
let body;
if (this.chosedTemplate) {
this.chosedTemplate.content = JSON.stringify(this.ruleList);
body = this.chosedTemplate;
} else {
body = {
name: this.templateForm.name,
comment: this.templateForm.comment,
content: JSON.stringify(this.ruleList),
};
}
this.chosedTemplate = await HttpUtil.post("/applicationRule", null, body);
this.saveTemplateDilalogShow = false;
this.chosedTemplate.content = JSON.stringify(this.ruleList);
await HttpUtil.post("/applicationRule", null, this.chosedTemplate);
this.$message.success("操作成功");
},
//
async templateUpdate(newVal) {
this.ruleList = JSON.parse(newVal.content);
this.ruleUpdate();
this.ruleTemplateShow = false;
},
//
async ruleAdd(data) {
if (this.editRule != null) {
@ -134,7 +114,7 @@ export default {
item.blocked = !item.blocked;
item.checked = false;
});
this.ruleUpdate();
await this.ruleUpdate();
},
//
async deleteRule() {
@ -146,6 +126,28 @@ export default {
this.editRule = rule && rule.data ? rule : this.checkedRules[0];
this.addRuleDialogShow = true;
},
//
async move(type) {
let index = this.ruleList.indexOf(this.checkedRules[0]);
let newIndex;
if (type == "top") {
if (index == 0) {
return;
}
newIndex = index - 1;
} else {
if (index == this.ruleList.length - 1) {
return;
}
newIndex = index + 1;
}
let temp = this.checkedRules[0];
this.ruleList[index] = this.ruleList[newIndex];
this.ruleList[newIndex] = temp;
this.ruleList = [...this.ruleList];
await this.ruleUpdate();
},
//
ruleDialogClose() {
this.editRule = null;
this.addRuleDialogShow = false;
@ -157,7 +159,6 @@ export default {
<style lang="less" scoped>
.main {
text-align: left;
border: 1px solid black;
padding: 5px;
.menu {
display: flex;