Skip to content

权限表单

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>