更新
This commit is contained in:
parent
782ba23435
commit
c07ccdd3ef
@ -1,12 +1,8 @@
|
||||
import request from '@/config/axios'
|
||||
import type { UserLoginType, UserType } from './types'
|
||||
|
||||
interface RoleParams {
|
||||
roleName: string
|
||||
}
|
||||
|
||||
export const loginApi = (data: UserLoginType): Promise<IResponse> => {
|
||||
return request.post({ url: '/api/auth/login', data })
|
||||
return request.post({ url: '/auth/login/', data })
|
||||
}
|
||||
|
||||
export const loginOutApi = (): Promise<IResponse> => {
|
||||
@ -20,12 +16,6 @@ export const getUserListApi = ({ params }: AxiosConfig) => {
|
||||
}>({ url: '/user/list', params })
|
||||
}
|
||||
|
||||
export const getAdminRoleApi = (
|
||||
params: RoleParams
|
||||
): Promise<IResponse<AppCustomRouteRecordRaw[]>> => {
|
||||
return request.get({ url: '/role/list', params })
|
||||
}
|
||||
|
||||
export const getTestRoleApi = (params: RoleParams): Promise<IResponse<string[]>> => {
|
||||
return request.get({ url: '/role/list', params })
|
||||
export const getRoleMenusApi = (): Promise<IResponse<AppCustomRouteRecordRaw[]>> => {
|
||||
return request.get({ url: '/auth/getMenuList/' })
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ export type UserLoginType = {
|
||||
|
||||
export type UserType = {
|
||||
telephone: string
|
||||
password: string
|
||||
role: string
|
||||
roleId: string
|
||||
permissions: string | string[]
|
||||
nickname: string
|
||||
id: number
|
||||
avatar: string
|
||||
name: string
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ export interface AppState {
|
||||
}
|
||||
|
||||
export const appModules: AppState = {
|
||||
userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
|
||||
userInfo: 'UserInfo', // 登录信息保存的存储字段名称-建议每个项目换一个字段,避免与其他项目冲突,方便后面直接使用这个名称来获取对应的登录用户信息
|
||||
sizeMap: ['default', 'large', 'small'],
|
||||
mobile: false, // 是否是移动端
|
||||
title: import.meta.env.VITE_APP_TITLE, // 标题
|
||||
|
@ -14,22 +14,22 @@ const config: {
|
||||
*/
|
||||
base_url: {
|
||||
// 开发环境接口前缀
|
||||
base: '',
|
||||
base: '/api',
|
||||
|
||||
// 打包开发环境接口前缀
|
||||
dev: '',
|
||||
dev: '/api',
|
||||
|
||||
// 打包生产环境接口前缀
|
||||
pro: '',
|
||||
pro: '/api',
|
||||
|
||||
// 打包测试环境接口前缀
|
||||
test: ''
|
||||
test: '/api'
|
||||
},
|
||||
|
||||
/**
|
||||
* 接口成功返回状态码
|
||||
*/
|
||||
result_code: '200',
|
||||
result_code: 200,
|
||||
|
||||
/**
|
||||
* 接口请求超时时间
|
||||
|
@ -1,4 +1,5 @@
|
||||
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
|
||||
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
||||
|
||||
import qs from 'qs'
|
||||
|
||||
@ -10,18 +11,24 @@ const { result_code, base_url } = config
|
||||
|
||||
export const PATH_URL = base_url[import.meta.env.VITE_API_BASEPATH]
|
||||
|
||||
const authStore = useAuthStoreWithOut()
|
||||
|
||||
// 创建axios实例
|
||||
const service: AxiosInstance = axios.create({
|
||||
baseURL: PATH_URL, // api 的 base_url
|
||||
timeout: config.request_timeout // 请求超时时间
|
||||
timeout: config.request_timeout, // 请求超时时间
|
||||
headers: {} // 请求头信息
|
||||
})
|
||||
|
||||
// request拦截器
|
||||
service.interceptors.request.use(
|
||||
(config: AxiosRequestConfig) => {
|
||||
if (authStore.token !== '') {
|
||||
config.headers['Authorization'] = authStore.token // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
}
|
||||
if (
|
||||
config.method === 'post' &&
|
||||
(config.headers as any)['Content-Type'] === 'application/x-www-form-urlencoded'
|
||||
config.headers['Content-Type'] === 'application/x-www-form-urlencoded'
|
||||
) {
|
||||
config.data = qs.stringify(config.data)
|
||||
}
|
||||
|
@ -6,15 +6,13 @@ import { loginApi } from '@/api/login'
|
||||
export interface AuthState {
|
||||
token: string
|
||||
is_reset_password: boolean
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export const useAuthStore = defineStore({
|
||||
id: 'auth',
|
||||
state: (): AuthState => ({
|
||||
token: '',
|
||||
is_reset_password: false,
|
||||
user_id: 0
|
||||
is_reset_password: false
|
||||
}),
|
||||
persist: {
|
||||
// 开启持久化存储
|
||||
@ -24,9 +22,6 @@ export const useAuthStore = defineStore({
|
||||
getToken(): string {
|
||||
return this.token
|
||||
},
|
||||
getUserId(): number {
|
||||
return this.user_id
|
||||
},
|
||||
getIsResetPassword(): boolean {
|
||||
return this.is_reset_password
|
||||
}
|
||||
@ -35,13 +30,9 @@ export const useAuthStore = defineStore({
|
||||
async login(formData: UserLoginType) {
|
||||
const res = await loginApi(formData)
|
||||
if (res) {
|
||||
console.log('登录成功', res)
|
||||
} else {
|
||||
console.log('登录失败', res)
|
||||
this.token = `${res.data.token_type} ${res.data.access_token}`
|
||||
this.is_reset_password = res.data.is_reset_password
|
||||
}
|
||||
// this.token = token
|
||||
// this.is_reset_password = is_reset_password
|
||||
// this.user_id = user_id
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
@ -38,22 +38,10 @@ export const usePermissionStore = defineStore({
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
generateRoutes(
|
||||
type: 'admin' | 'test' | 'none',
|
||||
routers?: AppCustomRouteRecordRaw[] | string[]
|
||||
): Promise<unknown> {
|
||||
generateRoutes(routers?: AppCustomRouteRecordRaw[]): Promise<unknown> {
|
||||
return new Promise<void>((resolve) => {
|
||||
let routerMap: AppRouteRecordRaw[] = []
|
||||
if (type === 'admin') {
|
||||
// 模拟后端过滤菜单
|
||||
routerMap = generateRoutesFn2(routers as AppCustomRouteRecordRaw[])
|
||||
} else if (type === 'test') {
|
||||
// 模拟前端过滤菜单
|
||||
routerMap = generateRoutesFn1(cloneDeep(asyncRouterMap), routers as string[])
|
||||
} else {
|
||||
// 直接读取静态路由表
|
||||
routerMap = cloneDeep(asyncRouterMap)
|
||||
}
|
||||
routerMap = generateRoutesFn2(routers as AppCustomRouteRecordRaw[])
|
||||
// 动态路由,404一定要放到最后面
|
||||
this.addRouters = routerMap.concat([
|
||||
{
|
||||
|
@ -1,127 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import PanelGroup from './components/PanelGroup.vue'
|
||||
import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
|
||||
import { Echart } from '@/components/Echart'
|
||||
import { pieOptions, barOptions, lineOptions } from './echarts-data'
|
||||
import { ref, reactive } from 'vue'
|
||||
import {
|
||||
getUserAccessSourceApi,
|
||||
getWeeklyUserActivityApi,
|
||||
getMonthlySalesApi
|
||||
} from '@/api/dashboard/analysis'
|
||||
import { set } from 'lodash-es'
|
||||
import { EChartsOption } from 'echarts'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const loading = ref(true)
|
||||
|
||||
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
|
||||
|
||||
// 用户来源
|
||||
const getUserAccessSource = async () => {
|
||||
const res = await getUserAccessSourceApi().catch(() => {})
|
||||
if (res) {
|
||||
set(
|
||||
pieOptionsData,
|
||||
'legend.data',
|
||||
res.data.map((v) => t(v.name))
|
||||
)
|
||||
pieOptionsData!.series![0].data = res.data.map((v) => {
|
||||
return {
|
||||
name: t(v.name),
|
||||
value: v.value
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
|
||||
|
||||
// 周活跃量
|
||||
const getWeeklyUserActivity = async () => {
|
||||
const res = await getWeeklyUserActivityApi().catch(() => {})
|
||||
if (res) {
|
||||
set(
|
||||
barOptionsData,
|
||||
'xAxis.data',
|
||||
res.data.map((v) => t(v.name))
|
||||
)
|
||||
set(barOptionsData, 'series', [
|
||||
{
|
||||
name: t('analysis.activeQuantity'),
|
||||
data: res.data.map((v) => v.value),
|
||||
type: 'bar'
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
|
||||
|
||||
// 每月销售总额
|
||||
const getMonthlySales = async () => {
|
||||
const res = await getMonthlySalesApi().catch(() => {})
|
||||
if (res) {
|
||||
set(
|
||||
lineOptionsData,
|
||||
'xAxis.data',
|
||||
res.data.map((v) => t(v.name))
|
||||
)
|
||||
set(lineOptionsData, 'series', [
|
||||
{
|
||||
name: t('analysis.estimate'),
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
data: res.data.map((v) => v.estimate),
|
||||
animationDuration: 2800,
|
||||
animationEasing: 'cubicInOut'
|
||||
},
|
||||
{
|
||||
name: t('analysis.actual'),
|
||||
smooth: true,
|
||||
type: 'line',
|
||||
itemStyle: {},
|
||||
data: res.data.map((v) => v.actual),
|
||||
animationDuration: 2800,
|
||||
animationEasing: 'quadraticOut'
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
const getAllApi = async () => {
|
||||
await Promise.all([getUserAccessSource(), getWeeklyUserActivity(), getMonthlySales()])
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
getAllApi()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PanelGroup />
|
||||
<ElRow :gutter="20" justify="space-between">
|
||||
<ElCol :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
|
||||
<ElCard shadow="hover" class="mb-20px">
|
||||
<ElSkeleton :loading="loading" animated>
|
||||
<Echart :options="pieOptionsData" :height="300" />
|
||||
</ElSkeleton>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
<ElCol :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
|
||||
<ElCard shadow="hover" class="mb-20px">
|
||||
<ElSkeleton :loading="loading" animated>
|
||||
<Echart :options="barOptionsData" :height="300" />
|
||||
</ElSkeleton>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
<ElCol :span="24">
|
||||
<ElCard shadow="hover" class="mb-20px">
|
||||
<ElSkeleton :loading="loading" animated :rows="4">
|
||||
<Echart :options="lineOptionsData" :height="350" />
|
||||
</ElSkeleton>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</template>
|
@ -4,14 +4,14 @@ import { Form } from '@/components/Form'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElButton, ElCheckbox, ElLink } from 'element-plus'
|
||||
import { useForm } from '@/hooks/web/useForm'
|
||||
import { getTestRoleApi, getAdminRoleApi } from '@/api/login'
|
||||
import { getRoleMenusApi } from '@/api/login'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import { useAuthStoreWithOut } from '@/store/modules/auth'
|
||||
import { usePermissionStore } from '@/store/modules/permission'
|
||||
import { useRouter } from 'vue-router'
|
||||
import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
|
||||
import { UserType, UserLoginType } from '@/api/login/types'
|
||||
import { UserLoginType } from '@/api/login/types'
|
||||
import { useValidator } from '@/hooks/web/useValidator'
|
||||
|
||||
const { required } = useValidator()
|
||||
@ -57,7 +57,7 @@ const schema = reactive<FormSchema[]>([
|
||||
{
|
||||
field: 'password',
|
||||
label: t('login.password'),
|
||||
value: 'admin',
|
||||
value: '430559',
|
||||
component: 'InputPassword',
|
||||
colProps: {
|
||||
span: 24
|
||||
@ -132,18 +132,10 @@ const signIn = async () => {
|
||||
const res = await authStore.login(formData)
|
||||
|
||||
if (res) {
|
||||
wsCache.set(appStore.getUserInfo, res.data)
|
||||
// 存储用户信息
|
||||
wsCache.set(appStore.getUserInfo, res.data.user)
|
||||
// 是否使用动态路由
|
||||
if (appStore.getDynamicRouter) {
|
||||
getRole()
|
||||
} else {
|
||||
await permissionStore.generateRoutes('none').catch(() => {})
|
||||
permissionStore.getAddRouters.forEach((route) => {
|
||||
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||
})
|
||||
permissionStore.setIsAddRouters(true)
|
||||
push({ path: redirect.value || permissionStore.addRouters[0].path })
|
||||
}
|
||||
getMenu()
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
@ -152,26 +144,15 @@ const signIn = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 获取角色信息
|
||||
const getRole = async () => {
|
||||
const { getFormData } = methods
|
||||
const formData = await getFormData<UserType>()
|
||||
const params = {
|
||||
roleName: formData.telephone
|
||||
}
|
||||
// admin - 模拟后端过滤菜单
|
||||
// test - 模拟前端过滤菜单
|
||||
const res =
|
||||
formData.telephone === 'admin' ? await getAdminRoleApi(params) : await getTestRoleApi(params)
|
||||
// 获取用户菜单信息
|
||||
const getMenu = async () => {
|
||||
const res = await getRoleMenusApi()
|
||||
console.log('菜单信息', res)
|
||||
if (res) {
|
||||
const { wsCache } = useCache()
|
||||
const routers = res.data || []
|
||||
wsCache.set('roleRouters', routers)
|
||||
|
||||
formData.telephone === 'admin'
|
||||
? await permissionStore.generateRoutes('admin', routers).catch(() => {})
|
||||
: await permissionStore.generateRoutes('test', routers).catch(() => {})
|
||||
|
||||
await permissionStore.generateRoutes(routers).catch(() => {})
|
||||
permissionStore.getAddRouters.forEach((route) => {
|
||||
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||
})
|
||||
|
46
kinit-api/alembic/versions/2d8939b3a228_update.py
Normal file
46
kinit-api/alembic/versions/2d8939b3a228_update.py
Normal file
@ -0,0 +1,46 @@
|
||||
"""update
|
||||
|
||||
Revision ID: 2d8939b3a228
|
||||
Revises: ecb50546debd
|
||||
Create Date: 2022-09-22 16:34:00.663906
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '2d8939b3a228'
|
||||
down_revision = 'ecb50546debd'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('vadmin_auth_menu', sa.Column('name', sa.String(length=50), nullable=False, comment='名称'))
|
||||
op.add_column('vadmin_auth_menu', sa.Column('noCache', sa.Boolean(), nullable=True, comment='如果设置为true,则不会被 <keep-alive> 缓存(默认 false)'))
|
||||
op.add_column('vadmin_auth_menu', sa.Column('breadcrumb', sa.Boolean(), nullable=True, comment='如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)'))
|
||||
op.add_column('vadmin_auth_menu', sa.Column('affix', sa.Boolean(), nullable=True, comment='如果设置为true,则会一直固定在tag项中(默认 false)'))
|
||||
op.add_column('vadmin_auth_menu', sa.Column('noTagsView', sa.Boolean(), nullable=True, comment='如果设置为true,则不会出现在tag中(默认 false)'))
|
||||
op.add_column('vadmin_auth_menu', sa.Column('canTo', sa.Boolean(), nullable=True, comment='设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)'))
|
||||
op.drop_index('ix_vadmin_auth_menu_title', table_name='vadmin_auth_menu')
|
||||
op.create_index(op.f('ix_vadmin_auth_menu_name'), 'vadmin_auth_menu', ['name'], unique=False)
|
||||
op.drop_column('vadmin_auth_menu', 'title_zh')
|
||||
op.drop_column('vadmin_auth_menu', 'title')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('vadmin_auth_menu', sa.Column('title', mysql.VARCHAR(length=50), nullable=False, comment='名称'))
|
||||
op.add_column('vadmin_auth_menu', sa.Column('title_zh', mysql.VARCHAR(length=50), nullable=True, comment='中文名称'))
|
||||
op.drop_index(op.f('ix_vadmin_auth_menu_name'), table_name='vadmin_auth_menu')
|
||||
op.create_index('ix_vadmin_auth_menu_title', 'vadmin_auth_menu', ['title'], unique=False)
|
||||
op.drop_column('vadmin_auth_menu', 'canTo')
|
||||
op.drop_column('vadmin_auth_menu', 'noTagsView')
|
||||
op.drop_column('vadmin_auth_menu', 'affix')
|
||||
op.drop_column('vadmin_auth_menu', 'breadcrumb')
|
||||
op.drop_column('vadmin_auth_menu', 'noCache')
|
||||
op.drop_column('vadmin_auth_menu', 'name')
|
||||
# ### end Alembic commands ###
|
34
kinit-api/alembic/versions/d37b76a689c1_update.py
Normal file
34
kinit-api/alembic/versions/d37b76a689c1_update.py
Normal file
@ -0,0 +1,34 @@
|
||||
"""update
|
||||
|
||||
Revision ID: d37b76a689c1
|
||||
Revises: 2d8939b3a228
|
||||
Create Date: 2022-09-22 16:35:48.607099
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'd37b76a689c1'
|
||||
down_revision = '2d8939b3a228'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('vadmin_auth_menu', sa.Column('title', sa.String(length=50), nullable=False, comment='名称'))
|
||||
op.drop_index('ix_vadmin_auth_menu_name', table_name='vadmin_auth_menu')
|
||||
op.create_index(op.f('ix_vadmin_auth_menu_title'), 'vadmin_auth_menu', ['title'], unique=False)
|
||||
op.drop_column('vadmin_auth_menu', 'name')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('vadmin_auth_menu', sa.Column('name', mysql.VARCHAR(length=50), nullable=False, comment='名称'))
|
||||
op.drop_index(op.f('ix_vadmin_auth_menu_title'), table_name='vadmin_auth_menu')
|
||||
op.create_index('ix_vadmin_auth_menu_name', 'vadmin_auth_menu', ['name'], unique=False)
|
||||
op.drop_column('vadmin_auth_menu', 'title')
|
||||
# ### end Alembic commands ###
|
@ -71,18 +71,13 @@ class MenuDal(DalBase):
|
||||
async def get_routers(self, user: models.VadminUser):
|
||||
"""
|
||||
获取路由表
|
||||
export interface Menu {
|
||||
name: string; // 菜单名
|
||||
icon?: string; // 菜单图标,如果没有,则会尝试使用route.meta.icon
|
||||
path: string; // 菜单路径
|
||||
disabled?: boolean; // 是否禁用
|
||||
children?: Menu[]; // 子菜单
|
||||
tag: { // 菜单标签设置
|
||||
dot: boolean; // 为true则显示小圆点
|
||||
content: string'; // 内容
|
||||
type: 'error' | 'primary' | 'warn' | 'success'; // 类型
|
||||
};
|
||||
hideMenu?: boolean; // 是否隐藏菜单
|
||||
declare interface AppCustomRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> {
|
||||
name: string
|
||||
meta: RouteMeta
|
||||
component: string
|
||||
path: string
|
||||
redirect: string
|
||||
children?: AppCustomRouteRecordRaw[]
|
||||
}
|
||||
"""
|
||||
if any([i.is_admin for i in user.roles]):
|
||||
@ -94,6 +89,7 @@ class MenuDal(DalBase):
|
||||
for role in user.roles:
|
||||
role_obj = await RoleDal(self.db).get_data(role.id, options=[models.VadminRole.menus])
|
||||
for menu in role_obj.menus:
|
||||
# 该路由没有被禁用,并且菜单不是按钮
|
||||
if not menu.disabled and menu.menu_type != "2":
|
||||
menus.add(menu)
|
||||
roots = filter(lambda i: not i.parent_id, menus)
|
||||
@ -116,7 +112,7 @@ class MenuDal(DalBase):
|
||||
for root in nodes:
|
||||
router = schemas.RouterOut.from_orm(root)
|
||||
router.name = router.path.split("/")[-1].capitalize()
|
||||
router.meta = schemas.Meta(title=root.title, icon=root.icon)
|
||||
router.meta = schemas.Meta(title=root.title, icon=root.icon, hidden=root.hidden)
|
||||
if root.menu_type == "0":
|
||||
sons = filter(lambda i: i.parent_id == root.id, menus)
|
||||
router.children = self.generate_router_tree(menus, sons)
|
||||
|
@ -23,7 +23,6 @@ class VadminMenu(BaseModel):
|
||||
# button = "2"
|
||||
|
||||
title = Column(String(50), index=True, nullable=False, comment="名称")
|
||||
title_zh = Column(String(50), comment="中文名称") # 选择框时使用
|
||||
icon = Column(String(50), comment="菜单图标")
|
||||
redirect = Column(String(100), comment="重定向地址")
|
||||
component = Column(String(50), comment="前端组件地址")
|
||||
@ -34,5 +33,10 @@ class VadminMenu(BaseModel):
|
||||
menu_type = Column(String(8), comment="菜单类型")
|
||||
parent_id = Column(ForeignKey("vadmin_auth_menu.id", ondelete='CASCADE'), comment="父菜单")
|
||||
perms = Column(String(50), comment="权限标识", unique=False, nullable=True, index=True)
|
||||
noCache = Column(Boolean, comment="如果设置为true,则不会被 <keep-alive> 缓存(默认 false)", default=False)
|
||||
breadcrumb = Column(Boolean, comment="如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)", default=True)
|
||||
affix = Column(Boolean, comment="如果设置为true,则会一直固定在tag项中(默认 false)", default=False)
|
||||
noTagsView = Column(Boolean, comment="如果设置为true,则不会出现在tag中(默认 false)", default=False)
|
||||
canTo = Column(Boolean, comment="设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)", default=False)
|
||||
|
||||
roles = relationship("VadminRole", back_populates='menus', secondary=vadmin_role_menus)
|
||||
|
@ -40,6 +40,12 @@ class MenuSimpleOut(Menu):
|
||||
class Meta(BaseModel):
|
||||
title: str
|
||||
icon: Optional[str] = None
|
||||
hidden: bool = False
|
||||
noCache: Optional[bool] = True
|
||||
breadcrumb: Optional[bool] = True
|
||||
affix: Optional[bool] = False
|
||||
noTagsView: Optional[bool] = False
|
||||
canTo: Optional[bool] = False
|
||||
|
||||
|
||||
# 路由展示
|
||||
@ -48,10 +54,7 @@ class RouterOut(BaseModel):
|
||||
component: str
|
||||
path: str
|
||||
redirect: Optional[str] = None
|
||||
perms: Optional[str] = None
|
||||
meta: Optional[Meta] = None
|
||||
disabled: bool = False
|
||||
hidden: bool = Field(False, alias='hideMenu')
|
||||
children: List['RouterOut'] = []
|
||||
|
||||
class Config:
|
||||
|
@ -25,8 +25,7 @@ from utils.response import SuccessResponse, ErrorResponse
|
||||
from application import settings
|
||||
from .auth_util import authenticate_user, create_access_token
|
||||
from apps.vadmin.record.models import VadminLoginRecord
|
||||
from apps.vadmin.auth.crud import RoleDal, MenuDal
|
||||
from apps.vadmin.auth.models import VadminRole
|
||||
from apps.vadmin.auth.crud import MenuDal
|
||||
from .current import AdminAuth, full_admin
|
||||
|
||||
app = APIRouter()
|
||||
@ -53,7 +52,8 @@ async def login_for_access_token(request: Request, data: dict = Depends(authenti
|
||||
"telephone": user.telephone,
|
||||
"name": user.name,
|
||||
"nickname": user.nickname,
|
||||
"avatar": user.avatar
|
||||
"avatar": user.avatar,
|
||||
"roles": [{"name": i.name, "value": i.role_key} for i in user.roles]
|
||||
}
|
||||
}
|
||||
await VadminLoginRecord.create_login_record(telephone=user.telephone, status=data.get("status"), request=request,
|
||||
@ -61,19 +61,6 @@ async def login_for_access_token(request: Request, data: dict = Depends(authenti
|
||||
return SuccessResponse(result)
|
||||
|
||||
|
||||
@app.get("/getUserInfo/", summary="获取当前登录用户基本信息")
|
||||
async def get_user_info(auth: AdminAuth = Depends(full_admin)):
|
||||
result = {
|
||||
"id": auth.admin.id,
|
||||
"telephone": auth.admin.telephone,
|
||||
"name": auth.admin.name,
|
||||
"nickname": auth.admin.nickname,
|
||||
"avatar": auth.admin.avatar,
|
||||
"roles": [{"name": i.name, "value": i.role_key} for i in auth.admin.roles]
|
||||
}
|
||||
return SuccessResponse(result)
|
||||
|
||||
|
||||
@app.get("/getMenuList/", summary="获取当前用户菜单树")
|
||||
async def get_menu_list(auth: AdminAuth = Depends(full_admin)):
|
||||
datas = await MenuDal(auth.db).get_routers(auth.admin)
|
||||
|
Loading…
x
Reference in New Issue
Block a user