主题
权限表单
INFO
在线案例权限 CURD
后端
php
namespace Modules\Common\Tables;
use Catch\Enums\Status;
use CatchForm\Components\Rules\Control;
use CatchForm\Form;
use CatchForm\Table\Table;
use Modules\Common\Repository\Options\Modules;
use Modules\Permissions\Enums\MenuType;
class Permission extends Dynamic
{
public function table()
{
return Table::make('permissions/permissions')->columns(function (Table $table){
$table->column('权限名称', 'permission_name');
$table->column('菜单路由', 'route');
$table->column('操作')->type('operate');
})->dialog(900)->rowKey();
}
protected function form()
{
return Form::make(function (Form $form){
$form->col( function (Form $form){
$form->radio('type', '菜单类型')->required()->asButton()->options(MenuType::class)
->defaultValue(1)
// 目录
->whenEqual(MenuType::Top->value(), function (Control $control){
$control->required(['permission_name', 'module', 'route']);
})
// 菜单操作
->whenEqual(MenuType::Menu->value(), function (Control $control){
$control->required(['permission_name', 'module', 'route', 'select_permission_mark', 'parent_id']);
})
// 按钮操作
->whenEqual(MenuType::Action->value(), function (Control $control){
$control->required(['permission_name', 'text_permission_mark', 'parent_id']);
})
->emitChange();
$form->text('permission_name', '菜单名称')->maxlength(30)->showWordLimit();
$form->select('module', '所属模块')->options((new Modules())->get())->emitChange();
$form->text('route', '路由Path')->maxlength(30)->showWordLimit()->required();
$form->text('redirect', 'Redirect')->maxlength(50)->showWordLimit();
$form->number('sort', '排序')->min(0)->max(999999)->defaultValue(1);
})->span12();
$form->col(function (Form $form){
$form->cascader('parent_id', '上级菜单')->optionsTo('options')->options(
\Modules\Permissions\Models\Permissions::query()
->whereIn('type', [
MenuType::Menu->value,
MenuType::Top->value
])->get(['id as value', 'permission_name as label', 'parent_id'])->toTree(id: 'value')
)->checkStrictly()->class('w-full');
$form->selectOptions('permission_mark', '权限标识')
->alias('select_permission_mark')
->api('controllers');
$form->text('permission_mark', '权限标识')->alias('text_permission_mark');
$form->iconSelect('icon', '选择icon')->class('w-full');
$form->selectOptions('component', '所属组件')->api('components');
$form->radio('hidden', 'Hidden')->options(Status::class)->defaultValue(Status::Enable->value());
$form->radio('keepalive', 'Keepalive')->options(Status::class)->defaultValue(Status::Enable->value());
})->span12();
$form->text('active_menu', '激活菜单')
->info('如果是访问内页的菜单路由,例如创建文章 create/post, 虽然它隶属于文章列表,但实际上并不会嵌套在文章列表路由里
而是单独的一个路由,并且是不显示在左侧菜单的。所以在访问它的时候,需要左侧菜单高亮,则需要设置该参数');
});
}
}
前端
table 页面
vue
<template>
<div v-loading="loading" class="min-h-96">
<catch-table :paginate="false" v-bind="table" v-if="!loading">
<template #dialog="row">
<Create :config="{ ...form, primary: row?.id }" />
</template>
</catch-table>
</div>
</template>
<script lang="ts" setup>
import Create from './create.vue'
import { useDymaic } from '@/composables/useDymaic'
const { table, form, loading } = useDymaic('dynamic/permission')
</script>
表单页面
vue
<template>
<!--<form-create v-model="formData" :rule="rule" v-model:api="formApi" :option="options" ref="form"> </form-create>-->
<catch-form ref="formRef" :config="config" :beforeSubmit="beforeSubmit" :afterSubmit="afterSubmit" v-model="formData" />
</template>
<script lang="ts" setup>
// @ts-nocheck
import http from '@/support/http'
import { before } from 'node:test'
import { onMounted, ref, beforeMount, watch, onUnmounted } from 'vue'
const props = defineProps({
config: Object
})
const formData = ref({})
const formRef = ref()
// 类型字段 change
const typeChange = (value: number) => {
const form = formRef.value.getForm()
// 监听类型值
watch(
() => formData.value.type,
(newValue) => {
if (newValue === 3) {
form.hidden(true, ['icon', 'module', 'component', 'route', 'hidden', 'redirect', 'sort', 'keepalive', 'select_permission_mark', 'active_menu'])
form.hidden(false, ['text_permission_mark', 'parent_id'])
} else if (newValue === 2) {
form.hidden(true, 'text_permission_mark')
form.hidden(false, ['icon', 'module', 'component', 'route', 'hidden', 'redirect', 'parent_id', 'sort', 'keepalive', 'select_permission_mark', 'active_menu'])
} else {
form.hidden(true, ['select_permission_mark', 'text_permission_mark', 'active_menu', 'parent_id', 'redirect'])
form.hidden(false, ['icon', 'module', 'component', 'route', 'hidden', 'sort', 'keepalive'])
}
},
{
deep: true
}
)
// 监听模块组件的 change 事件
watch(
() => formData.value.module,
(newValue) => {
if (!newValue) return
form.mergeRule('select_permission_mark', { props: { query: { module: newValue } } })
form.mergeRule('component', { props: { query: { module: newValue } } })
}
)
if (form.getValue('type') === 1) {
form.hidden(false, ['icon', 'module', 'component', 'route', 'hidden', 'sort', 'keepalive'])
form.hidden(true, ['redirect', 'parent_id', 'select_permission_mark', 'text_permission_mark', 'active_menu'])
}
}
// 提交前的钩子
const beforeSubmit = (formData) => {
if (typeof formData.parent_id !== 'number') {
formData.parent_id = formData.parent_id[0]
}
return formData
}
// 提交后的钩子
const afterSubmit = () => {
formRef.value.resetExceptFields('type')
formRef.value.setFieldValue('type', 1)
}
onMounted(() => {
// changeEvent()
typeChange()
})
</script>