1
0
mirror of https://github.com/zclzone/vue-naive-admin.git synced 2025-06-17 12:29:01 +08:00
2024-09-06 14:46:07 +08:00

242 lines
7.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--------------------------------
- @Author: Ronnie Zhang
- @LastEditor: Ronnie Zhang
- @LastEditTime: 2024/04/01 15:52:31
- @Email: zclzone@outlook.com
- Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
--------------------------------->
<template>
<MeModal ref="modalRef">
<n-form
ref="modalFormRef"
label-placement="left"
require-mark-placement="left"
:label-width="100"
:model="modalForm"
>
<n-grid :cols="24" :x-gap="24">
<n-form-item-gi :span="12" label="所属菜单" path="parentId">
<n-tree-select
v-model:value="modalForm.parentId"
:options="menuOptions"
:disabled="parentIdDisabled"
label-field="name"
key-field="id"
placeholder="根菜单"
clearable
/>
</n-form-item-gi>
<n-form-item-gi :span="12" path="name" :rule="required">
<template #label>
<QuestionLabel label="名称" content="标题" />
</template>
<n-input v-model:value="modalForm.name" />
</n-form-item-gi>
<n-form-item-gi :span="12" path="code" :rule="required">
<template #label>
<QuestionLabel label="编码" content="如果是菜单则对应前端路由的name使用大驼峰" />
</template>
<n-input v-model:value="modalForm.code" />
</n-form-item-gi>
<n-form-item-gi
v-if="modalForm.type === 'MENU'"
:span="12"
path="path"
:rule="{
trigger: ['blur', 'change'],
type: 'string',
message: '必须是/、http、https开头',
validator(rule, value) {
if (value) {
return /\/|http|https/.test(value)
}
return true
},
}"
>
<template #label>
<QuestionLabel label="路由地址" content="父级菜单可不填" />
</template>
<n-input v-model:value="modalForm.path" />
</n-form-item-gi>
<n-form-item-gi v-if="modalForm.type === 'MENU'" :span="12" path="icon">
<template #label>
<QuestionLabel
label="菜单图标"
content="如material-symbols:help图标库地址: https://icones.js.org/collection/all"
/>
</template>
<n-select v-model:value="modalForm.icon" :options="iconOptions" clearable filterable />
</n-form-item-gi>
<n-form-item-gi v-if="modalForm.type === 'MENU'" :span="12" path="layout">
<template #label>
<QuestionLabel
label="layout"
content="对应layouts文件夹下的目录名, 为空则默认为 default"
/>
</template>
<n-select v-model:value="modalForm.layout" :options="layoutOptions" clearable />
</n-form-item-gi>
<n-form-item-gi v-if="modalForm.type === 'MENU'" :span="24" path="component">
<template #label>
<QuestionLabel
label="组件路径"
content="前端组件的路径,以 /src 开头,父级菜单可不填"
/>
</template>
<n-select
v-model:value="modalForm.component"
:options="componentOptions"
clearable
filterable
tag
/>
</n-form-item-gi>
<n-form-item-gi v-if="modalForm.type === 'MENU'" :span="12" path="show">
<template #label>
<QuestionLabel label="显示状态" content="控制是否在菜单栏显示,不影响路由注册" />
</template>
<n-switch v-model:value="modalForm.show">
<template #checked>
显示
</template>
<template #unchecked>
隐藏
</template>
</n-switch>
</n-form-item-gi>
<n-form-item-gi :span="12" path="enable">
<template #label>
<QuestionLabel
label="状态"
content="如果是菜单,禁用后将不添加到路由表,无法进入此页面"
/>
</template>
<n-switch v-model:value="modalForm.enable">
<template #checked>
启用
</template>
<template #unchecked>
禁用
</template>
</n-switch>
</n-form-item-gi>
<n-form-item-gi v-if="modalForm.type === 'MENU'" :span="12" path="keepAlive">
<template #label>
<QuestionLabel
label="KeepAlive"
content="设置keepAlive需将组件的name设置成当前菜单的code"
/>
</template>
<n-switch v-model:value="modalForm.keepAlive">
<template #checked>
</template>
<template #unchecked>
</template>
</n-switch>
</n-form-item-gi>
<n-form-item-gi
v-if="modalForm.type === 'MENU'"
:span="12"
label="排序"
path="order"
:rule="{
type: 'number',
required: true,
message: '此为必填项',
trigger: ['blur', 'change'],
}"
>
<n-input-number v-model:value="modalForm.order" />
</n-form-item-gi>
</n-grid>
</n-form>
</MeModal>
</template>
<script setup>
import { MeModal } from '@/components'
import { useForm, useModal } from '@/composables'
import icons from 'isme:icons'
import pagePathes from 'isme:page-pathes'
import api from '../api'
import QuestionLabel from './QuestionLabel.vue'
const props = defineProps({
menus: {
type: Array,
required: true,
},
})
const emit = defineEmits(['refresh'])
const menuOptions = computed(() => {
return [{ name: '根菜单', id: '', children: props.menus || [] }]
})
const componentOptions = pagePathes.map(path => ({ label: path, value: path }))
const iconOptions = icons.map(item => ({
label: () =>
h('span', { class: 'flex items-center' }, [h('i', { class: `${item} text-18 mr-8` }), item]),
value: item,
}))
const layoutOptions = [
{ label: '跟随系统', value: '' },
{ label: '简约-simple', value: 'simple' },
{ label: '通用-normal', value: 'normal' },
{ label: '全面-full', value: 'full' },
{ label: '空白-empty', value: 'empty' },
]
const required = {
required: true,
message: '此为必填项',
trigger: ['blur', 'change'],
}
const defaultForm = { enable: true, show: true, layout: '' }
const [modalFormRef, modalForm, validation] = useForm()
const [modalRef, okLoading] = useModal()
const modalAction = ref('')
const parentIdDisabled = ref(false)
function handleOpen(options = {}) {
const { action, row = {}, ...rest } = options
modalAction.value = action
modalForm.value = { ...defaultForm, ...row }
parentIdDisabled.value = !!row.parentId && row.type === 'BUTTON'
modalRef.value.open({ ...rest, onOk: onSave })
}
async function onSave() {
await validation()
okLoading.value = true
try {
let newFormData
if (!modalForm.value.parentId)
modalForm.value.parentId = null
if (modalAction.value === 'add') {
const res = await api.addPermission(modalForm.value)
newFormData = res.data
}
else if (modalAction.value === 'edit') {
await api.savePermission(modalForm.value.id, modalForm.value)
}
okLoading.value = false
$message.success('保存成功')
emit('refresh', modalAction.value === 'add' ? newFormData : modalForm.value)
}
catch (error) {
console.error(error)
okLoading.value = false
return false
}
}
defineExpose({
handleOpen,
})
</script>