<template>
<div class="app-container">
<el-table :data="rolesList" style="width: 100%; margin-top: 30px" border>
<el-table-column align="center" label="收费学段" width="220">
<template slot-scope="scope">
{{ scope.row.sfxd }}
</template>
</el-table-column>
<el-table-column align="center" label="学校" width="220">
<template slot-scope="scope">
{{ scope.row.xx }}
</template>
</el-table-column>
<el-table-column align="center" label="类型" width="220">
<template slot-scope="scope">
{{ scope.row.lx }}
</template>
</el-table-column>
<el-table-column align="center" label="项目名称" width="220">
<template slot-scope="scope">
{{ scope.row.xmmc }}
</template>
</el-table-column>
<el-table-column align="center" label="项目状态" width="220">
<template slot-scope="scope">
{{ scope.row.xmzt }}
</template>
</el-table-column>
<el-table-column align="center" label="金额(元/人)" width="220">
<template slot-scope="scope">
{{ scope.row.je }}
</template>
</el-table-column>
<el-table-column align="center" label="状态" width="220">
<template slot-scope="scope">
{{ scope.row.zt }}
</template>
</el-table-column>
<el-table-column align="center" label="开始时间" width="220">
<template slot-scope="scope">
{{ scope.row.kssj }}
</template>
</el-table-column>
</el-table>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType === 'edit' ? 'Edit Role' : 'New Role'"
>
<el-form :model="role" label-width="80px" label-position="left">
<el-form-item label="Name">
<el-input v-model="role.name" placeholder="Role Name" />
</el-form-item>
<el-form-item label="Desc">
<el-input
v-model="role.description"
:autosize="{ minRows: 2, maxRows: 4 }"
type="textarea"
placeholder="Role Description"
/>
</el-form-item>
<el-form-item label="Menus">
<el-tree
ref="tree"
:check-strictly="checkStrictly"
:data="routesData"
:props="defaultProps"
show-checkbox
node-key="path"
class="permission-tree"
/>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">
{{ $t("permission.cancel") }}
</el-button>
<el-button type="primary" @click="confirmRole">
{{ $t("permission.confirm") }}
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import path from "path";
import { deepClone } from "@/utils";
import {
getRoutes,
getRoles,
addRole,
deleteRole,
updateRole,
} from "@/api/role";
import i18n from "@/lang";
const defaultRole = {
key: "",
name: "",
description: "",
routes: [],
};
export default {
data() {
return {
role: Object.assign({}, defaultRole),
routes: [],
rolesList: [
{
sfxd: "小学",
xx: "中兴小学",
lx: "基础",
xmmc: "餐费",
xmzt: "进行中",
je: "20",
zt: "启用",
kssj: "2025-01-01",
},
{
sfxd: "小学",
xx: "实验小学",
lx: "基础",
xmmc: "书本费",
xmzt: "进行中",
je: "360",
zt: "启用",
kssj: "2025-01-01",
},
],
dialogVisible: false,
dialogType: "new",
checkStrictly: false,
defaultProps: {
children: "children",
label: "title",
},
};
},
computed: {
routesData() {
return this.routes;
},
},
created() {
// Mock: get all routes and roles list from server
// this.getRoutes();
// this.getRoles();
},
methods: {
async getRoutes() {
const res = await getRoutes();
this.serviceRoutes = res.data;
const routes = this.generateRoutes(res.data);
this.routes = this.i18n(routes);
},
async getRoles() {
const res = await getRoles();
this.rolesList = res.data;
},
i18n(routes) {
const app = routes.map((route) => {
route.title = i18n.t(`route.${route.title}`);
if (route.children) {
route.children = this.i18n(route.children);
}
return route;
});
return app;
},
// Reshape the routes structure so that it looks the same as the sidebar
generateRoutes(routes, basePath = "/") {
const res = [];
for (let route of routes) {
// skip some route
if (route.hidden) {
continue;
}
const onlyOneShowingChild = this.onlyOneShowingChild(
route.children,
route
);
if (route.children && onlyOneShowingChild && !route.alwaysShow) {
route = onlyOneShowingChild;
}
const data = {
path: path.resolve(basePath, route.path),
title: route.meta && route.meta.title,
};
// recursive child routes
if (route.children) {
data.children = this.generateRoutes(route.children, data.path);
}
res.push(data);
}
return res;
},
generateArr(routes) {
let data = [];
routes.forEach((route) => {
data.push(route);
if (route.children) {
const temp = this.generateArr(route.children);
if (temp.length > 0) {
data = [...data, ...temp];
}
}
});
return data;
},
handleAddRole() {
this.role = Object.assign({}, defaultRole);
if (this.$refs.tree) {
this.$refs.tree.setCheckedNodes([]);
}
this.dialogType = "new";
this.dialogVisible = true;
},
handleEdit(scope) {
this.dialogType = "edit";
this.dialogVisible = true;
this.checkStrictly = true;
this.role = deepClone(scope.row);
this.$nextTick(() => {
const routes = this.generateRoutes(this.role.routes);
this.$refs.tree.setCheckedNodes(this.generateArr(routes));
// set checked state of a node not affects its father and child nodes
this.checkStrictly = false;
});
},
handleDelete({ $index, row }) {
this.$confirm("Confirm to remove the role?", "Warning", {
confirmButtonText: "Confirm",
cancelButtonText: "Cancel",
type: "warning",
})
.then(async () => {
await deleteRole(row.key);
this.rolesList.splice($index, 1);
this.$message({
type: "success",
message: "Delete succed!",
});
})
.catch((err) => {
console.error(err);
});
},
generateTree(routes, basePath = "/", checkedKeys) {
const res = [];
for (const route of routes) {
const routePath = path.resolve(basePath, route.path);
// recursive child routes
if (route.children) {
route.children = this.generateTree(
route.children,
routePath,
checkedKeys
);
}
if (
checkedKeys.includes(routePath) ||
(route.children && route.children.length >= 1)
) {
res.push(route);
}
}
return res;
},
async confirmRole() {
const isEdit = this.dialogType === "edit";
const checkedKeys = this.$refs.tree.getCheckedKeys();
this.role.routes = this.generateTree(
deepClone(this.serviceRoutes),
"/",
checkedKeys
);
if (isEdit) {
await updateRole(this.role.key, this.role);
for (let index = 0; index < this.rolesList.length; index++) {
if (this.rolesList[index].key === this.role.key) {
this.rolesList.splice(index, 1, Object.assign({}, this.role));
break;
}
}
} else {
const { data } = await addRole(this.role);
this.role.key = data.key;
this.rolesList.push(this.role);
}
const { description, key, name } = this.role;
this.dialogVisible = false;
this.$notify({
title: "Success",
dangerouslyUseHTMLString: true,
message: `
<div>Role Key: ${key}</div>
<div>Role Name: ${name}</div>
<div>Description: ${description}</div>
`,
type: "success",
});
},
// reference: src/view/layout/components/Sidebar/SidebarItem.vue
onlyOneShowingChild(children = [], parent) {
let onlyOneChild = null;
const showingChildren = children.filter((item) => !item.hidden);
// When there is only one child route, the child route is displayed by default
if (showingChildren.length === 1) {
onlyOneChild = showingChildren[0];
onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path);
return onlyOneChild;
}
// Show parent if there are no child route to display
if (showingChildren.length === 0) {
onlyOneChild = { ...parent, path: "", noShowingChildren: true };
return onlyOneChild;
}
return false;
},
},
};
</script>
<style lang="scss" scoped>
.app-container {
.roles-table {
margin-top: 30px;
}
.permission-tree {
margin-bottom: 30px;
}
}
</style>
这套代码也是一样 按照去前面的样式结构 加入搜索和分页功能
最新发布