Merge pull request #3 from mizhexiaoxiao/dev

Update: menu management
This commit is contained in:
mizhexiaoxiao 2023-09-08 16:10:18 +08:00 committed by GitHub
commit 4571db190f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 33 deletions

View File

@ -65,7 +65,6 @@ async def create_user(
async def update_user( async def update_user(
user_in: UserUpdate, user_in: UserUpdate,
) -> BaseResponse: ) -> BaseResponse:
print(user_in.dict())
user_controller = UserController() user_controller = UserController()
user = await user_controller.update(obj_in=user_in) user = await user_controller.update(obj_in=user_in)
await user_controller.update_roles(user, user_in.roles) await user_controller.update_roles(user, user_in.roles)

View File

@ -80,7 +80,7 @@ async def init_menus():
parent_menu = await Menu.create( parent_menu = await Menu.create(
menu_type=MenuType.CATALOG, menu_type=MenuType.CATALOG,
name="系统管理", name="系统管理",
path="/system", path="system",
order=1, order=1,
parent_id=0, parent_id=0,
icon="carbon:gui-management", icon="carbon:gui-management",

View File

@ -35,12 +35,11 @@ export async function addDynamicRoutes() {
router.addRoute(EMPTY_ROUTE) router.addRoute(EMPTY_ROUTE)
return return
} }
// 有token的情况 // 有token的情况
const userStore = useUserStore()
const permissionStore = usePermissionStore()
!userStore.userId && (await userStore.getUserInfo())
try { try {
const userStore = useUserStore()
const permissionStore = usePermissionStore()
!userStore.userId && (await userStore.getUserInfo())
const accessRoutes = await permissionStore.generateRoutes() const accessRoutes = await permissionStore.generateRoutes()
await permissionStore.getAccessApis() await permissionStore.getAccessApis()
accessRoutes.forEach((route) => { accessRoutes.forEach((route) => {
@ -49,6 +48,7 @@ export async function addDynamicRoutes() {
router.hasRoute(EMPTY_ROUTE.name) && router.removeRoute(EMPTY_ROUTE.name) router.hasRoute(EMPTY_ROUTE.name) && router.removeRoute(EMPTY_ROUTE.name)
router.addRoute(NOT_FOUND_ROUTE) router.addRoute(NOT_FOUND_ROUTE)
} catch (error) { } catch (error) {
console.error('error', error)
const userStore = useUserStore() const userStore = useUserStore()
await userStore.logout() await userStore.logout()
} }

View File

@ -8,7 +8,7 @@ import api from '@/api'
function buildRoutes(routes = []) { function buildRoutes(routes = []) {
return routes.map((e) => ({ return routes.map((e) => ({
name: e.name, name: e.name,
path: e.component !== 'Layout' ? '/' : e.path, // 处理目录是一级菜单的情况 path: e.component !== 'Layout' ? '/' : '/' + e.path, // 处理目录是一级菜单的情况
component: shallowRef(Layout), // ? 不使用 shallowRef 控制台会有 warning component: shallowRef(Layout), // ? 不使用 shallowRef 控制台会有 warning
isHidden: e.is_hidden, isHidden: e.is_hidden,
redirect: e.redirect, redirect: e.redirect,

View File

@ -54,7 +54,6 @@
<script setup> <script setup>
import { lStorage, setToken } from '@/utils' import { lStorage, setToken } from '@/utils'
import { useStorage } from '@vueuse/core'
import bgImg from '@/assets/images/login_bg.webp' import bgImg from '@/assets/images/login_bg.webp'
import api from '@/api' import api from '@/api'
import { addDynamicRoutes } from '@/router' import { addDynamicRoutes } from '@/router'
@ -79,7 +78,6 @@ function initLoginInfo() {
} }
} }
const isRemember = useStorage('isRemember', false)
const loading = ref(false) const loading = ref(false)
async function handleLogin() { async function handleLogin() {
const { username, password } = loginInfo.value const { username, password } = loginInfo.value
@ -93,14 +91,10 @@ async function handleLogin() {
const res = await api.login({ username, password: password.toString() }) const res = await api.login({ username, password: password.toString() })
$message.success('登录成功') $message.success('登录成功')
setToken(res.data.access_token) setToken(res.data.access_token)
if (isRemember.value) {
lStorage.set('loginInfo', { username, password })
} else {
lStorage.remove('loginInfo')
}
await addDynamicRoutes() await addDynamicRoutes()
if (query.redirect) { if (query.redirect) {
const path = query.redirect const path = query.redirect
console.log('path', { path, query })
Reflect.deleteProperty(query, 'redirect') Reflect.deleteProperty(query, 'redirect')
router.push({ path, query }) router.push({ path, query })
} else { } else {

View File

@ -7,9 +7,6 @@ import {
NInput, NInput,
NInputNumber, NInputNumber,
NPopconfirm, NPopconfirm,
NRadio,
NRadioGroup,
NSpace,
NSwitch, NSwitch,
NTreeSelect, NTreeSelect,
} from 'naive-ui' } from 'naive-ui'
@ -29,6 +26,7 @@ defineOptions({ name: '菜单管理' })
const $table = ref(null) const $table = ref(null)
const queryItems = ref({}) const queryItems = ref({})
const vPermission = resolveDirective('permission') const vPermission = resolveDirective('permission')
const menuDisabled = ref(false)
// //
const initForm = { const initForm = {
@ -133,6 +131,7 @@ const columns = [
initForm.parent_id = row.id initForm.parent_id = row.id
initForm.menu_type = 'menu' initForm.menu_type = 'menu'
showMenuType.value = false showMenuType.value = false
menuDisabled.value = false
handleAdd() handleAdd()
}, },
}, },
@ -189,7 +188,7 @@ const columns = [
}, },
}, },
] ]
// // keepalive
async function handleUpdateKeepalive(row) { async function handleUpdateKeepalive(row) {
if (!row.id) return if (!row.id) return
row.publishing = true row.publishing = true
@ -217,6 +216,7 @@ function handleClickAdd() {
initForm.order = 1 initForm.order = 1
initForm.keepalive = true initForm.keepalive = true
showMenuType.value = true showMenuType.value = true
menuDisabled.value = true
handleAdd() handleAdd()
} }
@ -233,7 +233,7 @@ async function getTreeSelect() {
<CommonPage show-footer title="菜单列表"> <CommonPage show-footer title="菜单列表">
<template #action> <template #action>
<NButton v-permission="'post/api/v1/menu/create'" type="primary" @click="handleClickAdd"> <NButton v-permission="'post/api/v1/menu/create'" type="primary" @click="handleClickAdd">
<TheIcon icon="material-symbols:add" :size="18" class="mr-5" />新建菜单 <TheIcon icon="material-symbols:add" :size="18" class="mr-5" />新建菜单
</NButton> </NButton>
</template> </template>
@ -245,7 +245,6 @@ async function getTreeSelect() {
:columns="columns" :columns="columns"
:get-data="api.getMenus" :get-data="api.getMenus"
:single-line="true" :single-line="true"
default-expand-all="true"
> >
</CrudTable> </CrudTable>
@ -264,14 +263,6 @@ async function getTreeSelect() {
:label-width="80" :label-width="80"
:model="modalForm" :model="modalForm"
> >
<NFormItem v-if="showMenuType" label="菜单类型" path="type">
<NRadioGroup v-model:value="modalForm.menu_type" name="radiogroup">
<NSpace>
<NRadio value="catalog"> 目录 </NRadio>
<NRadio value="menu"> 菜单 </NRadio>
</NSpace>
</NRadioGroup>
</NFormItem>
<NFormItem label="上级菜单" path="parent_id"> <NFormItem label="上级菜单" path="parent_id">
<NTreeSelect <NTreeSelect
v-model:value="modalForm.parent_id" v-model:value="modalForm.parent_id"
@ -279,6 +270,7 @@ async function getTreeSelect() {
label-field="name" label-field="name"
:options="menuOptions" :options="menuOptions"
default-expand-all="true" default-expand-all="true"
:disabled="menuDisabled"
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
@ -286,11 +278,11 @@ async function getTreeSelect() {
path="name" path="name"
:rule="{ :rule="{
required: true, required: true,
message: '请输入菜单名称', message: '请输入唯一菜单名称',
trigger: ['input', 'blur'], trigger: ['input', 'blur'],
}" }"
> >
<NInput v-model:value="modalForm.name" placeholder="请输入菜单名称" /> <NInput v-model:value="modalForm.name" placeholder="请输入唯一菜单名称" />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
label="访问路径" label="访问路径"
@ -298,19 +290,24 @@ async function getTreeSelect() {
:rule="{ :rule="{
required: true, required: true,
message: '请输入访问路径', message: '请输入访问路径',
trigger: ['input', 'blur'], trigger: ['blur'],
}" }"
> >
<NInput v-model:value="modalForm.path" placeholder="请输入访问路径" /> <NInput v-model:value="modalForm.path" placeholder="请输入访问路径" />
</NFormItem> </NFormItem>
<NFormItem v-if="modalForm.menu_type === 'menu'" label="组件路径" path="component"> <NFormItem v-if="modalForm.menu_type === 'menu'" label="组件路径" path="component">
<NInput v-model:value="modalForm.component" placeholder="请输入组件路径" /> <NInput
v-model:value="modalForm.component"
placeholder="请输入组件路径,例如:/system/user"
/>
</NFormItem> </NFormItem>
<NFormItem label="跳转路径" path="redirect"> <NFormItem label="跳转路径" path="redirect">
<NInput <NInput
v-model:value="modalForm.redirect" v-model:value="modalForm.redirect"
:disabled="modalForm.parent_id !== 0" :disabled="modalForm.parent_id !== 0"
placeholder="只有一级菜单可以设置跳转路径" :placeholder="
modalForm.parent_id !== 0 ? '只有一级菜单可以设置跳转路径' : '请输入跳转路径'
"
/> />
</NFormItem> </NFormItem>
<NFormItem label="菜单图标" path="icon"> <NFormItem label="菜单图标" path="icon">