更新
This commit is contained in:
parent
051ddca964
commit
331b233e60
@ -1,13 +1,26 @@
|
||||
import request from '@/config/axios'
|
||||
import { List } from 'echarts'
|
||||
|
||||
export const getMenuListApi = (params: any): Promise<IResponse> => {
|
||||
return request.get({ url: '/vadmin/auth/menus/', params })
|
||||
}
|
||||
|
||||
export const delMenuListApi = (params: any): Promise<IResponse> => {
|
||||
return request.delete({ url: '/vadmin/auth/menus/', params })
|
||||
export const delMenuListApi = (data: List): Promise<IResponse> => {
|
||||
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> => {
|
||||
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> => {
|
||||
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">
|
||||
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 { componentMap } from './componentMap'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
@ -150,9 +150,23 @@ export default defineComponent({
|
||||
const renderFormItemWrap = () => {
|
||||
// hidden属性表示隐藏,不做渲染
|
||||
const { schema = [], isCol } = unref(getProps)
|
||||
|
||||
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) => {
|
||||
// 如果是 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 (
|
||||
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
|
||||
{{
|
||||
|
@ -17,7 +17,8 @@ import {
|
||||
ElTransfer,
|
||||
ElAutocomplete,
|
||||
ElDivider,
|
||||
ElTreeSelect
|
||||
ElTreeSelect,
|
||||
ElTree
|
||||
} from 'element-plus'
|
||||
import { InputPassword } from '@/components/InputPassword'
|
||||
import { Editor } from '@/components/Editor'
|
||||
@ -44,7 +45,8 @@ const componentMap: Recordable<Component, ComponentName> = {
|
||||
RadioButton: ElRadioGroup,
|
||||
InputPassword: InputPassword,
|
||||
Editor: Editor,
|
||||
TreeSelect: ElTreeSelect
|
||||
TreeSelect: ElTreeSelect,
|
||||
Tree: ElTree
|
||||
}
|
||||
|
||||
export { componentMap }
|
||||
|
@ -16,7 +16,7 @@ export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
|
||||
const selectMap = ['Select', 'TimePicker', 'DatePicker', 'TimeSelect', 'TimeSelect']
|
||||
if (textMap.includes(schema?.component as string)) {
|
||||
return {
|
||||
placeholder: t('common.inputText')
|
||||
placeholder: `请输入${schema.label}`
|
||||
}
|
||||
}
|
||||
if (selectMap.includes(schema?.component as string)) {
|
||||
@ -34,7 +34,7 @@ export const setTextPlaceholder = (schema: FormSchema): PlaceholderMoel => {
|
||||
}
|
||||
} else {
|
||||
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') {
|
||||
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
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { Form, FormExpose } from '@/components/Form'
|
||||
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'
|
||||
|
||||
export const useForm = (props?: FormProps) => {
|
||||
@ -23,7 +23,7 @@ export const useForm = (props?: FormProps) => {
|
||||
await nextTick()
|
||||
const form = unref(formRef)
|
||||
if (!form) {
|
||||
console.error('Form 没有注册。请使用注册方式进行注册')
|
||||
console.error('Form 没有注册。请使用 register 方法进行注册')
|
||||
}
|
||||
return form
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import { TableData } from '@/api/table/types'
|
||||
import { useValidator } from '@/hooks/web/useValidator'
|
||||
import { getMenuTreeOptionsApi } from '@/api/vadmin/auth/menu'
|
||||
import { ElButton, ElInput } from 'element-plus'
|
||||
import { schema } from './menu.data'
|
||||
|
||||
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({
|
||||
title: [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">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
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 { useTable } from '@/hooks/web/useTable'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElButton, ElTag } from 'element-plus'
|
||||
import { h, ref, unref, reactive } from 'vue'
|
||||
import { ElButton } from 'element-plus'
|
||||
import { ref, unref } from 'vue'
|
||||
import { Dialog } from '@/components/Dialog'
|
||||
import Write from './components/Write.vue'
|
||||
import { columns } from './components/menu.data'
|
||||
|
||||
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>({
|
||||
getListApi: getMenuListApi,
|
||||
delListApi: delMenuListApi,
|
||||
@ -60,25 +31,31 @@ const { register, tableObject, methods } = useTable<TableData>({
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const actionType = ref('')
|
||||
const delLoading = ref(false)
|
||||
const actionType = ref('')
|
||||
|
||||
// 添加事件
|
||||
const AddAction = () => {
|
||||
dialogTitle.value = t('exampleDemo.add')
|
||||
tableObject.currentRow = null
|
||||
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
|
||||
const { delListApi, getSelections } = methods
|
||||
const selections = await getSelections()
|
||||
dialogVisible.value = true
|
||||
actionType.value = 'edit'
|
||||
}
|
||||
|
||||
// 删除事件
|
||||
const delData = async (row: any) => {
|
||||
tableObject.currentRow = row
|
||||
const { delListApi } = methods
|
||||
delLoading.value = true
|
||||
await delListApi(
|
||||
multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
|
||||
multiple
|
||||
).finally(() => {
|
||||
await delListApi([row.id], false).finally(() => {
|
||||
delLoading.value = false
|
||||
})
|
||||
}
|
||||
@ -92,8 +69,17 @@ const save = async () => {
|
||||
await write?.elFormRef?.validate(async (isValid) => {
|
||||
if (isValid) {
|
||||
loading.value = true
|
||||
const data = (await write?.getFormData()) as TableData
|
||||
console.log('a', data)
|
||||
const data = await write?.getFormData()
|
||||
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
|
||||
}
|
||||
})
|
||||
@ -117,11 +103,19 @@ getList()
|
||||
row-key="id"
|
||||
@register="register"
|
||||
>
|
||||
<template #action="{}">
|
||||
<ElButton type="primary" text>
|
||||
<template #title="{ row }">
|
||||
{{ 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') }}
|
||||
</ElButton>
|
||||
<ElButton type="danger" text>
|
||||
<ElButton type="danger" text size="small" @click="delData(row)">
|
||||
{{ t('exampleDemo.del') }}
|
||||
</ElButton>
|
||||
</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">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { Table } from '@/components/Table'
|
||||
import { getRoleListApi } from '@/api/vadmin/auth/role'
|
||||
import { TableData } from '@/api/table/types'
|
||||
import { reactive } from 'vue'
|
||||
import {
|
||||
getRoleListApi,
|
||||
addRoleListApi,
|
||||
delRoleListApi,
|
||||
putRoleListApi,
|
||||
getRoleApi
|
||||
} from '@/api/vadmin/auth/role'
|
||||
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 { ElButton } from 'element-plus'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const columns = reactive<TableColumn[]>([
|
||||
{
|
||||
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>({
|
||||
const { register, tableObject, methods } = useTable({
|
||||
getListApi: getRoleListApi,
|
||||
delListApi: delRoleListApi,
|
||||
response: {
|
||||
data: 'data',
|
||||
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
|
||||
|
||||
getList()
|
||||
@ -70,6 +100,10 @@ getList()
|
||||
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<div class="mb-10px">
|
||||
<ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
v-model:limit="tableObject.limit"
|
||||
v-model:page="tableObject.page"
|
||||
@ -81,17 +115,29 @@ getList()
|
||||
}"
|
||||
@register="register"
|
||||
>
|
||||
<template #action="{}">
|
||||
<ElButton type="primary" text>
|
||||
<template #action="{ row }">
|
||||
<ElButton type="primary" text size="small" @click="updateAction(row)">
|
||||
{{ t('exampleDemo.edit') }}
|
||||
</ElButton>
|
||||
<ElButton type="success" text>
|
||||
{{ t('exampleDemo.detail') }}
|
||||
</ElButton>
|
||||
<ElButton type="danger" text>
|
||||
<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"
|
||||
: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>
|
||||
</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">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { Table } from '@/components/Table'
|
||||
import { getTableListApi } from '@/api/table'
|
||||
import { TableData } from '@/api/table/types'
|
||||
import { reactive } from 'vue'
|
||||
import {
|
||||
getUserListApi,
|
||||
addUserListApi,
|
||||
delUserListApi,
|
||||
putUserListApi,
|
||||
getUserApi
|
||||
} from '@/api/vadmin/auth/user'
|
||||
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[]>([
|
||||
{
|
||||
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 { t } = useI18n()
|
||||
|
||||
const { register, tableObject, methods } = useTable<TableData>({
|
||||
getListApi: getTableListApi,
|
||||
const { register, tableObject, methods } = useTable({
|
||||
getListApi: getUserListApi,
|
||||
delListApi: delUserListApi,
|
||||
response: {
|
||||
list: 'list',
|
||||
total: 'total'
|
||||
data: 'data',
|
||||
count: 'count'
|
||||
},
|
||||
props: {
|
||||
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
|
||||
|
||||
getList()
|
||||
@ -52,15 +96,40 @@ getList()
|
||||
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<div class="mb-10px">
|
||||
<ElButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</ElButton>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
v-model:pageSize="tableObject.pageSize"
|
||||
v-model:currentPage="tableObject.currentPage"
|
||||
:data="tableObject.tableList"
|
||||
v-model:limit="tableObject.limit"
|
||||
v-model:page="tableObject.page"
|
||||
:data="tableObject.tableData"
|
||||
:loading="tableObject.loading"
|
||||
:selection="false"
|
||||
:pagination="{
|
||||
total: tableObject.total
|
||||
total: tableObject.count
|
||||
}"
|
||||
@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>
|
||||
</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'
|
||||
| 'Editor'
|
||||
| 'TreeSelect'
|
||||
| 'Tree'
|
||||
|
||||
declare type ColProps = {
|
||||
span?: number
|
||||
@ -86,6 +87,8 @@ declare global {
|
||||
value?: FormValueType
|
||||
// 是否隐藏
|
||||
hidden?: boolean
|
||||
// 是否显示
|
||||
ifshow?: (values: Recordable) => boolean
|
||||
// 远程加载下拉项
|
||||
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 : 增删改查
|
||||
from typing import List
|
||||
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from sqlalchemy import select
|
||||
from core.crud import DalBase
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
@ -42,6 +43,43 @@ class RoleDal(DalBase):
|
||||
def __init__(self, db: AsyncSession):
|
||||
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):
|
||||
role = await self.get_data(role_id, options=[self.model.menus])
|
||||
return [i.id for i in role.menus]
|
||||
@ -106,10 +144,12 @@ class MenuDal(DalBase):
|
||||
return self.generate_router_tree(menus, roots)
|
||||
|
||||
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)
|
||||
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:
|
||||
"""
|
||||
|
@ -18,8 +18,8 @@ class VadminRole(BaseModel):
|
||||
|
||||
name = 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="是否可用")
|
||||
index = Column(Integer, comment="排序")
|
||||
disabled = Column(Boolean, default=False, comment="是否禁用")
|
||||
order = Column(Integer, comment="排序")
|
||||
desc = Column(String(255), comment="描述")
|
||||
is_admin = Column(Boolean, comment="是否为超级角色", default=False)
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
from .user import UserOut, UserUpdate, User, UserIn, UserSimpleOut, ResetPwd
|
||||
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()
|
||||
|
||||
|
||||
# 采单树列表,选用权限展示使用
|
||||
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):
|
||||
children: List['TreeListOut'] = []
|
||||
|
||||
|
@ -17,8 +17,8 @@ from .menu import MenuSimpleOut
|
||||
|
||||
class Role(BaseModel):
|
||||
name: str
|
||||
is_active: bool = True
|
||||
index: Optional[int] = None
|
||||
disabled: bool = False
|
||||
order: Optional[int] = None
|
||||
desc: Optional[str] = None
|
||||
role_key: str
|
||||
is_admin: bool = False
|
||||
@ -41,14 +41,13 @@ class RoleOut(RoleSimpleOut):
|
||||
|
||||
|
||||
class RoleIn(Role):
|
||||
menus: Optional[List[int]] = []
|
||||
menu_ids: Optional[List[int]] = []
|
||||
|
||||
|
||||
class RoleSelectOut(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
is_active: bool
|
||||
role_key: str
|
||||
disabled: bool
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
from typing import Optional
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from utils.response import SuccessResponse
|
||||
from utils.response import SuccessResponse, ErrorResponse
|
||||
from . import schemas, crud, models
|
||||
from core.dependencies import paging, id_list, Params
|
||||
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))
|
||||
|
||||
|
||||
@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="获取角色信息")
|
||||
async def get_role(data_id: int, auth: Auth = Depends(login_auth)):
|
||||
model = models.VadminRole
|
||||
|
Loading…
x
Reference in New Issue
Block a user