feat:按钮权限,fix更新角色菜单没过滤关联表状态9的数据问题
This commit is contained in:
parent
aa20898bc8
commit
2ff52ce086
@ -13,7 +13,7 @@ async def get_role_menus(rid: int):
|
||||
"""
|
||||
select m.id, m.name, m.meta, m.path, m.type, m.component, m.pid, m.identifier
|
||||
FROM sys_menu as m, sys_role_menu WHERE m.id = sys_role_menu.mid
|
||||
AND sys_role_menu.rid = (?) AND m.`status` = 1""",
|
||||
AND sys_role_menu.rid = (?) AND sys_role_menu.`status` = 1""",
|
||||
[rid],
|
||||
)
|
||||
|
||||
|
@ -32,7 +32,20 @@ async def get_user_info(user: UserModel):
|
||||
[user.id],
|
||||
)
|
||||
|
||||
return {**jsonable_encoder(user), "roles": sql_result}
|
||||
# 当前激活角色的按钮权限列表
|
||||
perm_result = await db.execute_query_dict(
|
||||
"""
|
||||
select m.identifier from sys_role_menu as rm, sys_menu as m where rm.mid = m.id and rm.rid = (?) and
|
||||
m.identifier not null and m.identifier != "" and rm.status != 9
|
||||
""",
|
||||
[sql_result[0]["id"]],
|
||||
)
|
||||
|
||||
return {
|
||||
**jsonable_encoder(user),
|
||||
"roles": sql_result,
|
||||
"permissions": [i["identifier"] for i in perm_result],
|
||||
}
|
||||
|
||||
|
||||
async def get_users(skip: int, limit: int, kwargs: dict = None):
|
||||
|
Binary file not shown.
Binary file not shown.
@ -41,6 +41,7 @@ class UserInfo(UserRead):
|
||||
"""用户信息模型"""
|
||||
|
||||
roles: list[UserHasRole] = Field(..., description="用户拥有角色")
|
||||
permissions: list[str] = Field(..., description="角色拥有的按钮权限标识")
|
||||
|
||||
|
||||
class RoleActive(BaseModel):
|
||||
|
25
frontend/package-lock.json
generated
25
frontend/package-lock.json
generated
@ -10,6 +10,8 @@
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^3.2.12",
|
||||
"axios": "^0.27.2",
|
||||
"moment": "^2.29.4",
|
||||
"monent": "^0.0.2-security",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pinia": "^2.0.21",
|
||||
"pinia-plugin-persistedstate": "^2.2.0",
|
||||
@ -1131,6 +1133,19 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/monent": {
|
||||
"version": "0.0.2-security",
|
||||
"resolved": "https://registry.npmjs.org/monent/-/monent-0.0.2-security.tgz",
|
||||
"integrity": "sha512-qghr6SG18OAHdr2emuACuhMJWUi1Yax10+V0N1Fr3ISC921hOtw6g7fuDxdgJszzSGTMFyKiUgBRafpKRrsjkQ=="
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
@ -2365,6 +2380,16 @@
|
||||
"brace-expansion": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||
},
|
||||
"monent": {
|
||||
"version": "0.0.2-security",
|
||||
"resolved": "https://registry.npmjs.org/monent/-/monent-0.0.2-security.tgz",
|
||||
"integrity": "sha512-qghr6SG18OAHdr2emuACuhMJWUi1Yax10+V0N1Fr3ISC921hOtw6g7fuDxdgJszzSGTMFyKiUgBRafpKRrsjkQ=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
|
@ -9,6 +9,7 @@
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^3.2.12",
|
||||
"axios": "^0.27.2",
|
||||
"moment": "^2.29.4",
|
||||
"normalize.css": "^8.0.1",
|
||||
"pinia": "^2.0.21",
|
||||
"pinia-plugin-persistedstate": "^2.2.0",
|
||||
|
@ -10,9 +10,10 @@ import "normalize.css";
|
||||
import "@/assets/css/base.css";
|
||||
|
||||
import "ant-design-vue/dist/antd.css";
|
||||
import hasPermisson from "@/utils/directive";
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
hasPermisson(app);
|
||||
app.use(store);
|
||||
|
||||
userStore().loadRoleRouter();
|
||||
|
@ -29,3 +29,10 @@ export function selectRole(rid) {
|
||||
method: "put",
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户列表
|
||||
export function getUsers() {
|
||||
return request({
|
||||
url: "/user",
|
||||
});
|
||||
}
|
||||
|
17
frontend/src/utils/directive.js
Normal file
17
frontend/src/utils/directive.js
Normal file
@ -0,0 +1,17 @@
|
||||
import { userStore } from "@/stores/user";
|
||||
|
||||
export default (app) => {
|
||||
// 按钮权限
|
||||
app.directive("per", {
|
||||
mounted(el, binding) {
|
||||
console.log(el, binding.value);
|
||||
if (
|
||||
// 是否存在
|
||||
userStore().userInfo.permissions.indexOf(binding.value) === -1
|
||||
) {
|
||||
// 删除元素
|
||||
el.parentNode && el.parentNode.removeChild(el);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
5
frontend/src/utils/format.js
Normal file
5
frontend/src/utils/format.js
Normal file
@ -0,0 +1,5 @@
|
||||
import moment from "moment";
|
||||
|
||||
export const formatTime = (value) => {
|
||||
return moment(value).format("YYYY-MM-DD HH:mm:ss");
|
||||
};
|
@ -20,7 +20,7 @@ export default (config) => {
|
||||
if (res.data.code !== 200) {
|
||||
message.error(res.data.msg);
|
||||
}
|
||||
|
||||
console.log(res.data);
|
||||
return res.data;
|
||||
},
|
||||
(err) => {
|
||||
|
39
frontend/src/views/main/system/user/conf.js
Normal file
39
frontend/src/views/main/system/user/conf.js
Normal file
@ -0,0 +1,39 @@
|
||||
// 表格数据列 表头配置
|
||||
export const columns = [
|
||||
{
|
||||
title: "序号",
|
||||
dataIndex: "index",
|
||||
key: "index",
|
||||
align: "center",
|
||||
customRender: ({ text, record, index }) => `${index + 1}`,
|
||||
},
|
||||
{
|
||||
title: "用户名",
|
||||
dataIndex: "username",
|
||||
key: "username",
|
||||
},
|
||||
{
|
||||
title: "昵称",
|
||||
dataIndex: "nickname",
|
||||
key: "nickname",
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
dataIndex: "status",
|
||||
key: "status",
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
dataIndex: "created",
|
||||
key: "created",
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
dataIndex: "modified",
|
||||
key: "modified",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
},
|
||||
];
|
@ -1,7 +1,122 @@
|
||||
<script setup></script>
|
||||
<script setup>
|
||||
import { getUsers } from "@/service/user";
|
||||
import { columns } from "./conf";
|
||||
import { formatTime } from "@/utils/format";
|
||||
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
|
||||
import { PlusOutlined, SearchOutlined } from "@ant-design/icons-vue";
|
||||
|
||||
// 列表数据
|
||||
const dataSource = ref([]);
|
||||
|
||||
// 页面展示数据条数变化回调
|
||||
const pageSizeChange = (current, size) => {
|
||||
console.log(current, size, "展示数量变化");
|
||||
};
|
||||
|
||||
// 页码变化回调
|
||||
const pageChange = (page, pageSize) => {
|
||||
console.log(page, pageSize, "页码变化");
|
||||
};
|
||||
|
||||
//分页
|
||||
const pagination = reactive({
|
||||
current: 1, //当前页
|
||||
pageSize: 10, // 每页数量
|
||||
showSizeChanger: true,
|
||||
total: 200,
|
||||
pageSizeOptions: ["10", "50", "100"],
|
||||
showTotal: (total) => `共${total}条数据`,
|
||||
onShowSizeChange: pageSizeChange,
|
||||
onChange: pageChange,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
getPageData();
|
||||
});
|
||||
|
||||
const getPageData = () => {
|
||||
getUsers().then((res) => {
|
||||
dataSource.value = res.data.items;
|
||||
pagination.total = res.data.total;
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>user</div>
|
||||
<div class="user">
|
||||
<!-- 查询 -->
|
||||
<div class="search">
|
||||
<a-form layout="inline">
|
||||
<a-form-item label="用户名">
|
||||
<a-input placeholder="用户名"> </a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="昵称">
|
||||
<a-input placeholder="昵称"> </a-input>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" v-per="'user:query'">
|
||||
<template #icon> <SearchOutlined /> </template>查询</a-button
|
||||
>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 列表 -->
|
||||
<div class="data">
|
||||
<a-card title="用户列表"
|
||||
><template #extra>
|
||||
<a-button type="primary" v-per="'user:create'">
|
||||
<template #icon><plus-outlined /></template>
|
||||
新增</a-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- 数据 -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="dataSource"
|
||||
:pagination="pagination"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag :color="record.status !== 9 ? 'green' : 'red'">
|
||||
{{ record.status !== 9 ? "正常" : "已删除" }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'created'">
|
||||
{{ formatTime(record.created) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'modified'">
|
||||
{{ formatTime(record.modified) }}
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<span>
|
||||
<a v-pre="'user:update'">修改</a>
|
||||
<a-divider type="vertical" />
|
||||
<template v-if="record.status !== 9">
|
||||
<a v-per="'user:delete'">删除</a>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.search {
|
||||
display: flex;
|
||||
/* justify-content: center; */
|
||||
align-content: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 24px;
|
||||
background: #fff;
|
||||
}
|
||||
.data {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user