feat: 添加菜单管理页面
parent
2f49f3814c
commit
5f7e71ae90
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<a-dropdown position="br">
|
||||
<span class="inline-flex items-center cursor-pointer rounded hover:bg-gray-100 px-2 py-1.5">
|
||||
<a-avatar :size="20">
|
||||
<a-avatar :size="24">
|
||||
<img :src="userStore.avatar || 'https://github.com/juetan.png'" :alt="userStore.nickname" />
|
||||
</a-avatar>
|
||||
<span class="mx-2">
|
||||
|
|
@ -11,9 +11,14 @@
|
|||
</span>
|
||||
<template #content>
|
||||
<a-doption>
|
||||
<div class="w-[160px] leading-4 my-1">
|
||||
{{ userStore.nickname }}
|
||||
<div class="text-xs text-gray-500">@{{ userStore.username }}</div>
|
||||
<div class="w-[200px] flex items-center gap-2">
|
||||
<a-avatar :size="32">
|
||||
<img :src="userStore.avatar || 'https://github.com/juetan.png'" :alt="userStore.nickname" />
|
||||
</a-avatar>
|
||||
<div class="leading-4 my-2">
|
||||
{{ userStore.nickname }}
|
||||
<div class="text-xs text-gray-500">@{{ userStore.username }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-doption>
|
||||
<a-divider :margin="4"></a-divider>
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@
|
|||
<a-form-item label="个人描述">
|
||||
<a-textarea v-model="user.description" placeholder="请输入" class="!w-[432px] h-24"></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label="密码">
|
||||
<a-button>修改密码</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item label="性别">
|
||||
<a-radio-group v-model="user.gender" type="button">
|
||||
<a-radio :value="1">男</a-radio>
|
||||
|
|
@ -38,6 +35,7 @@
|
|||
<a-form-item label="出生日期">
|
||||
<a-date-picker v-model="user.birth"></a-date-picker>
|
||||
</a-form-item>
|
||||
<a-button type="primary">保存修改</a-button>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="5" title="消息推送">
|
||||
|
|
@ -63,6 +61,24 @@
|
|||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="8" title="账号密码">
|
||||
<template #title>
|
||||
<i class="icon-park-outline-lock"></i>
|
||||
账号密码
|
||||
</template>
|
||||
<a-form :model="user" layout="vertical">
|
||||
<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 label="确认新密码">
|
||||
<a-input placeholder="请再次输入新密码"></a-input>
|
||||
</a-form-item>
|
||||
<a-button type="primary">修改密码</a-button>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" title="主题偏好">
|
||||
<template #title>
|
||||
<i class="icon-park-outline-theme"></i>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
<BreadPage>
|
||||
<template #content>
|
||||
<div class="p-4">
|
||||
<a-alert :closable="true" class="mb-2">
|
||||
仅展示近 90 天内的数据,如需查看更多数据,请联系管理员。
|
||||
</a-alert>
|
||||
<a-alert :closable="true" class="mb-2"> 仅展示近 90 天内的数据,如需查看更多数据,请联系管理员。 </a-alert>
|
||||
<div class="bg-white p-4">
|
||||
<Table v-bind="table"></Table>
|
||||
</div>
|
||||
|
|
@ -17,7 +15,6 @@
|
|||
import { api } from "@/api";
|
||||
import { Table, useTable } from "@/components";
|
||||
import { dayjs } from "@/libs/dayjs";
|
||||
import { Tag } from "@arco-design/web-vue";
|
||||
|
||||
const table = useTable({
|
||||
data: async (model, paging) => {
|
||||
|
|
@ -35,9 +32,13 @@ const table = useTable({
|
|||
render: ({ record: { status, description } }) => {
|
||||
return (
|
||||
<span>
|
||||
<Tag color={status === null || status ? "green" : "red"} class="mr-2">
|
||||
{status === null || status ? "成功" : "失败"}
|
||||
</Tag>
|
||||
<span
|
||||
class={
|
||||
status === null || status
|
||||
? "text-base text-green-500 icon-park-outline-check-one mr-2"
|
||||
: "text-base text-red-500 icon-park-outline-close-one mr-2"
|
||||
}
|
||||
></span>
|
||||
{description}
|
||||
</span>
|
||||
);
|
||||
|
|
@ -62,7 +63,7 @@ const table = useTable({
|
|||
{
|
||||
title: "登陆时间",
|
||||
dataIndex: "createdAt",
|
||||
width: 120,
|
||||
width: 160,
|
||||
render: ({ record }) => dayjs(record.createdAt).fromNow(),
|
||||
},
|
||||
],
|
||||
|
|
@ -71,10 +72,10 @@ const table = useTable({
|
|||
{
|
||||
field: "nickname",
|
||||
label: "登陆账号",
|
||||
type: "input",
|
||||
type: "search",
|
||||
required: false,
|
||||
nodeProps: {
|
||||
placeholder: "请输入登陆账号",
|
||||
// placeholder: "请输入登陆账号",
|
||||
},
|
||||
itemProps: {
|
||||
hideLabel: true,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,197 @@
|
|||
<template>
|
||||
<bread-page class="">
|
||||
<Table v-bind="table"></Table>
|
||||
</bread-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="tsx">
|
||||
import { api } from "@/api";
|
||||
import { Table, useTable } from "@/components";
|
||||
import { dayjs } from "@/libs/dayjs";
|
||||
import { menus } from "@/router";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
|
||||
const items = cloneDeep(menus) as any;
|
||||
for (const item of items) {
|
||||
item.checked = false;
|
||||
// if (item.icon) {
|
||||
// const icon = item.icon;
|
||||
// item.icon = () => <i class={icon}></i>;
|
||||
// }
|
||||
item.switcherIcon = () => null;
|
||||
if (item.children) {
|
||||
for (const child of item.children) {
|
||||
// if (child.icon) {
|
||||
// const icon = child.icon;
|
||||
// child.icon = () => <i class={icon}></i>;
|
||||
// }
|
||||
child.checked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const state = reactive({
|
||||
menus: items,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
const indeter = (items: any[]) => {
|
||||
if (!items) {
|
||||
return false;
|
||||
}
|
||||
const checked = items.filter((item) => item.checked);
|
||||
return checked.length > 0 && checked.length < items.length;
|
||||
};
|
||||
|
||||
const onItemChange = (item: any, menu: any) => {
|
||||
const checked = menu.children.filter((item: any) => item.checked);
|
||||
if (checked === 0) {
|
||||
menu.checked = false;
|
||||
} else if (checked === menu.children.length) {
|
||||
menu.checked = true;
|
||||
}
|
||||
};
|
||||
|
||||
const table = useTable({
|
||||
data: items,
|
||||
columns: [
|
||||
{
|
||||
title: "角色名称",
|
||||
dataIndex: "title",
|
||||
width: 180,
|
||||
render: ({ record }) => {
|
||||
return (
|
||||
<span>
|
||||
<i class={`${record.icon} mr-1 ml-1 vertical-[-2px]`}></i>
|
||||
{ record.title }
|
||||
</span>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "类型",
|
||||
dataIndex: "description",
|
||||
align: 'center',
|
||||
width: 80,
|
||||
render: () => <a-tag color="blue">菜单</a-tag>,
|
||||
},
|
||||
{
|
||||
title: "访问路径",
|
||||
dataIndex: "path",
|
||||
},
|
||||
{
|
||||
title: "启用",
|
||||
dataIndex: "createdAt",
|
||||
width: 80,
|
||||
align: 'center',
|
||||
render: ({ record }) => <a-switch size="small" checked-color="#3c9"></a-switch>,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
dataIndex: "createdAt",
|
||||
width: 200,
|
||||
render: ({ record }) => dayjs(record.createdAt).format(),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
type: "button",
|
||||
width: 184,
|
||||
buttons: [
|
||||
{
|
||||
type: "modify",
|
||||
text: "修改",
|
||||
},
|
||||
{
|
||||
text: "分配权限",
|
||||
onClick: ({ record }) => {
|
||||
console.log(record);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: "删除",
|
||||
type: "delete",
|
||||
onClick: ({ record }) => {
|
||||
return api.role.delRole(record.id);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
visible: false
|
||||
},
|
||||
search: {
|
||||
items: [
|
||||
{
|
||||
extend: "name",
|
||||
required: false,
|
||||
nodeProps: {
|
||||
placeholder: "请输入角色名称",
|
||||
},
|
||||
itemProps: {
|
||||
hideLabel: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
create: {
|
||||
title: "新建角色",
|
||||
modalProps: {
|
||||
width: 580,
|
||||
maskClosable: false,
|
||||
},
|
||||
formProps: {
|
||||
layout: "vertical",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
field: "name",
|
||||
label: "角色名称",
|
||||
type: "input",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
field: "slug",
|
||||
label: "角色标识",
|
||||
type: "input",
|
||||
},
|
||||
{
|
||||
field: "description",
|
||||
label: "个人描述",
|
||||
type: "textarea",
|
||||
},
|
||||
{
|
||||
field: "permissionIds",
|
||||
label: "关联权限",
|
||||
type: "select",
|
||||
options: () => api.permission.getPermissions(),
|
||||
nodeProps: {
|
||||
multiple: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
submit: ({ model }) => {
|
||||
return api.role.addRole(model);
|
||||
},
|
||||
},
|
||||
modify: {
|
||||
extend: true,
|
||||
title: "修改角色",
|
||||
submit: ({ model }) => {
|
||||
return api.role.updateRole(model.id, model);
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"meta": {
|
||||
"sort": 10201,
|
||||
"title": "菜单管理",
|
||||
"icon": "icon-park-outline-add-subtract"
|
||||
}
|
||||
}
|
||||
</route>
|
||||
|
|
@ -22,7 +22,7 @@ const table = useTable({
|
|||
return (
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<span>{record.name}</span>
|
||||
<span class="text-gray-400 text-xs truncate">{record.slug}</span>
|
||||
<span class="text-gray-400 text-xs truncate">@{record.slug}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
@ -112,7 +112,7 @@ const table = useTable({
|
|||
extend: true,
|
||||
title: "修改权限",
|
||||
submit: ({ model }) => {
|
||||
return api.permission.updatePermission(model.id, model);
|
||||
return api.permission.setPermission(model.id, model);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<BreadPage>
|
||||
<Table v-bind="table">
|
||||
<template #action>
|
||||
<a-button status="danger" type="outline" :disabled="true">
|
||||
<a-button status="danger" :disabled="true">
|
||||
<template #icon>
|
||||
<i class="icon-park-outline-delete"></i>
|
||||
</template>
|
||||
|
|
@ -24,6 +24,11 @@ const table = useTable({
|
|||
data: async (model, paging) => {
|
||||
return api.user.getUsers({ ...model, ...paging });
|
||||
},
|
||||
tableProps: {
|
||||
rowSelection: {
|
||||
showCheckedAll: true
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "用户昵称",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ body {
|
|||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
border-radius: 4px;
|
||||
&:not(:first-child) {
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
.arco-layout-sider {
|
||||
box-shadow: none;
|
||||
|
|
@ -39,6 +42,7 @@ body {
|
|||
margin-top: 8px;
|
||||
}
|
||||
[class^="icon-"] {
|
||||
font-size: 16px;
|
||||
vertical-align: -2px;
|
||||
}
|
||||
.arco-menu-item {
|
||||
|
|
|
|||
Loading…
Reference in New Issue