更新
This commit is contained in:
parent
051ddca964
commit
331b233e60
@ -1,13 +1,26 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
import { List } from 'echarts'
|
||||||
|
|
||||||
export const getMenuListApi = (params: any): Promise<IResponse> => {
|
export const getMenuListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/menus/', params })
|
return request.get({ url: '/vadmin/auth/menus/', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const delMenuListApi = (params: any): Promise<IResponse> => {
|
export const delMenuListApi = (data: List): Promise<IResponse> => {
|
||||||
return request.delete({ url: '/vadmin/auth/menus/', params })
|
return request.delete({ url: '/vadmin/auth/menus/', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const addMenuListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/vadmin/auth/menus/', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const putMenuListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.put({ url: `/vadmin/auth/menus/${data.id}/`, data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMenuTreeOptionsApi = (): Promise<IResponse> => {
|
export const getMenuTreeOptionsApi = (): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/menus/tree/options/' })
|
return request.get({ url: '/vadmin/auth/menus/tree/options/' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getMenuRoleTreeOptionsApi = (): Promise<IResponse> => {
|
||||||
|
return request.get({ url: '/vadmin/auth/menus/role/tree/options/' })
|
||||||
|
}
|
||||||
|
@ -3,3 +3,23 @@ import request from '@/config/axios'
|
|||||||
export const getRoleListApi = (params: any): Promise<IResponse> => {
|
export const getRoleListApi = (params: any): Promise<IResponse> => {
|
||||||
return request.get({ url: '/vadmin/auth/roles/', params })
|
return request.get({ url: '/vadmin/auth/roles/', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addRoleListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/vadmin/auth/roles/', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const delRoleListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.delete({ url: '/vadmin/auth/roles/', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const putRoleListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.put({ url: `/vadmin/auth/roles/${data.id}/`, data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getRoleApi = (dataId: number): Promise<IResponse> => {
|
||||||
|
return request.get({ url: `/vadmin/auth/roles/${dataId}/` })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getRoleOptionsApi = (): Promise<IResponse> => {
|
||||||
|
return request.get({ url: `/vadmin/auth/roles/options/` })
|
||||||
|
}
|
||||||
|
21
kinit-admin/src/api/vadmin/auth/user.ts
Normal file
21
kinit-admin/src/api/vadmin/auth/user.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export const getUserListApi = (params: any): Promise<IResponse> => {
|
||||||
|
return request.get({ url: '/vadmin/auth/users/', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const addUserListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.post({ url: '/vadmin/auth/users/', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const delUserListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.delete({ url: '/vadmin/auth/users/', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const putUserListApi = (data: any): Promise<IResponse> => {
|
||||||
|
return request.put({ url: `/vadmin/auth/users/${data.id}/`, data })
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUserApi = (dataId: number): Promise<IResponse> => {
|
||||||
|
return request.get({ url: `/vadmin/auth/users/${dataId}/` })
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { PropType, defineComponent, ref, computed, unref, watch, onMounted, Ref, isRef } from 'vue'
|
import { PropType, defineComponent, ref, computed, unref, watch, onMounted } from 'vue'
|
||||||
import { ElForm, ElFormItem, ElRow, ElCol, ElTooltip } from 'element-plus'
|
import { ElForm, ElFormItem, ElRow, ElCol, ElTooltip } from 'element-plus'
|
||||||
import { componentMap } from './componentMap'
|
import { componentMap } from './componentMap'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
@ -150,9 +150,23 @@ export default defineComponent({
|
|||||||
const renderFormItemWrap = () => {
|
const renderFormItemWrap = () => {
|
||||||
// hidden属性表示隐藏,不做渲染
|
// hidden属性表示隐藏,不做渲染
|
||||||
const { schema = [], isCol } = unref(getProps)
|
const { schema = [], isCol } = unref(getProps)
|
||||||
|
|
||||||
return schema
|
return schema
|
||||||
.filter((v) => !v.hidden)
|
.filter((v) => {
|
||||||
|
if (v.hidden !== undefined) {
|
||||||
|
return !v.hidden
|
||||||
|
} else if (v.ifshow !== undefined) {
|
||||||
|
const show = v.ifshow(unref(formModel))
|
||||||
|
if (!show) {
|
||||||
|
if (v.value !== undefined) {
|
||||||
|
formModel.value[v.field] = v.value
|
||||||
|
} else {
|
||||||
|
formModel.value[v.field] = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return show
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
// 如果是 Divider 组件,需要自己占用一行
|
// 如果是 Divider 组件,需要自己占用一行
|
||||||
const isDivider = item.component === 'Divider'
|
const isDivider = item.component === 'Divider'
|
||||||
@ -207,14 +221,6 @@ export default defineComponent({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item?.componentProps?.placeholder === undefined) {
|
|
||||||
if (item.componentProps === undefined) {
|
|
||||||
item.componentProps = {}
|
|
||||||
}
|
|
||||||
if (item?.component === 'Input') {
|
|
||||||
item.componentProps.placeholder = `请输入${item.label}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
|
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
|
||||||
{{
|
{{
|
||||||
|
@ -17,7 +17,8 @@ import {
|
|||||||
ElTransfer,
|
ElTransfer,
|
||||||
ElAutocomplete,
|
ElAutocomplete,
|
||||||
ElDivider,
|
ElDivider,
|
||||||
ElTreeSelect
|
ElTreeSelect,
|
||||||
|
ElTree
|
||||||
} from 'element-plus'
|
} from 'element-plus'
|
||||||
import { InputPassword } from '@/components/InputPassword'
|
import { InputPassword } from '@/components/InputPassword'
|
||||||
import { Editor } from '@/components/Editor'
|
import { Editor } from '@/components/Editor'
|
||||||
@ -44,7 +45,8 @@ const componentMap: Recordable<Component, ComponentName> = {
|
|||||||
RadioButton: ElRadioGroup,
|
RadioButton: ElRadioGroup,
|
||||||
InputPassword: InputPassword,
|
InputPassword: InputPassword,
|
||||||
Editor: Editor,
|
Editor: Editor,
|
||||||
TreeSelect: ElTreeSelect
|
TreeSelect: ElTreeSelect,
|
||||||
|
Tree: ElTree
|
||||||
}
|
}
|
||||||
|
|
||||||
export { componentMap }
|
export { componentMap }
|
||||||
|
@ -16,7 +16,7 @@ export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
|
|||||||
const selectMap = ['Select', 'TimePicker', 'DatePicker', 'TimeSelect', 'TimeSelect']
|
const selectMap = ['Select', 'TimePicker', 'DatePicker', 'TimeSelect', 'TimeSelect']
|
||||||
if (textMap.includes(schema?.component as string)) {
|
if (textMap.includes(schema?.component as string)) {
|
||||||
return {
|
return {
|
||||||
placeholder: t('common.inputText')
|
placeholder: `请输入${schema.label}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (selectMap.includes(schema?.component as string)) {
|
if (selectMap.includes(schema?.component as string)) {
|
||||||
@ -34,7 +34,7 @@ export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
placeholder: t('common.selectText')
|
placeholder: `请选择${schema.label}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ export const initModel = (schema: FormSchema[], formModel: Recordable) => {
|
|||||||
} else if (v.component && v.component !== 'Divider') {
|
} else if (v.component && v.component !== 'Divider') {
|
||||||
const hasField = Reflect.has(model, v.field)
|
const hasField = Reflect.has(model, v.field)
|
||||||
// 如果先前已经有值存在,则不进行重新赋值,而是采用现有的值
|
// 如果先前已经有值存在,则不进行重新赋值,而是采用现有的值
|
||||||
model[v.field] = hasField ? model[v.field] : v.value !== void 0 ? v.value : ''
|
model[v.field] = hasField ? model[v.field] : v.value !== void 0 ? v.value : undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return model
|
return model
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { Form, FormExpose } from '@/components/Form'
|
import type { Form, FormExpose } from '@/components/Form'
|
||||||
import type { ElForm } from 'element-plus'
|
import type { ElForm } from 'element-plus'
|
||||||
import { ref, unref, nextTick, Ref } from 'vue'
|
import { ref, unref, nextTick } from 'vue'
|
||||||
import type { FormProps } from '@/components/Form/src/types'
|
import type { FormProps } from '@/components/Form/src/types'
|
||||||
|
|
||||||
export const useForm = (props?: FormProps) => {
|
export const useForm = (props?: FormProps) => {
|
||||||
@ -23,7 +23,7 @@ export const useForm = (props?: FormProps) => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
const form = unref(formRef)
|
const form = unref(formRef)
|
||||||
if (!form) {
|
if (!form) {
|
||||||
console.error('Form 没有注册。请使用注册方式进行注册')
|
console.error('Form 没有注册。请使用 register 方法进行注册')
|
||||||
}
|
}
|
||||||
return form
|
return form
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import { TableData } from '@/api/table/types'
|
|||||||
import { useValidator } from '@/hooks/web/useValidator'
|
import { useValidator } from '@/hooks/web/useValidator'
|
||||||
import { getMenuTreeOptionsApi } from '@/api/vadmin/auth/menu'
|
import { getMenuTreeOptionsApi } from '@/api/vadmin/auth/menu'
|
||||||
import { ElButton, ElInput } from 'element-plus'
|
import { ElButton, ElInput } from 'element-plus'
|
||||||
|
import { schema } from './menu.data'
|
||||||
|
|
||||||
const { required } = useValidator()
|
const { required } = useValidator()
|
||||||
|
|
||||||
@ -16,153 +17,6 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleRadioChange = (item: string) => {
|
|
||||||
console.log(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
const schema = reactive<FormSchema[]>([
|
|
||||||
{
|
|
||||||
field: 'parent_id',
|
|
||||||
label: '上级菜单',
|
|
||||||
colProps: {
|
|
||||||
span: 24
|
|
||||||
},
|
|
||||||
component: 'TreeSelect',
|
|
||||||
componentProps: {
|
|
||||||
style: {
|
|
||||||
width: '100%'
|
|
||||||
},
|
|
||||||
checkStrictly: true,
|
|
||||||
placeholder: '请选择上级菜单'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'menu_type',
|
|
||||||
label: '菜单类型',
|
|
||||||
colProps: {
|
|
||||||
span: 24
|
|
||||||
},
|
|
||||||
component: 'Radio',
|
|
||||||
componentProps: {
|
|
||||||
style: {
|
|
||||||
width: '100%'
|
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: '目录',
|
|
||||||
value: '0'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '菜单',
|
|
||||||
value: '1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '按钮',
|
|
||||||
value: '2'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
onChange: handleRadioChange
|
|
||||||
},
|
|
||||||
value: '0'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'icon',
|
|
||||||
label: '菜单图标',
|
|
||||||
colProps: {
|
|
||||||
span: 24
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'title',
|
|
||||||
label: '菜单名称',
|
|
||||||
component: 'Input',
|
|
||||||
colProps: {
|
|
||||||
span: 12
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'order',
|
|
||||||
label: '显示排序',
|
|
||||||
component: 'InputNumber',
|
|
||||||
colProps: {
|
|
||||||
span: 12
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'path',
|
|
||||||
label: '路由地址',
|
|
||||||
component: 'Input',
|
|
||||||
colProps: {
|
|
||||||
span: 12
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'component',
|
|
||||||
label: '组件路径',
|
|
||||||
component: 'Input',
|
|
||||||
colProps: {
|
|
||||||
span: 12
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'hidden',
|
|
||||||
label: '显示状态',
|
|
||||||
colProps: {
|
|
||||||
span: 12
|
|
||||||
},
|
|
||||||
component: 'Radio',
|
|
||||||
componentProps: {
|
|
||||||
style: {
|
|
||||||
width: '100%'
|
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: '显示',
|
|
||||||
value: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '隐藏',
|
|
||||||
value: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
value: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'disabled',
|
|
||||||
label: '菜单状态',
|
|
||||||
colProps: {
|
|
||||||
span: 12
|
|
||||||
},
|
|
||||||
component: 'Radio',
|
|
||||||
componentProps: {
|
|
||||||
style: {
|
|
||||||
width: '100%'
|
|
||||||
},
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: '正常',
|
|
||||||
value: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '停用',
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
value: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'perms',
|
|
||||||
label: '权限标识',
|
|
||||||
component: 'Input',
|
|
||||||
colProps: {
|
|
||||||
span: 24
|
|
||||||
},
|
|
||||||
hidden: true
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
title: [required()],
|
title: [required()],
|
||||||
disabled: [required()],
|
disabled: [required()],
|
||||||
|
199
kinit-admin/src/views/vadmin/auth/menu/components/menu.data.ts
Normal file
199
kinit-admin/src/views/vadmin/auth/menu/components/menu.data.ts
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
export const columns = reactive<TableColumn[]>([
|
||||||
|
{
|
||||||
|
field: 'title',
|
||||||
|
label: '菜单名称',
|
||||||
|
width: '200px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'icon',
|
||||||
|
label: '图标',
|
||||||
|
width: '120px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'order',
|
||||||
|
label: '排序',
|
||||||
|
width: '120px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'menu_type',
|
||||||
|
label: '菜单类型',
|
||||||
|
width: '120px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'perms',
|
||||||
|
label: '权限标识',
|
||||||
|
width: '150px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'path',
|
||||||
|
label: '路由地址'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'component',
|
||||||
|
label: '组件路径'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'hidden',
|
||||||
|
label: '显示状态',
|
||||||
|
width: '120px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'disabled',
|
||||||
|
label: '菜单状态',
|
||||||
|
width: '120px'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
width: '200px',
|
||||||
|
label: '操作'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
export const schema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'parent_id',
|
||||||
|
label: '上级菜单',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'TreeSelect',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
checkStrictly: true,
|
||||||
|
placeholder: '请选择上级菜单'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'menu_type',
|
||||||
|
label: '菜单类型',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '目录',
|
||||||
|
value: '0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '菜单',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '按钮',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: '0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'icon',
|
||||||
|
label: '菜单图标',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
ifshow: (values) => values.menu_type !== '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'title',
|
||||||
|
label: '菜单名称',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'order',
|
||||||
|
label: '显示排序',
|
||||||
|
component: 'InputNumber',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'path',
|
||||||
|
label: '路由地址',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
ifshow: (values) => values.menu_type !== '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'component',
|
||||||
|
label: '组件路径',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
ifshow: (values) => values.menu_type !== '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'hidden',
|
||||||
|
label: '显示状态',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '显示',
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '隐藏',
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: false,
|
||||||
|
ifshow: (values) => values.menu_type !== '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'disabled',
|
||||||
|
label: '菜单状态',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '正常',
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '停用',
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: false,
|
||||||
|
ifshow: (values) => values.menu_type !== '2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'perms',
|
||||||
|
label: '权限标识',
|
||||||
|
component: 'Input',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
ifshow: (values) => values.menu_type !== '0'
|
||||||
|
}
|
||||||
|
])
|
@ -1,52 +1,23 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ContentWrap } from '@/components/ContentWrap'
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
import { Table } from '@/components/Table'
|
import { Table } from '@/components/Table'
|
||||||
import { getMenuListApi, delMenuListApi } from '@/api/vadmin/auth/menu'
|
import {
|
||||||
|
getMenuListApi,
|
||||||
|
delMenuListApi,
|
||||||
|
addMenuListApi,
|
||||||
|
putMenuListApi
|
||||||
|
} from '@/api/vadmin/auth/menu'
|
||||||
import { TableData } from '@/api/table/types'
|
import { TableData } from '@/api/table/types'
|
||||||
import { useTable } from '@/hooks/web/useTable'
|
import { useTable } from '@/hooks/web/useTable'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { ElButton, ElTag } from 'element-plus'
|
import { ElButton } from 'element-plus'
|
||||||
import { h, ref, unref, reactive } from 'vue'
|
import { ref, unref } from 'vue'
|
||||||
import { Dialog } from '@/components/Dialog'
|
import { Dialog } from '@/components/Dialog'
|
||||||
import Write from './components/Write.vue'
|
import Write from './components/Write.vue'
|
||||||
|
import { columns } from './components/menu.data'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const columns = reactive<TableColumn[]>([
|
|
||||||
{
|
|
||||||
field: 'title',
|
|
||||||
label: '菜单名称'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'icon',
|
|
||||||
label: '图标'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'order',
|
|
||||||
label: '排序'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'menu_type',
|
|
||||||
label: '菜单类型'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'perms',
|
|
||||||
label: '权限标识'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'component',
|
|
||||||
label: '组件路径'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'action',
|
|
||||||
width: '260px',
|
|
||||||
label: t('tableDemo.action'),
|
|
||||||
form: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const { register, tableObject, methods } = useTable<TableData>({
|
const { register, tableObject, methods } = useTable<TableData>({
|
||||||
getListApi: getMenuListApi,
|
getListApi: getMenuListApi,
|
||||||
delListApi: delMenuListApi,
|
delListApi: delMenuListApi,
|
||||||
@ -60,25 +31,31 @@ const { register, tableObject, methods } = useTable<TableData>({
|
|||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const dialogTitle = ref('')
|
const dialogTitle = ref('')
|
||||||
const actionType = ref('')
|
|
||||||
const delLoading = ref(false)
|
const delLoading = ref(false)
|
||||||
|
const actionType = ref('')
|
||||||
|
|
||||||
|
// 添加事件
|
||||||
const AddAction = () => {
|
const AddAction = () => {
|
||||||
dialogTitle.value = t('exampleDemo.add')
|
dialogTitle.value = t('exampleDemo.add')
|
||||||
tableObject.currentRow = null
|
tableObject.currentRow = null
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
actionType.value = ''
|
actionType.value = 'add'
|
||||||
}
|
}
|
||||||
|
|
||||||
const delData = async (row: TableData | null, multiple: boolean) => {
|
// 编辑事件
|
||||||
|
const updateAction = (row: any) => {
|
||||||
|
dialogTitle.value = '编辑'
|
||||||
tableObject.currentRow = row
|
tableObject.currentRow = row
|
||||||
const { delListApi, getSelections } = methods
|
dialogVisible.value = true
|
||||||
const selections = await getSelections()
|
actionType.value = 'edit'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除事件
|
||||||
|
const delData = async (row: any) => {
|
||||||
|
tableObject.currentRow = row
|
||||||
|
const { delListApi } = methods
|
||||||
delLoading.value = true
|
delLoading.value = true
|
||||||
await delListApi(
|
await delListApi([row.id], false).finally(() => {
|
||||||
multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
|
|
||||||
multiple
|
|
||||||
).finally(() => {
|
|
||||||
delLoading.value = false
|
delLoading.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -92,8 +69,17 @@ const save = async () => {
|
|||||||
await write?.elFormRef?.validate(async (isValid) => {
|
await write?.elFormRef?.validate(async (isValid) => {
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const data = (await write?.getFormData()) as TableData
|
const data = await write?.getFormData()
|
||||||
console.log('a', data)
|
const res = ref({})
|
||||||
|
if (actionType.value === 'add') {
|
||||||
|
res.value = await addMenuListApi(data)
|
||||||
|
} else if (actionType.value === 'edit') {
|
||||||
|
res.value = await putMenuListApi(data)
|
||||||
|
}
|
||||||
|
if (res.value) {
|
||||||
|
dialogVisible.value = false
|
||||||
|
getList()
|
||||||
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -117,11 +103,19 @@ getList()
|
|||||||
row-key="id"
|
row-key="id"
|
||||||
@register="register"
|
@register="register"
|
||||||
>
|
>
|
||||||
<template #action="{}">
|
<template #title="{ row }">
|
||||||
<ElButton type="primary" text>
|
{{ t(row.title) }}
|
||||||
|
</template>
|
||||||
|
<template #icon="{ row }">
|
||||||
|
<div v-if="row.icon">
|
||||||
|
<Icon :icon="row.icon" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #action="{ row }">
|
||||||
|
<ElButton type="primary" text size="small" @click="updateAction(row)">
|
||||||
{{ t('exampleDemo.edit') }}
|
{{ t('exampleDemo.edit') }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<ElButton type="danger" text>
|
<ElButton type="danger" text size="small" @click="delData(row)">
|
||||||
{{ t('exampleDemo.del') }}
|
{{ t('exampleDemo.del') }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
</template>
|
</template>
|
||||||
|
94
kinit-admin/src/views/vadmin/auth/role/components/Write.vue
Normal file
94
kinit-admin/src/views/vadmin/auth/role/components/Write.vue
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Form } from '@/components/Form'
|
||||||
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
|
import { PropType, reactive, watch, ref } from 'vue'
|
||||||
|
import { useValidator } from '@/hooks/web/useValidator'
|
||||||
|
import { getMenuRoleTreeOptionsApi } from '@/api/vadmin/auth/menu'
|
||||||
|
import { schema } from './role.data'
|
||||||
|
import { ElTree } from 'element-plus'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
|
||||||
|
const { required } = useValidator()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
currentRow: {
|
||||||
|
type: Object as PropType<Nullable<any>>,
|
||||||
|
default: () => null
|
||||||
|
},
|
||||||
|
defaultCheckedKeys: {
|
||||||
|
type: Array as PropType<number[]>,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
name: [required()],
|
||||||
|
role_key: [required()],
|
||||||
|
order: [required()]
|
||||||
|
})
|
||||||
|
|
||||||
|
const { register, methods, elFormRef } = useForm({
|
||||||
|
schema: schema
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.currentRow,
|
||||||
|
(currentRow) => {
|
||||||
|
if (!currentRow) return
|
||||||
|
const { setValues } = methods
|
||||||
|
setValues(currentRow)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
children: 'children',
|
||||||
|
label: 'label'
|
||||||
|
}
|
||||||
|
let data = ref([])
|
||||||
|
|
||||||
|
const getMenuRoleTreeOptions = async () => {
|
||||||
|
const res = await getMenuRoleTreeOptionsApi()
|
||||||
|
if (res) {
|
||||||
|
data.value = res.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getMenuRoleTreeOptions()
|
||||||
|
|
||||||
|
const treeRef = ref<InstanceType<typeof ElTree>>()
|
||||||
|
|
||||||
|
const getTreeCheckedKeys = () => {
|
||||||
|
return treeRef.value!.getCheckedKeys(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
elFormRef,
|
||||||
|
getFormData: methods.getFormData,
|
||||||
|
getTreeCheckedKeys: getTreeCheckedKeys
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Form :rules="rules" @register="register">
|
||||||
|
<template #menu_ids>
|
||||||
|
<ElTree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="data"
|
||||||
|
show-checkbox
|
||||||
|
node-key="value"
|
||||||
|
:props="defaultProps"
|
||||||
|
:default-checked-keys="defaultCheckedKeys"
|
||||||
|
>
|
||||||
|
<template #default="{ node }">
|
||||||
|
<span>{{ t(node.label) }}</span>
|
||||||
|
</template>
|
||||||
|
</ElTree>
|
||||||
|
</template>
|
||||||
|
</Form>
|
||||||
|
</template>
|
127
kinit-admin/src/views/vadmin/auth/role/components/role.data.ts
Normal file
127
kinit-admin/src/views/vadmin/auth/role/components/role.data.ts
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
export const columns = reactive<TableColumn[]>([
|
||||||
|
{
|
||||||
|
field: 'id',
|
||||||
|
label: '角色编号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '角色名称'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'role_key',
|
||||||
|
label: '权限字符'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'order',
|
||||||
|
label: '显示顺序'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'disabled',
|
||||||
|
label: '角色状态'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'is_admin',
|
||||||
|
label: '最高权限'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'create_datetime',
|
||||||
|
label: '创建时间'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
width: '260px',
|
||||||
|
label: '操作'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
export const schema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '角色名称',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'role_key',
|
||||||
|
label: '权限字符',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'order',
|
||||||
|
label: '显示排序',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'InputNumber'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'disabled',
|
||||||
|
label: '角色状态',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '正常',
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '禁用',
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'is_admin',
|
||||||
|
label: '最高权限',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '使用',
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '不使用',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'desc',
|
||||||
|
label: '描述',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'menu_ids',
|
||||||
|
label: '菜单权限',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
@ -1,59 +1,26 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ContentWrap } from '@/components/ContentWrap'
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
import { Table } from '@/components/Table'
|
import { Table } from '@/components/Table'
|
||||||
import { getRoleListApi } from '@/api/vadmin/auth/role'
|
import {
|
||||||
import { TableData } from '@/api/table/types'
|
getRoleListApi,
|
||||||
import { reactive } from 'vue'
|
addRoleListApi,
|
||||||
|
delRoleListApi,
|
||||||
|
putRoleListApi,
|
||||||
|
getRoleApi
|
||||||
|
} from '@/api/vadmin/auth/role'
|
||||||
import { useTable } from '@/hooks/web/useTable'
|
import { useTable } from '@/hooks/web/useTable'
|
||||||
|
import { ElButton, ElMessage } from 'element-plus'
|
||||||
|
import { columns } from './components/role.data'
|
||||||
|
import { ref, unref } from 'vue'
|
||||||
|
import Write from './components/Write.vue'
|
||||||
|
import { Dialog } from '@/components/Dialog'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { ElButton } from 'element-plus'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const columns = reactive<TableColumn[]>([
|
const { register, tableObject, methods } = useTable({
|
||||||
{
|
|
||||||
field: 'id',
|
|
||||||
label: '角色编号'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'name',
|
|
||||||
label: '角色名称'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'role_key',
|
|
||||||
label: '权限字符'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'index',
|
|
||||||
label: '显示顺序'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'is_active',
|
|
||||||
label: '状态'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'is_admin',
|
|
||||||
label: '最高权限'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'create_datetime',
|
|
||||||
label: '创建时间'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'action',
|
|
||||||
width: '260px',
|
|
||||||
label: t('tableDemo.action'),
|
|
||||||
form: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
detail: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const { register, tableObject, methods } = useTable<TableData>({
|
|
||||||
getListApi: getRoleListApi,
|
getListApi: getRoleListApi,
|
||||||
|
delListApi: delRoleListApi,
|
||||||
response: {
|
response: {
|
||||||
data: 'data',
|
data: 'data',
|
||||||
count: 'count'
|
count: 'count'
|
||||||
@ -63,6 +30,69 @@ const { register, tableObject, methods } = useTable<TableData>({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const dialogTitle = ref('')
|
||||||
|
const actionType = ref('')
|
||||||
|
const loading = ref(false)
|
||||||
|
const defaultCheckedKeys = ref([])
|
||||||
|
|
||||||
|
// 添加事件
|
||||||
|
const AddAction = () => {
|
||||||
|
dialogTitle.value = t('exampleDemo.add')
|
||||||
|
tableObject.currentRow = null
|
||||||
|
dialogVisible.value = true
|
||||||
|
actionType.value = 'add'
|
||||||
|
defaultCheckedKeys.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑事件
|
||||||
|
const updateAction = async (row: any) => {
|
||||||
|
const res = await getRoleApi(row.id)
|
||||||
|
dialogTitle.value = '编辑'
|
||||||
|
tableObject.currentRow = res.data
|
||||||
|
defaultCheckedKeys.value = res.data.menus.map((item: any) => item.id)
|
||||||
|
dialogVisible.value = true
|
||||||
|
actionType.value = 'edit'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除事件
|
||||||
|
const delData = async (row: any) => {
|
||||||
|
tableObject.currentRow = row
|
||||||
|
const { delListApi } = methods
|
||||||
|
loading.value = true
|
||||||
|
await delListApi([row.id], false).finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const writeRef = ref<ComponentRef<typeof Write>>()
|
||||||
|
|
||||||
|
const save = async () => {
|
||||||
|
const write = unref(writeRef)
|
||||||
|
await write?.elFormRef?.validate(async (isValid) => {
|
||||||
|
if (isValid) {
|
||||||
|
loading.value = true
|
||||||
|
let data = await write?.getFormData()
|
||||||
|
if (!data) {
|
||||||
|
loading.value = false
|
||||||
|
return ElMessage.error('未获取到数据')
|
||||||
|
}
|
||||||
|
data.menu_ids = write?.getTreeCheckedKeys()
|
||||||
|
const res = ref({})
|
||||||
|
if (actionType.value === 'add') {
|
||||||
|
res.value = await addRoleListApi(data)
|
||||||
|
} else if (actionType.value === 'edit') {
|
||||||
|
res.value = await putRoleListApi(data)
|
||||||
|
}
|
||||||
|
if (res.value) {
|
||||||
|
dialogVisible.value = false
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const { getList } = methods
|
const { getList } = methods
|
||||||
|
|
||||||
getList()
|
getList()
|
||||||
@ -70,6 +100,10 @@ getList()
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
|
<div class="mb-10px">
|
||||||
|
<ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
v-model:limit="tableObject.limit"
|
v-model:limit="tableObject.limit"
|
||||||
v-model:page="tableObject.page"
|
v-model:page="tableObject.page"
|
||||||
@ -81,17 +115,29 @@ getList()
|
|||||||
}"
|
}"
|
||||||
@register="register"
|
@register="register"
|
||||||
>
|
>
|
||||||
<template #action="{}">
|
<template #action="{ row }">
|
||||||
<ElButton type="primary" text>
|
<ElButton type="primary" text size="small" @click="updateAction(row)">
|
||||||
{{ t('exampleDemo.edit') }}
|
{{ t('exampleDemo.edit') }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
<ElButton type="success" text>
|
<ElButton type="danger" text size="small" @click="delData(row)">
|
||||||
{{ t('exampleDemo.detail') }}
|
|
||||||
</ElButton>
|
|
||||||
<ElButton type="danger" text>
|
|
||||||
{{ t('exampleDemo.del') }}
|
{{ t('exampleDemo.del') }}
|
||||||
</ElButton>
|
</ElButton>
|
||||||
</template>
|
</template>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
||||||
|
<Dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
|
||||||
|
<Write
|
||||||
|
ref="writeRef"
|
||||||
|
:current-row="tableObject.currentRow"
|
||||||
|
:default-checked-keys="defaultCheckedKeys"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<ElButton type="primary" :loading="loading" @click="save">
|
||||||
|
{{ t('exampleDemo.save') }}
|
||||||
|
</ElButton>
|
||||||
|
<ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
66
kinit-admin/src/views/vadmin/auth/user/components/Write.vue
Normal file
66
kinit-admin/src/views/vadmin/auth/user/components/Write.vue
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Form } from '@/components/Form'
|
||||||
|
import { useForm } from '@/hooks/web/useForm'
|
||||||
|
import { PropType, reactive, watch } from 'vue'
|
||||||
|
import { useValidator } from '@/hooks/web/useValidator'
|
||||||
|
import { schema } from './user.data'
|
||||||
|
import { getRoleOptionsApi } from '@/api/vadmin/auth/role'
|
||||||
|
|
||||||
|
const { required } = useValidator()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
currentRow: {
|
||||||
|
type: Object as PropType<Nullable<any>>,
|
||||||
|
default: () => null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = reactive({
|
||||||
|
name: [required()],
|
||||||
|
role_key: [required()],
|
||||||
|
order: [required()]
|
||||||
|
})
|
||||||
|
|
||||||
|
const { register, methods, elFormRef } = useForm({
|
||||||
|
schema: schema
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.currentRow,
|
||||||
|
(currentRow) => {
|
||||||
|
if (!currentRow) return
|
||||||
|
const { setValues } = methods
|
||||||
|
setValues(currentRow)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const getRoleOptions = async () => {
|
||||||
|
const res = await getRoleOptionsApi()
|
||||||
|
console.log('111111', res)
|
||||||
|
if (res) {
|
||||||
|
const { setSchema } = methods
|
||||||
|
setSchema([
|
||||||
|
{
|
||||||
|
field: 'role_ids',
|
||||||
|
path: 'componentProps.options',
|
||||||
|
value: res.data
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRoleOptions()
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
elFormRef,
|
||||||
|
getFormData: methods.getFormData
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Form :rules="rules" @register="register" />
|
||||||
|
</template>
|
170
kinit-admin/src/views/vadmin/auth/user/components/user.data.ts
Normal file
170
kinit-admin/src/views/vadmin/auth/user/components/user.data.ts
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
|
export const columns = reactive<TableColumn[]>([
|
||||||
|
{
|
||||||
|
field: 'id',
|
||||||
|
label: '用户编号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '姓名'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'nickname',
|
||||||
|
label: '昵称'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'telephone',
|
||||||
|
label: '手机号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'gender',
|
||||||
|
label: '性别'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'is_active',
|
||||||
|
label: '是否可用'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'last_login',
|
||||||
|
label: '最近一次登录时间'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'create_datetime',
|
||||||
|
label: '创建时间'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
width: '260px',
|
||||||
|
label: '操作'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
export const schema = reactive<FormSchema[]>([
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
label: '用户名称',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'telephone',
|
||||||
|
label: '手机号码',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'nickname',
|
||||||
|
label: '用户昵称',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'Input'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'password',
|
||||||
|
label: '用户密码',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'InputPassword',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'gender',
|
||||||
|
label: '性别',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '男',
|
||||||
|
value: '0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '女',
|
||||||
|
value: '1'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: '0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'is_active',
|
||||||
|
label: '状态',
|
||||||
|
colProps: {
|
||||||
|
span: 12
|
||||||
|
},
|
||||||
|
component: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
label: '正常',
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '停用',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'role_ids',
|
||||||
|
label: '角色',
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
},
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
},
|
||||||
|
// optionsAlias: {
|
||||||
|
// labelField: 'name',
|
||||||
|
// valueField: 'id'
|
||||||
|
// },
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'Option1',
|
||||||
|
label: 'Option1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Option2',
|
||||||
|
label: 'Option2',
|
||||||
|
disabled: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Option3',
|
||||||
|
label: 'Option3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Option4',
|
||||||
|
label: 'Option4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Option5',
|
||||||
|
label: 'Option5'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
])
|
@ -1,50 +1,94 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ContentWrap } from '@/components/ContentWrap'
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
import { Table } from '@/components/Table'
|
import { Table } from '@/components/Table'
|
||||||
import { getTableListApi } from '@/api/table'
|
import {
|
||||||
import { TableData } from '@/api/table/types'
|
getUserListApi,
|
||||||
import { reactive } from 'vue'
|
addUserListApi,
|
||||||
|
delUserListApi,
|
||||||
|
putUserListApi,
|
||||||
|
getUserApi
|
||||||
|
} from '@/api/vadmin/auth/user'
|
||||||
import { useTable } from '@/hooks/web/useTable'
|
import { useTable } from '@/hooks/web/useTable'
|
||||||
|
import { columns } from './components/user.data'
|
||||||
|
import { ref, unref } from 'vue'
|
||||||
|
import Write from './components/Write.vue'
|
||||||
|
import { Dialog } from '@/components/Dialog'
|
||||||
|
import { ElButton, ElMessage } from 'element-plus'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
|
||||||
const columns = reactive<TableColumn[]>([
|
const { t } = useI18n()
|
||||||
{
|
|
||||||
field: 'index',
|
|
||||||
label: 'index',
|
|
||||||
type: 'index'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'title',
|
|
||||||
label: 'title'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'author',
|
|
||||||
label: 'author'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'display_time',
|
|
||||||
label: 'displayTime'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'pageviews',
|
|
||||||
label: 'pageviews'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'action',
|
|
||||||
label: 'action'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const { register, tableObject, methods } = useTable<TableData>({
|
const { register, tableObject, methods } = useTable({
|
||||||
getListApi: getTableListApi,
|
getListApi: getUserListApi,
|
||||||
|
delListApi: delUserListApi,
|
||||||
response: {
|
response: {
|
||||||
list: 'list',
|
data: 'data',
|
||||||
total: 'total'
|
count: 'count'
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
columns
|
columns
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const dialogTitle = ref('')
|
||||||
|
const actionType = ref('')
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 添加事件
|
||||||
|
const AddAction = () => {
|
||||||
|
dialogTitle.value = t('exampleDemo.add')
|
||||||
|
tableObject.currentRow = null
|
||||||
|
dialogVisible.value = true
|
||||||
|
actionType.value = 'add'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑事件
|
||||||
|
const updateAction = async (row: any) => {
|
||||||
|
const res = await getUserApi(row.id)
|
||||||
|
dialogTitle.value = '编辑'
|
||||||
|
tableObject.currentRow = res.data
|
||||||
|
dialogVisible.value = true
|
||||||
|
actionType.value = 'edit'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除事件
|
||||||
|
const delData = async (row: any) => {
|
||||||
|
tableObject.currentRow = row
|
||||||
|
const { delListApi } = methods
|
||||||
|
loading.value = true
|
||||||
|
await delListApi([row.id], false).finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const writeRef = ref<ComponentRef<typeof Write>>()
|
||||||
|
|
||||||
|
const save = async () => {
|
||||||
|
const write = unref(writeRef)
|
||||||
|
await write?.elFormRef?.validate(async (isValid) => {
|
||||||
|
if (isValid) {
|
||||||
|
loading.value = true
|
||||||
|
let data = await write?.getFormData()
|
||||||
|
if (!data) {
|
||||||
|
loading.value = false
|
||||||
|
return ElMessage.error('未获取到数据')
|
||||||
|
}
|
||||||
|
const res = ref({})
|
||||||
|
if (actionType.value === 'add') {
|
||||||
|
res.value = await addUserListApi(data)
|
||||||
|
} else if (actionType.value === 'edit') {
|
||||||
|
res.value = await putUserListApi(data)
|
||||||
|
}
|
||||||
|
if (res.value) {
|
||||||
|
dialogVisible.value = false
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const { getList } = methods
|
const { getList } = methods
|
||||||
|
|
||||||
getList()
|
getList()
|
||||||
@ -52,15 +96,40 @@ getList()
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
|
<div class="mb-10px">
|
||||||
|
<ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Table
|
<Table
|
||||||
v-model:pageSize="tableObject.pageSize"
|
v-model:limit="tableObject.limit"
|
||||||
v-model:currentPage="tableObject.currentPage"
|
v-model:page="tableObject.page"
|
||||||
:data="tableObject.tableList"
|
:data="tableObject.tableData"
|
||||||
:loading="tableObject.loading"
|
:loading="tableObject.loading"
|
||||||
|
:selection="false"
|
||||||
:pagination="{
|
:pagination="{
|
||||||
total: tableObject.total
|
total: tableObject.count
|
||||||
}"
|
}"
|
||||||
@register="register"
|
@register="register"
|
||||||
/>
|
>
|
||||||
|
<template #action="{ row }">
|
||||||
|
<ElButton type="primary" text size="small" @click="updateAction(row)">
|
||||||
|
{{ t('exampleDemo.edit') }}
|
||||||
|
</ElButton>
|
||||||
|
<ElButton type="danger" text size="small" @click="delData(row)">
|
||||||
|
{{ t('exampleDemo.del') }}
|
||||||
|
</ElButton>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
|
||||||
|
<Dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
|
||||||
|
<Write ref="writeRef" :current-row="tableObject.currentRow" />
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<ElButton type="primary" :loading="loading" @click="save">
|
||||||
|
{{ t('exampleDemo.save') }}
|
||||||
|
</ElButton>
|
||||||
|
<ElButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</ElButton>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
3
kinit-admin/types/componentType/form.d.ts
vendored
3
kinit-admin/types/componentType/form.d.ts
vendored
@ -24,6 +24,7 @@ declare global {
|
|||||||
| 'InputPassword'
|
| 'InputPassword'
|
||||||
| 'Editor'
|
| 'Editor'
|
||||||
| 'TreeSelect'
|
| 'TreeSelect'
|
||||||
|
| 'Tree'
|
||||||
|
|
||||||
declare type ColProps = {
|
declare type ColProps = {
|
||||||
span?: number
|
span?: number
|
||||||
@ -86,6 +87,8 @@ declare global {
|
|||||||
value?: FormValueType
|
value?: FormValueType
|
||||||
// 是否隐藏
|
// 是否隐藏
|
||||||
hidden?: boolean
|
hidden?: boolean
|
||||||
|
// 是否显示
|
||||||
|
ifshow?: (values: Recordable) => boolean
|
||||||
// 远程加载下拉项
|
// 远程加载下拉项
|
||||||
api?: <T = any>() => AxiosPromise<T>
|
api?: <T = any>() => AxiosPromise<T>
|
||||||
}
|
}
|
||||||
|
30
kinit-api/alembic/versions/5947e4ed42db_update.py
Normal file
30
kinit-api/alembic/versions/5947e4ed42db_update.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"""update
|
||||||
|
|
||||||
|
Revision ID: 5947e4ed42db
|
||||||
|
Revises: d37b76a689c1
|
||||||
|
Create Date: 2022-10-01 16:52:06.752039
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '5947e4ed42db'
|
||||||
|
down_revision = 'd37b76a689c1'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('vadmin_auth_role', sa.Column('order', sa.Integer(), nullable=True, comment='排序'))
|
||||||
|
op.drop_column('vadmin_auth_role', 'index')
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('vadmin_auth_role', sa.Column('index', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True, comment='排序'))
|
||||||
|
op.drop_column('vadmin_auth_role', 'order')
|
||||||
|
# ### end Alembic commands ###
|
30
kinit-api/alembic/versions/ab5fb033599e_update.py
Normal file
30
kinit-api/alembic/versions/ab5fb033599e_update.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"""update
|
||||||
|
|
||||||
|
Revision ID: ab5fb033599e
|
||||||
|
Revises: 5947e4ed42db
|
||||||
|
Create Date: 2022-10-02 22:40:45.967326
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'ab5fb033599e'
|
||||||
|
down_revision = '5947e4ed42db'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('vadmin_auth_role', sa.Column('disabled', sa.Boolean(), nullable=True, comment='是否禁用'))
|
||||||
|
op.drop_column('vadmin_auth_role', 'is_active')
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('vadmin_auth_role', sa.Column('is_active', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True, comment='是否可用'))
|
||||||
|
op.drop_column('vadmin_auth_role', 'disabled')
|
||||||
|
# ### end Alembic commands ###
|
@ -7,6 +7,7 @@
|
|||||||
# @desc : 增删改查
|
# @desc : 增删改查
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
from fastapi.encoders import jsonable_encoder
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
from core.crud import DalBase
|
from core.crud import DalBase
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
@ -42,6 +43,43 @@ class RoleDal(DalBase):
|
|||||||
def __init__(self, db: AsyncSession):
|
def __init__(self, db: AsyncSession):
|
||||||
super(RoleDal, self).__init__(db, models.VadminRole, schemas.RoleSimpleOut)
|
super(RoleDal, self).__init__(db, models.VadminRole, schemas.RoleSimpleOut)
|
||||||
|
|
||||||
|
async def create_data(self, data: schemas.RoleIn, return_obj: bool = False, options: list = None, schema=None):
|
||||||
|
"""创建数据"""
|
||||||
|
obj = self.model(**data.dict(exclude={'menu_ids'}))
|
||||||
|
for data_id in data.menu_ids:
|
||||||
|
obj.menus.append(await MenuDal(db=self.db).get_data(data_id=data_id))
|
||||||
|
self.db.add(obj)
|
||||||
|
await self.db.flush()
|
||||||
|
await self.db.refresh(obj)
|
||||||
|
if options:
|
||||||
|
obj = await self.get_data(obj.id, options=options)
|
||||||
|
if return_obj:
|
||||||
|
return obj
|
||||||
|
if schema:
|
||||||
|
return schema.from_orm(obj).dict()
|
||||||
|
return self.out_dict(await self.get_data(obj.id))
|
||||||
|
|
||||||
|
async def put_data(self, data_id: int, data: schemas.RoleIn, return_obj: bool = False, options: list = None,
|
||||||
|
schema=None):
|
||||||
|
"""更新单个数据"""
|
||||||
|
obj = await self.get_data(data_id, options=[self.model.menus])
|
||||||
|
obj_dict = jsonable_encoder(data)
|
||||||
|
for key, value in obj_dict.items():
|
||||||
|
if key == "menu_ids":
|
||||||
|
if obj.menus:
|
||||||
|
obj.menus.clear()
|
||||||
|
for data_id in value:
|
||||||
|
obj.menus.append(await MenuDal(db=self.db).get_data(data_id=data_id))
|
||||||
|
continue
|
||||||
|
setattr(obj, key, value)
|
||||||
|
await self.db.flush()
|
||||||
|
await self.db.refresh(obj)
|
||||||
|
if return_obj:
|
||||||
|
return obj
|
||||||
|
if schema:
|
||||||
|
return schema.from_orm(obj).dict()
|
||||||
|
return self.out_dict(obj)
|
||||||
|
|
||||||
async def get_role_menu_tree(self, role_id: int):
|
async def get_role_menu_tree(self, role_id: int):
|
||||||
role = await self.get_data(role_id, options=[self.model.menus])
|
role = await self.get_data(role_id, options=[self.model.menus])
|
||||||
return [i.id for i in role.menus]
|
return [i.id for i in role.menus]
|
||||||
@ -106,10 +144,12 @@ class MenuDal(DalBase):
|
|||||||
return self.generate_router_tree(menus, roots)
|
return self.generate_router_tree(menus, roots)
|
||||||
|
|
||||||
async def get_treeselect(self):
|
async def get_treeselect(self):
|
||||||
"""获取菜单树列表信息"""
|
"""获取菜单树列表,角色添加菜单权限时使用"""
|
||||||
sql = select(self.model)
|
sql = select(self.model).where(self.model.disabled == False, self.model.menu_type != "2")
|
||||||
queryset = await self.db.execute(sql)
|
queryset = await self.db.execute(sql)
|
||||||
return [schemas.TreeselectOut.from_orm(i).dict() for i in queryset.scalars().all()]
|
menus = queryset.scalars().all()
|
||||||
|
roots = filter(lambda i: not i.parent_id, menus)
|
||||||
|
return self.generate_tree_options(menus, roots)
|
||||||
|
|
||||||
def generate_router_tree(self, menus: List[models.VadminMenu], nodes: filter) -> list:
|
def generate_router_tree(self, menus: List[models.VadminMenu], nodes: filter) -> list:
|
||||||
"""
|
"""
|
||||||
|
@ -18,8 +18,8 @@ class VadminRole(BaseModel):
|
|||||||
|
|
||||||
name = Column(String(50), index=True, nullable=False, comment="名称")
|
name = Column(String(50), index=True, nullable=False, comment="名称")
|
||||||
role_key = Column(String(50), index=True, nullable=False, comment="权限字符")
|
role_key = Column(String(50), index=True, nullable=False, comment="权限字符")
|
||||||
is_active = Column(Boolean, default=True, comment="是否可用")
|
disabled = Column(Boolean, default=False, comment="是否禁用")
|
||||||
index = Column(Integer, comment="排序")
|
order = Column(Integer, comment="排序")
|
||||||
desc = Column(String(255), comment="描述")
|
desc = Column(String(255), comment="描述")
|
||||||
is_admin = Column(Boolean, comment="是否为超级角色", default=False)
|
is_admin = Column(Boolean, comment="是否为超级角色", default=False)
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from .user import UserOut, UserUpdate, User, UserIn, UserSimpleOut, ResetPwd
|
from .user import UserOut, UserUpdate, User, UserIn, UserSimpleOut, ResetPwd
|
||||||
from .role import Role, RoleOut, RoleIn, RoleSelectOut, RoleSimpleOut
|
from .role import Role, RoleOut, RoleIn, RoleSelectOut, RoleSimpleOut
|
||||||
from .menu import Menu, MenuSimpleOut, RouterOut, Meta, TreeselectOut, TreeListOut
|
from .menu import Menu, MenuSimpleOut, RouterOut, Meta, TreeListOut
|
||||||
|
@ -63,17 +63,6 @@ class RouterOut(BaseModel):
|
|||||||
RouterOut.update_forward_refs()
|
RouterOut.update_forward_refs()
|
||||||
|
|
||||||
|
|
||||||
# 采单树列表,选用权限展示使用
|
|
||||||
class TreeselectOut(BaseModel):
|
|
||||||
id: int
|
|
||||||
label: str = Field(alias='title')
|
|
||||||
order: Optional[int] = 1
|
|
||||||
parent_id: Optional[int] = None
|
|
||||||
|
|
||||||
class Config:
|
|
||||||
orm_mode = True
|
|
||||||
|
|
||||||
|
|
||||||
class TreeListOut(MenuSimpleOut):
|
class TreeListOut(MenuSimpleOut):
|
||||||
children: List['TreeListOut'] = []
|
children: List['TreeListOut'] = []
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ from .menu import MenuSimpleOut
|
|||||||
|
|
||||||
class Role(BaseModel):
|
class Role(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
is_active: bool = True
|
disabled: bool = False
|
||||||
index: Optional[int] = None
|
order: Optional[int] = None
|
||||||
desc: Optional[str] = None
|
desc: Optional[str] = None
|
||||||
role_key: str
|
role_key: str
|
||||||
is_admin: bool = False
|
is_admin: bool = False
|
||||||
@ -41,14 +41,13 @@ class RoleOut(RoleSimpleOut):
|
|||||||
|
|
||||||
|
|
||||||
class RoleIn(Role):
|
class RoleIn(Role):
|
||||||
menus: Optional[List[int]] = []
|
menu_ids: Optional[List[int]] = []
|
||||||
|
|
||||||
|
|
||||||
class RoleSelectOut(BaseModel):
|
class RoleSelectOut(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
is_active: bool
|
disabled: bool
|
||||||
role_key: str
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
orm_mode = True
|
orm_mode = True
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from fastapi import APIRouter, Depends, Query
|
from fastapi import APIRouter, Depends, Query
|
||||||
from utils.response import SuccessResponse
|
from utils.response import SuccessResponse, ErrorResponse
|
||||||
from . import schemas, crud, models
|
from . import schemas, crud, models
|
||||||
from core.dependencies import paging, id_list, Params
|
from core.dependencies import paging, id_list, Params
|
||||||
from apps.vadmin.auth.utils.current import login_auth, Auth
|
from apps.vadmin.auth.utils.current import login_auth, Auth
|
||||||
@ -69,6 +69,11 @@ async def put_role(data_id: int, data: schemas.RoleIn, auth: Auth = Depends(logi
|
|||||||
return SuccessResponse(await crud.RoleDal(auth.db).put_data(data_id, data))
|
return SuccessResponse(await crud.RoleDal(auth.db).put_data(data_id, data))
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/roles/options/", summary="获取角色选择项")
|
||||||
|
async def get_role_options(auth: Auth = Depends(login_auth)):
|
||||||
|
return SuccessResponse(await crud.RoleDal(auth.db).get_select_datas())
|
||||||
|
|
||||||
|
|
||||||
@app.get("/roles/{data_id}/", summary="获取角色信息")
|
@app.get("/roles/{data_id}/", summary="获取角色信息")
|
||||||
async def get_role(data_id: int, auth: Auth = Depends(login_auth)):
|
async def get_role(data_id: int, auth: Auth = Depends(login_auth)):
|
||||||
model = models.VadminRole
|
model = models.VadminRole
|
||||||
|
Loading…
x
Reference in New Issue
Block a user