Parcourir la source

迁移菜单配置与权限配置

jzy il y a 3 mois
Parent
commit
bd57602418

+ 45 - 0
src/api/menu/menu.ts

@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+import {managerApi} from '@/utils/api'
+export default {
+
+  //应用列表
+  getMenuTree: (data: any) => request.get(managerApi+'/menu/treeData', {
+    params:data
+  }),
+  // 查询菜单按键详细
+  getMenu: (data: any) => request.get(managerApi+'/menu/info',{
+    params:data
+  }),
+
+  // 新增菜单按键
+  addMenu: (data: any) => request.post(managerApi+'/menu/save' , data),
+
+  // 修改菜单按键
+  updateMenu: (data: any) => request.post(managerApi+'/menu/save', data),
+  // 修改菜单是否启用
+  updateMenushow: (data: any) => request.post(managerApi+'/menu/updateMenuShow', data),
+
+
+  //切换菜单验证开关
+  updateMenuVerification: (data: any) => request.post(managerApi+'/menu/updateMenuVerification', data),
+  
+
+  // 删除菜单按键
+  delMenu: (data: any) => request.get(managerApi+'/menu/delete',{
+    params:data
+  }),
+
+  //获取实体类可选字段
+  getColumnList: (permission: any) => request.get(managerApi+'/menu/getColumnList',{
+    params:{
+      permission:permission
+    }
+  }),
+
+  //获取实体类权限字段
+  getPermissionParam: (permission: any) => request.get(managerApi+'/menu/getPermissionParam',{
+    params:{
+      permission:permission
+    }
+  }),
+}

+ 30 - 0
src/api/menu/menuButton.ts

@@ -0,0 +1,30 @@
+import request from '@/utils/request'
+import { managerApi } from '@/utils/api'
+export default {
+  // 查询菜单按键列表
+  listMenuButton: (query: any) => request.get(managerApi + '/menuButton/data', {
+    params: query
+  }),
+
+  // 查询菜单按键详细
+  getMenuButton: (id: any) => request.get(managerApi + '/menuButton/info?id=' + id),
+
+  // 新增菜单按键
+  addMenuButton: (data: any) => request.post(managerApi + '/menuButton/save', data),
+
+  // 修改菜单按键
+  updateMenuButton: (data: any) => request.post(managerApi + '/menuButton/update', data),
+
+  // 删除菜单按键
+  delMenuButton: (data: any) => request.get(managerApi + '/menuButton/delete', {
+    params: data
+  }),
+
+   //查看方案列表
+   findCommonSolutionsList: (data: any) => request.get(managerApi + '/menuButton/findCommonSolutionsList', {
+    params: data
+  }),
+
+  //保存方案
+  saveByCommonSolutions: (data: any) => request.post(managerApi + '/menuButton/saveByCommonSolutions', data),
+}

+ 24 - 0
src/api/menu/menuColumn.ts

@@ -0,0 +1,24 @@
+import request from '@/utils/request'
+import { managerApi } from '@/utils/api'
+export default {
+  // 查询菜单列表字段权限配置列表
+  listMenuColumn: (query: any) => request.get(managerApi + '/menuColumn/data', {
+    params: query
+  }),
+
+  // 查询菜单列表字段权限配置详细
+  getMenuColumn: (data: any) => request.get(managerApi + '/menuColumn/info',{
+    params:data
+  }),
+
+  // 新增菜单列表字段权限配置
+  addMenuColumn: (data: any) => request.post(managerApi + '/menuColumn/save', data),
+
+  // 修改菜单列表字段权限配置
+  updateMenuColumn: (data: any) => request.post(managerApi + '/menuColumn/update', data),
+
+  // 删除菜单列表字段权限配置
+  delMenuColumn: (data: any) => request.get(managerApi + '/menuColumn/delete', {
+    params: data
+  }),
+}

+ 24 - 0
src/api/menu/menuForm.ts

@@ -0,0 +1,24 @@
+import request from '@/utils/request'
+import { managerApi } from '@/utils/api'
+export default {
+  // 查询菜单表单字段配置列表
+  listMenuForm: (query: any) => request.get(managerApi + '/menuForm/data', {
+    params: query
+  }),
+
+  // 查询菜单表单字段配置详细
+  getMenuForm: (data:any) => request.get(managerApi + '/menuForm/info',{
+    params:data
+  }),
+
+  // 新增菜单表单字段配置
+  addMenuForm: (data: any) => request.post(managerApi + '/menuForm/save', data),
+
+  // 修改菜单表单字段配置
+  updateMenuForm: (data: any) => request.post(managerApi + '/menuForm/update', data),
+
+  // 删除菜单表单字段配置
+  delMenuForm: (data: any) => request.get(managerApi + '/menuForm/delete', {
+    params: data
+  }),
+}

+ 40 - 0
src/api/menu/menuPermission.ts

@@ -0,0 +1,40 @@
+import request from '@/utils/request'
+import { managerApi } from '@/utils/api'
+export default {
+  // 查询数据权限方案列表
+  listMenuPermission: (query: any) => request.get(managerApi + '/menuPermission/data', {
+    params: query
+  }),
+
+  // 查询数据权限方案详细
+  getMenuPermission: (id: any) => request.get(managerApi + '/menuPermission/info?id=' + id),
+
+  // 新增数据权限方案
+  addMenuPermission: (data: any) => request.post(managerApi + '/menuPermission/save', data),
+
+  // 修改数据权限方案
+  updateMenuPermission: (data: any) => request.post(managerApi + '/menuPermission/update', data),
+
+  // 删除数据权限方案
+  delMenuPermission: (data: any) => request.get(managerApi + '/menuPermission/delete', {
+    params: data
+  }),
+
+
+  //查看方案列表
+  findCommonSolutionsList: (data: any) => request.get(managerApi + '/menuPermission/findCommonSolutionsList', {
+    params: data
+  }),
+
+  //保存方案
+  saveByCommonSolutions: (data: any) => request.post(managerApi + '/menuPermission/saveByCommonSolutions', data),
+  
+
+  //获取数据链接
+  getMenuPermissionData: (data: any) => request.get(managerApi + '/menuPermission/getMenuPermissionData', {
+    params: data
+  }),
+  //保存数据链接
+  saveMenuPermissionData: (data: any) => request.post(managerApi + '/menuPermission/saveMenuPermissionData', data),
+  
+}

+ 29 - 0
src/api/menu/menuPermissionCondition.ts

@@ -0,0 +1,29 @@
+import request from '@/utils/request'
+import { managerApi } from '@/utils/api'
+export default {
+  // 查询数据权限字段管理列表
+  listMenuPermissionCondition: (query: any) => request.get(managerApi+'/menuPermissionCondition/data', {
+    params:query
+  }),
+
+  // 查询数据权限字段管理列表
+  allListMenuPermissionCondition: (query: any) => request.get(managerApi+'/menuPermissionCondition/list', {
+    params:query
+  }),
+
+  // 查询数据权限字段管理详细
+  getMenuPermissionCondition: (id: any) => request.get(managerApi+'/menuPermissionCondition/info?id=' + id),
+
+  // 新增数据权限字段管理
+  addMenuPermissionCondition: (data: any) => request.post(managerApi+'/menuPermissionCondition/save' , data),
+
+  // 修改数据权限字段管理
+  updateMenuPermissionCondition: (data: any) => request.post(managerApi+'/menuPermissionCondition/update', data),
+
+  // 删除数据权限字段管理
+  delMenuPermissionCondition: (ids: any) => request.get(managerApi+'/menuPermissionCondition/delete',{
+    params:{
+        ids:ids
+    }
+  }),
+}

+ 10 - 0
src/utils/api.ts

@@ -0,0 +1,10 @@
+const basicApi = '/basicApi/v1/basic' // 基础路由
+const managerApi = '/managerApi/v1/manager' //
+const userApi = '/userApi/v1/user'
+const tenantApi = '/tenantApi/v1/tenant'
+const permissionApi = '/permissionApi/v1/permission'
+const ruleApi = '/ruleApi/v1/rule'
+const sysApi = '/admin'
+const fileUploadApi = 'http://10.100.33.10:31019/file/v1/upload'
+
+export { basicApi, managerApi, userApi, tenantApi, permissionApi, fileUploadApi, ruleApi,sysApi }

+ 287 - 364
src/views/system/Menu.vue

@@ -1,435 +1,358 @@
 <script lang="ts" setup>
-import PaneModel from '@/components/splitpanes/PaneModel.vue'
-import { ElTree } from 'element-plus'
 import type { BasicForm, ICRUD } from '@/types/form'
-import SelIcon from '@/components/SelIcon.vue'
+import MenuButton from './modules/menuButton.vue'
+import MenuList from './modules/menuList.vue'
+import MenuForm from './modules/menuForm.vue'
+import MenuPermission from './modules/menuPermission.vue'
+import api from '@/api/menu/menu'
 
-interface Tree {
-  id: number
-  label: string
-  children?: Tree[]
-  icon?: string
-}
-const config = {
-  size: 20,
-  lMinSize: 20
-}
-const configSmall = {
-  size: 50
-}
-const filterText = ref('')
-const treeRef = ref<InstanceType<typeof ElTree>>()
-const defaultProps = {
-  children: 'children',
-  label: 'label'
-}
-const data: Tree[] = [
-  {
-    id: 1,
-    label: '系统管理',
-    icon: 'Edit',
-    children: [
-      {
-        id: 3,
-        label: '用户管理',
-        icon: 'Edit'
-      },
-      {
-        id: 4,
-        label: '角色管理',
-        icon: 'Edit'
-      }
-    ]
+const activeName = ref<any>('0')
+const activeMenu = ref<any>('1')
+const classPath=ref('')
+const itemTableRef = ref<any>(null)
+const orgTreeData = ref([])
+
+const CRUD: ICRUD = {
+  create(data: any) {
+    data.category = activeMenu.value == '1' ? 'WEB' : 'APP'
+    data.parentId = data.parentId ? data.parentId : '0'
+    return api.addMenu(data)
+  },
+  update(data: any) {
+    data.category = activeMenu.value == '1' ? 'WEB' : 'APP'
+    data.parentId = data.parentId ? data.parentId : '0'
+    return api.updateMenu(data)
   },
-  {
-    id: 2,
-    label: '组织机构',
-    icon: 'Edit',
-    children: [
-      {
-        id: 5,
-        label: '机构管理',
-        icon: 'Edit'
+  getList(data: any) {
+    data.category = activeMenu.value == '1' ? 'WEB' : 'APP'
+    return api.getMenuTree(data).then((res: any) => {
+      orgTreeData.value = res.data
+      return {
+        list: res.data
       }
-    ]
+    })
+  },
+  delete(data: any) {
+    return api.delMenu({
+      id:data.id
+    })
+  },
+  getRecord(data: any) {
+    return api.getMenu({ id: data.id }).then(async (res:any) => {
+      res.data.parentId == '0'?res.data.parentId = '' : res.data.parentId = res.data.parentId
+      return res
+    })
   }
-]
-const dialogVisible = ref(false)
-
-watch(filterText, val => {
-  treeRef.value?.filter(val)
-})
-const filterNode = (value: string, data: any) => {
-  if (!value) return true
-  return data.label.includes(value)
-}
-const menuId = ref('')
-const handleNodeClick = (val: any) => {
-  menuId.value = val.id
 }
-const changeType = (val: number) => {
-  console.log(val)
-}
-const formConfig = reactive<BasicForm>({
-  span: 24,
-  props: {
-    labelPosition: 'right'
-  },
+
+const logtFormConfig = reactive<BasicForm>({
+  span: 12,
   formItems: [
     {
-      label: '显示姓名',
+      label: '父级',
       value: '',
-      name: 'name',
-      type: 'input',
-      rules: [{ required: true, message: '请输入显示姓名', trigger: 'blur' }]
+      name: 'parentId',
+      type: 'tree-select',
+      search: false,
+      props: {
+        'value-key': 'id',
+        data: orgTreeData,
+        'check-strictly':true,
+        props: {
+          children: 'children',
+          label: 'name'
+        }
+      }
     },
     {
-      label: '多语言编码',
+      label: '菜单名称',
       value: '',
-      name: 'loginName',
-      type: 'input'
+      name: 'name',
+      type: 'input',
+      rules: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
+      search: false
     },
     {
-      label: '上级菜单',
+      label: '菜单类型',
       value: '',
-      name: 'company',
-      type: 'select'
-    },
-    {
-      label: '类型',
-      value: 1,
       name: 'type',
       type: 'select',
+      rules: [{ required: true, message: '菜单类型不能为空', trigger: 'blur' }],
       options: [
-        { label: '目录', value: 1 },
-        { label: '菜单', value: 2 },
-        { label: '按钮', value: 3 },
-        { label: '路由', value: 4 }
-      ],
-      events: {
-        change: changeType
-      }
+        {
+          label: '目录',
+          value: '1'
+        },
+        {
+          label: ' 页面',
+          value: '2'
+        },
+        {
+          label: ' 外链',
+          value: '3'
+        },
+        
+      ]
     },
     {
-      label: '链接地址',
+      label: '路径',
       value: '',
-      name: 'loginName',
+      name: 'path',
       type: 'input',
-      placeholder: '请填写路由路径或者超链接'
-    },
-    {
-      label: '链接类型',
-      value: '',
-      name: 'company',
-      type: 'select',
-      options: [
-        { label: 'link', value: 1 },
-        { label: 'iframe', value: 2 }
-      ],
-      placeholder: '路由请留空,http链接选择iframe,新窗口打开选择link'
+      rules: [{ required: true, message: '路径不能为空', trigger: 'blur' }],
+      search: false
     },
     {
-      label: '菜单图标',
+      label: '页面地址',
       value: '',
-      name: 'remark',
+      name: 'component',
       type: 'input',
-      slots: [
-        {
-          name: 'append',
-          alias: 'append1'
-        }
-      ]
+      hidden:true,
+      rules: [{ required: true, message: '页面地址不能为空', trigger: 'blur' }],
+      search: false
     },
     {
-      label: '可见',
+      label: '目标',
       value: '',
-      name: 'vis',
-      type: 'radio-group',
+      name: 'target',
+      type: 'select',
+      hidden:true,
       options: [
         {
-          label: '1',
-          value: '显示'
+          label: 'mainFrame',
+          value: 'mainFrame'
         },
         {
-          label: '0',
-          value: '隐藏'
-        }
-      ]
-    },
-    {
-      label: '固定在标签栏',
-      value: '',
-      name: 'vis',
-      type: 'radio-group',
-      options: [
+          label: 'blank',
+          value: 'blank'
+        },
         {
-          label: '1',
-          value: ''
+          label: 'self',
+          value: 'self'
         },
         {
-          label: '0',
-          value: '否'
+          label: 'parent',
+          value: 'parent'
+        },
+        {
+          label: 'top',
+          value: 'top'
         }
-      ]
+      ],
+      search: false
     },
     {
-      label: '隐藏面包屑',
+      label: '图标',
       value: '',
-      name: 'vis',
-      type: 'radio-group',
-      options: [
-        {
-          label: '1',
-          value: '是'
-        },
-        {
-          label: '0',
-          value: '否'
-        }
-      ]
+      name: 'icon',
+      type: 'icon-picker',
+    },
+
+    {
+      label: '排序',
+      value: 1,
+      name: 'sort',
+      type: 'input-number',
+      props: {
+        min:1,
+        controlsPosition:"right"
+      },
+    },
+    {
+      label: '是否启用',
+      value: '0',
+      name: 'isShow',
+      type: 'switch',
+      props: {
+        'active-value': '1',
+        'inactive-value': '0'
+      }
+    },
+    {
+      label: '验证开关',
+      value: '0',
+      name: 'verification',
+      type: 'switch',
+      props: {
+        'active-value': '1',
+        'inactive-value': '0'
+      }
     },
+   
     {
-      label: '授权标识',
+      label: '权标识',
       value: '',
-      name: 'loginName',
+      name: 'permission',
       type: 'input',
-      placeholder: '多个用逗号隔开'
+      // rules: [{ required: true, message: '权限标识不能为空', trigger: 'blur' }],
+      search: false
     },
     {
-      label: '备注',
+      label: '类路径',
       value: '',
-      name: 'loginName',
+      name: 'classPath',
       type: 'input',
-      props: {
-        autosize: {
-          minRows: 2,
-          maxRows: 6
-        },
-        type: 'textarea'
-      }
+      search: false
+    },
+    {
+      label: '提示',
+      value: '',
+      name: 'tip',
+      type: 'input',
+      search: false
     }
   ]
 })
-const create = (data: any) => {
-  console.log(data)
-}
-const update = (data: any) => {
-  console.log(data)
-}
-const formData = reactive<any>({})
+watch(()=>itemTableRef.value?.formData.type,(newval)=>{
+  console.log(newval)
+if(newval==1){
+  logtFormConfig.formItems.forEach(item=>{
+      if(item.name=='target'){
+        item.hidden=true
+      }
+      if(item.name=='component'){
+        item.hidden=true
+      }
+    })
+}else if(newval==2){
+    logtFormConfig.formItems.forEach(item=>{
+      if(item.name=='component'){
+        item.hidden=false
+      }
+    })
+  }else if(newval==3){
+    logtFormConfig.formItems.forEach(item=>{
+      if(item.name=='target'){
+        item.hidden=false
+      }
+      if(item.name=='component'){
+        item.hidden=true
+      }
+    })
+  }
+})
+const dialogVisible = ref(false)
 
-const selIcon = () => {
+const menuId = ref<any>('')
+const menuConfig = (row: any) => {
+  menuId.value = row.id;
+  classPath.value=row.classPath
   dialogVisible.value = true
 }
-const setIcon = (val: string) => {
-  console.log(val)
-  dialogVisible.value = false
-  formData.remark = val
+
+const checkSwitch = (row: any) => {
+  api.updateMenushow({ id: row.id, isShow: row.isShow == null ? '1' : row.isShow }).then(res => {
+    itemTableRef.value.refresh()
+  })
 }
-const CRUD: ICRUD = {
-  create(data) {
-    return new Promise(resolve => console.log(data))
-  },
-  update(data) {
-    return new Promise(resolve => console.log(data))
-  },
-  getList() {
-    return new Promise(resolve => {
-      resolve({
-        list: [],
-        total: 2
-      })
-    })
-  },
-  delete(data) {
-    return new Promise(resolve => console.log(data))
-  },
-  deleteBatch(data) {
-    return new Promise(resolve => console.log(data))
-  }
+
+//切换验证开关
+const checkVerification = (row:any) =>{
+  api.updateMenuVerification({ id: row.id, verification: row.verification == null ? '1' : row.verification }).then(res => {
+    itemTableRef.value.refresh()
+  })
 }
-const logtFormConfig = reactive<BasicForm>({
-  span: 24,
-  formItems: [
-    {
-      label: '数据规则名称',
-      value: '',
-      name: 'loginName',
-      type: 'input'
-    },
-    {
-      label: '规则mapper方法',
-      value: '',
-      name: 'loginName',
-      type: 'input'
-    }
-  ]
-})
-const curRow = ref<any>(null)
-const handleRowClick = ({ row }: { row: any }) => {
-  console.log(row)
-  curRow.value = row
+
+const addchild = (row:any) => {
+  itemTableRef.value?.handleCreate()
+  nextTick(()=>{
+    itemTableRef.value.formData.parentId=row.id
+    console.log(itemTableRef.value)
+  })
 }
-const rowClassName = ({ row }: { row: any }) => {
-  if (row.id === curRow.value.id) {
-    return 'active'
-  }
+
+const menuBack = () =>{
+  dialogVisible.value = false
 }
 </script>
 
 <template>
-  <PaneModel :config="config">
-    <template #left>
-      <el-card class="left">
-        <el-container>
-          <el-header>
-            <el-input v-model="filterText" placeholder="输入关键字进行过滤" />
-          </el-header>
-          <el-main>
-            <el-tree
-              ref="treeRef"
-              class="filter-tree"
-              :data="data"
-              :props="defaultProps"
-              default-expand-all
-              :filter-node-method="filterNode"
-              show-checkbox
-              @node-click="handleNodeClick"
-            >
-              <template #default="{ node, data }">
-                <span class="custom-tree-node">
-                  <el-icon :size="18">
-                    <component :is="data.icon" />
-                  </el-icon>
-                  <span>{{ node.label }}</span>
-                </span>
-              </template>
-            </el-tree>
-          </el-main>
-          <el-footer>
-            <el-button icon="plus" type="primary" size="small"></el-button>
-            <el-button icon="delete" type="danger" size="small"></el-button>
-            <el-button icon="refresh" size="small"></el-button>
-          </el-footer>
-        </el-container>
-      </el-card>
-    </template>
-    <template #right>
-      <el-empty v-if="menuId == ''" description="请选择左侧菜单后操作" />
-      <PaneModel v-else :config="configSmall" class="form-scoll">
-        <template #left>
-          <el-card class="right">
-            <template #header>
-              <span>office管理</span>
-            </template>
-            <pro-form
-              class="form-wrap"
-              :formConfig="formConfig"
-              :formData="formData"
-              ref="proFormRef"
-              :update="update"
-              :create="create"
-            >
-              <template #append> testt </template>
-              <template #append1>
-                <el-button @click="selIcon">
-                  <el-icon class="el-icon--right"><MoreFilled /></el-icon>
-                </el-button>
-              </template>
-            </pro-form>
-            <div class="text-center">
-              <el-button type="primary">保存</el-button>
-            </div>
-          </el-card>
-        </template>
-        <template #right>
-          <pro-table
-            :crud="CRUD"
-            :toolbarConfig="{ custom: true }"
-            :formConfig="logtFormConfig"
-            :row-class-name="rowClassName"
-            @cell-click="handleRowClick"
-          >
-            <template #header>
-              <span class="card-header">数据权限规则</span>
-            </template>
-            <vxe-column field="description" title="数据规则名称"></vxe-column>
-            <vxe-column field="type" title="规则mapper方法"></vxe-column>
-          </pro-table>
-        </template>
-      </PaneModel>
+  <el-tabs v-model="activeMenu" class="demo-tabs">
+    <el-tab-pane label="WEB菜单" name="1"></el-tab-pane>
+    <!-- <el-tab-pane label="APP菜单" name="2"></el-tab-pane> -->
+  </el-tabs>
+
+  <pro-table
+    :crud="CRUD"
+    :tree-config="{rowField:'id',expandAll:true,reserve: true,}"
+    :row-config="{ keyField: 'id', isHover: true }"
+    ref="itemTableRef"
+    :tableConfig="{ operateWidth: 230, }"
+    :formConfig="logtFormConfig"
+    :selection="false"
+    height="630px"
+  >
+    <vxe-column field="name" title="菜单名称" tree-node></vxe-column>
+    <vxe-column field="type" title="菜单类型">
+      <template #default="{ row }">
+        <el-tag v-if="row.type == 1" type="success">目录</el-tag>
+        <el-tag v-if="row.type == 2" type="primary">页面</el-tag>
+        <el-tag v-if="row.type==3" type="warning">外链</el-tag>
+      </template>
+    </vxe-column>
+    <vxe-column field="sort" title="菜单排序"></vxe-column>
+    <vxe-column field="icon" title="菜单图标"></vxe-column>
+    <vxe-column field="path" title="菜单地址"></vxe-column>
+    <vxe-column field="target" title="菜单目标"></vxe-column>
+    <vxe-column field="permission" title="权限标识"></vxe-column>
+    <vxe-column field="isShow" title="启用">
+      <template #default="{ row }">
+          <el-switch v-model="row.isShow" :active-text="row.isShow==1 ? '已启用' : '未启用'"  @change="checkSwitch(row)" active-value="1" inactive-value="0" />
+      </template>
+    </vxe-column>
+    <vxe-column field="verification" title="验证开关">
+      <template #default="{ row }">
+        <div @click="checkVerification(row)">
+          <el-switch v-model="row.verification" :active-text="row.verification==1 ? '开' : '关'"  active-value="1" inactive-value="0" />
+        </div>
+      </template>
+    </vxe-column>
+    <template #operateAfter="{ row }">
+      <el-button type="primary" plain size="small" @click="menuConfig(row)" v-if="row.type==2">配置</el-button>
+      <el-button type="primary" plain size="small" @click="addchild(row)" v-if="row.type==1">新建子级</el-button>
     </template>
-  </PaneModel>
-  <SelIcon v-if="dialogVisible" :dialogVisible="dialogVisible" @closeIcon="setIcon" />
+  </pro-table>
+ 
+  <el-drawer title="菜单配置" v-model="dialogVisible" size="50%" @close="menuBack">
+    <el-tabs v-model="activeName" stretch v-if="dialogVisible">
+      <el-tab-pane label="按键配置" name="0">
+        <el-alert title="维护菜单页面内包含的按钮,按钮编号为: (模块:操作), 例如(menu:add) 代表菜单新增按钮" type="warning" :closable="false" />
+        <MenuButton :id="menuId" v-if="activeName == 0"></MenuButton>
+      </el-tab-pane>
+      <el-tab-pane label="列表字段配置" name="1">
+        <el-alert title="维护菜单对应列表页面要显示的列表字段,如不配置按菜单对应的列表默认字段全部展示" type="warning" :closable="false" />
+        <MenuList :id="menuId" v-if="activeName == 1" :classPath="classPath"></MenuList>
+      </el-tab-pane>
+      <el-tab-pane label="表单字段配置" name="2">
+        <el-alert title="维护菜单对应表单内显示的字段,如不配置按菜单对应的表单默认字段全部展示" type="warning" :closable="false" />
+        <MenuForm :id="menuId" v-if="activeName == 2" :classPath="classPath"></MenuForm>
+      </el-tab-pane>
+      <el-tab-pane label="数据权限配置" name="3">
+        <MenuPermission :id="menuId" v-if="activeName == 3" :classPath="classPath"></MenuPermission>
+      </el-tab-pane>
+    </el-tabs>
+  </el-drawer>
 </template>
 
 <style lang="scss" scoped>
-:deep(.splitpanes__splitter) {
-  background: transparent !important;
+.demo-tabs {
+  background-color: white;
+  padding: 10px 20px;
 }
-.el-container {
-  height: 100%;
+.title-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding:10px 20px;
+  background-color:white ;
 }
-.card-header {
-  padding-bottom: 14px;
-  border-bottom: 1px solid var(--el-card-border-color);
-  box-sizing: border-box;
-  margin-top: -2px;
-  margin-bottom: 16px;
-}
-.right {
-  height: 100%;
-  :deep(.el-card__body) {
-    height: 100%;
-  }
-  .form-wrap {
-    padding-right: 20px;
-  }
-}
-.el-empty {
-  height: 100%;
-  background-color: #fff;
-}
-.form-scoll {
-  :deep(.el-card__body) {
-    overflow: auto;
-  }
+.title-icon {
+  display: inline-block;
+  margin-right: 10px;
+  font-size: 14px;
+  cursor: pointer;
 }
-:deep(.splitpanes__pane) {
-  background-color: #fff;
-}
-.left {
-  height: 100%;
-  :deep(.el-tree-node__content) {
-    height: 36px;
-  }
-  .custom-tree-node {
-    display: flex;
-    align-items: center;
-    span {
-      margin-left: 5px;
-    }
-  }
-  .el-header {
-    border-bottom: 1px solid #e6e6e6;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    height: 53px;
-  }
-  :deep(.el-card__body) {
-    padding: 0;
-    height: 100%;
-  }
-  .el-main {
-    overflow: auto;
-    flex: 1;
-    flex-basis: 100%;
-  }
-  .el-footer {
-    border-top: 1px solid #e6e6e6;
-    display: flex;
-    align-items: center;
-  }
+.title-text {
+  font-size: 16px;
 }
 </style>

+ 189 - 0
src/views/system/modules/menuButton.vue

@@ -0,0 +1,189 @@
+<script lang="ts" setup>
+import type { BasicForm, ICRUD } from '@/types/form'
+
+import api from '@/api/menu/menuButton'
+
+const props = defineProps({
+    id: {
+        type: String,
+        default: ''
+    }
+})
+
+const itemTableRef = ref<any>(null)
+
+const CRUD: ICRUD = {
+    create(data: any) {
+        data.menuId = props.id
+        return api.addMenuButton(data)
+    },
+    update(data: any) {
+        return api.updateMenuButton(data)
+    },
+    getList(data: any) {
+        data.menuId = props.id
+        return api.listMenuButton(data).then((res: any) => {
+            return {
+                list: res.data.records,
+                total: res.data.total
+            }
+        })
+    },
+    delete(data: any) {
+        return api.delMenuButton({
+            ids: data.id
+        })
+    },
+    getRecord(data: any) {
+        return api.getMenuButton(data.id)
+    }
+}
+
+
+const logtFormConfig = reactive<BasicForm>({
+    span: 12,
+    formItems: [
+        {
+            span: 24,
+            label: '',
+            value: '',
+            name: '',
+            type: 'custom',
+            slots: [
+                {
+                    name: 'default',
+                    alias: 'infos'
+                }
+            ]
+        },
+        {
+            label: '按键名称',
+            value: '',
+            name: 'name',
+            type: 'input',
+            rules: [{ required: true, message: '请输入按键名称', trigger: 'blur', },],
+            search: true,
+
+            props: {
+                'label-width': '150px'
+            }
+        },
+        {
+            label: '权限标识',
+            value: '',
+            name: 'code',
+            type: 'input',
+            rules: [{ required: true, message: '请输入权限标识', trigger: 'blur', },],
+            search: true,
+
+        },
+        {
+            label: '是否显示',
+            value: '0',
+            name: 'enabled',
+            type: 'switch',
+            props: {
+                'active-value': '0',
+                'inactive-value': '1'
+            }
+        },
+        {
+            label: '菜单排序',
+            value: 1,
+            name: 'sort',
+            type: 'input-number',
+            props: {
+        min:1,
+        controlsPosition:"right"
+      },
+        },
+        {
+            label: '描述',
+            value: '',
+            name: 'remarks',
+            type: 'input',
+        },
+
+    ]
+})
+
+const checkSwitch = (row: any) => {
+    api.updateMenuButton({ id: row.id, enabled: row.enabled == '0' ? '1' : '0' }).then(res => {
+        itemTableRef.value.refresh()
+    })
+}
+
+const programmeList = ref<any>([])
+const queryList = () => {
+  api.findCommonSolutionsList({
+    sysData: 1
+  }).then((res:any) => {
+    programmeList.value = res.data
+  })
+}
+
+const setProgramme = (e: any) => {
+  api.saveByCommonSolutions({
+    menuId: props.id,
+    commonSolutionsId: e.id
+  }).then((res: any) => {
+    if (res.code == 200) {
+      itemTableRef.value.refresh()
+    }
+  })
+}
+
+const handleEdit = (row: any) => {
+  itemTableRef.value.handleUpdate(row)
+}
+
+</script>
+
+<template>
+    <div>
+        <pro-table :crud="CRUD" :tree-config="{}" ref="itemTableRef" height="70vh" :tableConfig="{ operateWidth: 230,showEdit: false, }"
+        :formConfig="logtFormConfig" :selection="false">
+        <template #infos>
+            <el-alert title="权限标识 前端页面中为按钮定义的权限标识,如:'sys:menu:del'" type="warning" :closable="false" />
+        </template>
+        <template #toolbar="toolbar">
+            <el-dropdown trigger="click">
+            <el-button type="primary" class="ml-3" @click="queryList">
+                快捷按钮权限<el-icon class="el-icon--right"><arrow-down /></el-icon>
+            </el-button>
+            <template #dropdown>
+                <el-dropdown-menu v-for="(item, index) in programmeList">
+                <el-dropdown-item @click="setProgramme(item)">
+                    {{ item.name }}
+                </el-dropdown-item>
+                </el-dropdown-menu>
+            </template>
+            </el-dropdown>
+        </template>
+        <vxe-column field="name" title="按键名称" tree-node></vxe-column>
+        <vxe-column field="code" title="按键编号"></vxe-column>
+        <vxe-column field="enabled" title="是否启用">
+            <template #default="{ row }">
+                <div @click="checkSwitch(row)">
+                    <el-switch :model-value="row.enabled" :active-text="row.enabled=='0' ? '已启用' : '未启用'" active-value="0" inactive-value="1" />
+                </div>
+            </template>
+        </vxe-column>
+        <vxe-column field="sort" title="排序"></vxe-column>
+        <vxe-column field="remarks" title="描述"></vxe-column>
+        <template #operateAfter="{ row }">
+            <el-button type="primary" plain size="small" v-if="row.source == 0" @click="handleEdit(row)"> 编辑 </el-button>
+        </template>
+    </pro-table>
+    </div>
+    
+</template>
+
+<style lang="scss" scoped>
+@media only screen and (min-width: 1200px) {
+    :deep(.el-col-lg-6) {
+        flex: 0 0 50% !important;
+        max-width: 50% !important;
+       
+    }}
+</style>

+ 199 - 0
src/views/system/modules/menuForm.vue

@@ -0,0 +1,199 @@
+<script lang="ts" setup>
+import type { BasicForm, ICRUD } from '@/types/form'
+
+import api from '@/api/menu/menuForm'
+import mapi from '@/api/menu/menu'
+import { nextTick, onMounted } from 'vue'
+const props = defineProps({
+  id: {
+    type: String,
+    default: ''
+  },
+  classPath: {
+    type: String,
+    default: ''
+  }
+})
+const itemTableRef = ref<any>(null)
+const nameList = ref<any>([])
+
+const CRUD: ICRUD = {
+  create(data: any) {
+    data.menuId = props.id
+    return api.addMenuForm(data)
+  },
+  update(data: any) {
+    return api.updateMenuForm(data)
+  },
+  getList(data: any) {
+    data.menuId = props.id
+    return api.listMenuForm(data).then((res: any) => {
+      return {
+        list: res.data.records,
+        total: res.data.total
+      }
+    })
+  },
+  delete(data: any) {
+    return api.delMenuForm({
+      ids: data.id
+    })
+  },
+  getRecord(data: any) {
+    return api.getMenuForm({ id: data.id })
+  }
+}
+
+const logtFormConfig = reactive<BasicForm>({
+  span: 12,
+  formItems: [
+    {
+      span: 24,
+      label: '',
+      value: '',
+      name: '',
+      type: 'custom',
+      slots: [
+        {
+          name: 'default',
+          alias: 'infos'
+        }
+      ]
+    },
+    {
+      label: '字段名称',
+      value: '',
+      name: 'name',
+      type: 'select',
+      request: () => {
+        return mapi.getColumnList(props.classPath).then(res => {
+          nameList.value = res.data
+          return res.data.map((item: any) => {
+            return { ...item, value: item.name }
+          })
+        })
+      },
+      props: {
+        clearable: true,
+        filterable: true,
+        'default-first-option': true,
+        "allow-create": true
+      },
+      events: {
+        change: (el: any) => {
+          console.log(el)
+          console.log(nameList.value)
+          const field = nameList.value.find((item: any) => item.name == el)?.field
+          const entity = nameList.value.find((item: any) => item.name == el)?.entity
+          const name = nameList.value.find((item: any) => item.name == el)?.name
+          nextTick(() => {
+            itemTableRef.value.formData.code = name
+            itemTableRef.value.formData.formField = field
+            itemTableRef.value.formData.formEntity = entity
+          })
+        }
+      },
+      rules: [{ required: true, message: '字段名称不能为空', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '实体字段',
+      value: '',
+      name: 'code',
+      type: 'input',
+      rules: [{ required: true, message: '实体字段不能为空', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '表字段',
+      value: '',
+      name: 'formField',
+      rules: [{ required: true, message: '表字段不能为空', trigger: 'blur' }],
+      type: 'input'
+    },
+    {
+      label: '实体类',
+      value: '',
+      name: 'formEntity',
+      rules: [{ required: true, message: '实体字段不能为空', trigger: 'blur' }],
+      type: 'input'
+    },
+    {
+      label: '是否启用',
+      value: '0',
+      name: 'enabled',
+      type: 'switch',
+      props: {
+        'active-value': '0',
+        'inactive-value': '1'
+      }
+    },
+    {
+      label: '排序',
+      value: 1,
+      name: 'sort',
+      type: 'input-number',
+      props: {
+        min:1,
+        controlsPosition:"right"
+      },
+    },
+    {
+      label: '描述',
+      value: '',
+      name: 'remarks',
+      type: 'input',
+      props: {
+        type: 'textarea',
+        rows: 3
+      }, span: 24
+    }
+  ]
+})
+
+const checkSwitch = (row: any) => {
+  api.updateMenuForm({ id: row.id, enabled: row.enabled == 0 ? '1' : '0' }).then(res => {
+    itemTableRef.value.refresh()
+  })
+}
+</script>
+
+<template>
+  <div>
+    <pro-table
+    :crud="CRUD"
+    :tree-config="{}"
+    ref="itemTableRef"
+    height="80vh"
+    :tableConfig="{ operateWidth: 150 }"
+    :formConfig="logtFormConfig"
+    :selection="false"
+  >
+  <template #infos>
+    <el-alert title="字段名称:字段的含义如组织名称,  实体字段:实体字段如:organizeId, 表字段:数据库表字段名如:organize_id, 实体类:实体字段名如:Menu" type="warning" :closable="false" />
+  </template>
+    <vxe-column field="name" title="字段名称"></vxe-column>
+    <vxe-column field="code" title="字段编码"></vxe-column>
+    <vxe-column field="enabled" title="是否启用">
+      <template #default="{ row }">
+        <div @click="checkSwitch(row)">
+          <el-switch :model-value="row.enabled" :active-text="row.enabled==0 ? '已启用' : '未启用'" active-value="0" inactive-value="1" />
+        </div>
+      </template>
+    </vxe-column>
+    <vxe-column field="sort" title="排序"></vxe-column>
+    <vxe-column field="formField" title="表字段"></vxe-column>
+    <vxe-column field="formEntity" title="实体类字段"></vxe-column>
+  </pro-table>
+  </div>
+  
+</template>
+
+<style lang="scss" scoped>
+@media only screen and (min-width: 1200px) {
+    :deep(.el-col-lg-6) {
+        flex: 0 0 50% !important;
+        max-width: 50% !important;
+       
+    }}
+</style>

+ 196 - 0
src/views/system/modules/menuList.vue

@@ -0,0 +1,196 @@
+<script lang="ts" setup>
+import type { BasicForm, ICRUD } from '@/types/form'
+import mapi from '@/api/menu/menu'
+import api from '@/api/menu/menuColumn'
+
+const props = defineProps({
+    id: {
+        type: String,
+        default: ''
+    },
+    classPath: {
+        type: String,
+        default: ''
+    }
+})
+
+const itemTableRef = ref<any>(null)
+const nameList = ref<any>([])
+
+const CRUD: ICRUD = {
+    create(data: any) {
+        data.menuId = props.id
+        return api.addMenuColumn(data)
+    },
+    update(data: any) {
+        return api.updateMenuColumn(data)
+    },
+    getList(data: any) {
+        data.menuId = props.id
+        return api.listMenuColumn(data).then((res: any) => {
+            return {
+                list: res.data.records
+            }
+        })
+    },
+    delete(data: any) {
+        return api.delMenuColumn({
+            ids: data.id
+        })
+    },
+    getRecord(data: any) {
+        return api.getMenuColumn({ id: data.id }).then(res => {
+            return res
+        })
+    }
+}
+
+
+const logtFormConfig = reactive<BasicForm>({
+    span: 12,
+    formItems: [
+        {
+            span: 24,
+            label: '',
+            value: '',
+            name: '',
+            type: 'custom',
+            slots: [
+                {
+                    name: 'default',
+                    alias: 'infos'
+                }
+            ]
+        },
+        {
+            label: '字段名称',
+            value: '',
+            name: 'name',
+            type: 'select',
+            request: () => {
+                return mapi.getColumnList(props.classPath).then(res => {
+                    nameList.value = res.data
+                    return res.data.map((item: any) => {
+                        return { ...item, value: item.name }
+                    })
+                })
+            },
+            props: {
+                clearable: true,
+                filterable: true,
+                'default-first-option': true,
+                "allow-create": true
+            },
+            events: {
+                change: (el: any) => {
+                    console.log(el)
+                    console.log(nameList.value)
+                    const field = nameList.value.find((item: any) => item.name == el)?.field
+                    const entity = nameList.value.find((item: any) => item.name == el)?.entity
+                    const name = nameList.value.find((item: any) => item.name == el)?.name
+                    nextTick(() => {
+                        itemTableRef.value.formData.code = name
+                        itemTableRef.value.formData.columnField = field
+                        itemTableRef.value.formData.columnEntity = entity
+                    })
+                }
+            },
+            rules: [{ required: true, message: '请输入字段名称', trigger: 'blur', },],
+            search: true
+        },
+        {
+            label: '实体字段',
+            value: '',
+            name: 'code',
+            type: 'input',
+            rules: [{ required: true, message: '请输入实体字段', trigger: 'blur', },],
+            search: true
+        },
+        {
+            label: '表字段',
+            value: '',
+            name: 'columnField',
+            rules: [{ required: true, message: '请输入表字段', trigger: 'blur', },],
+            type: 'input',
+        },
+        {
+            label: '实体类',
+            value: '',
+            name: 'columnEntity',
+            rules: [{ required: true, message: '请输入实体类', trigger: 'blur', },],
+            type: 'input',
+        },
+        {
+            label: '是否启用',
+            value: '0',
+            name: 'enabled',
+            type: 'switch',
+            props: {
+                'active-value': '0',
+                'inactive-value': '1'
+            }
+        },
+        {
+            label: '排序',
+            value: 1,
+            name: 'sort',
+            type: 'input-number',
+            props: {
+        min:1,
+        controlsPosition:"right"
+      },
+        },
+        {
+            label: '描述',
+            value: '',
+            name: 'remarks',
+            type: 'input',
+            props: {
+                type: 'textarea',
+                rows: 3
+            }, span: 24
+        },
+
+    ]
+})
+const checkSwitch = (row: any) => {
+    api.updateMenuColumn({ id: row.id, enabled: row.enabled == 0 ? '1' : '0' }).then(res => {
+        itemTableRef.value.refresh()
+    })
+}
+
+</script>
+
+<template>
+    <div>
+        <pro-table :crud="CRUD" :tree-config="{ operateWidth: 150 }" ref="itemTableRef" height="80vh"
+        :tableConfig="{ operateWidth: 230 }" :formConfig="logtFormConfig"
+        :selection="false">
+        <template #infos>
+            <el-alert title="字段名称:字段的含义如组织名称,  实体字段:实体字段如:organizeId, 表字段:数据库表字段名如:organize_id, 实体类:实体字段名如:Menu"
+                type="warning" :closable="false" />
+        </template>
+        <vxe-column field="name" title="字段名称"></vxe-column>
+        <vxe-column field="code" title="字段编码" tree-node></vxe-column>
+        <vxe-column field="enabled" title="是否启用">
+            <template #default="{ row }">
+                <div @click="checkSwitch(row)">
+                    <el-switch :model-value="row.enabled" :active-text="row.enabled==0 ? '已启用' : '未启用'" active-value="0" inactive-value="1" />
+                </div>
+            </template>
+        </vxe-column>
+        <vxe-column field="columnField" title="表字段"></vxe-column>
+        <vxe-column field="columnEntity" title="实体类字段"></vxe-column>
+    </pro-table>
+    </div>
+   
+</template>
+
+<style lang="scss" scoped>
+@media only screen and (min-width: 1200px) {
+    :deep(.el-col-lg-6) {
+        flex: 0 0 50% !important;
+        max-width: 50% !important;
+       
+    }}
+</style>

+ 635 - 0
src/views/system/modules/menuPermission.vue

@@ -0,0 +1,635 @@
+<script lang="ts" setup>
+import type { BasicForm, ICRUD } from '@/types/form'
+import mapi from '@/api/menu/menu'
+import api from '@/api/menu/menuPermission'
+import cindApi from '@/api/menu/menuPermissionCondition'
+
+const props = defineProps({
+  id: {
+    type: String,
+    default: ''
+  },
+  classPath: {
+    type: String,
+    default: ''
+  }
+})
+const nameList = ref<any>([])
+
+const selectArray = ref<any>({
+  matchLogicArray: [
+    { label: 'and', value: 'and' },
+    { label: 'or', value: 'or' }
+  ],
+  conditionSymbolArray: [
+    { label: 'and', value: 'and' },
+    { label: 'or', value: 'or' }
+  ],
+  conditionArray: [],
+  condition: {}
+})
+
+const conditionJson = ref<any>([])
+
+const itemTableRef = ref<any>(null)
+
+const LEFTCRUD: ICRUD = {
+  create(data: any) {
+    data.conditionJson = JSON.stringify(conditionJson.value)
+    data.menuId = props.id
+    return api.addMenuPermission(data)
+  },
+  update(data: any) {
+    data.conditionJson = JSON.stringify(conditionJson.value)
+    data.menuId = props.id
+    return api.updateMenuPermission(data)
+  },
+  getList(data: any) {
+    data.menuId = props.id
+    return api.listMenuPermission(data).then((res: any) => {
+      cindApi.allListMenuPermissionCondition({ menuId: props.id }).then((res: any) => {
+        if (res.code == 200) {
+          selectArray.value.conditionArray = res.data
+
+          let conditionArray = selectArray.value.conditionArray
+          for (let i = 0; i < conditionArray.length; i++) {
+            selectArray.value.condition[conditionArray[i].id] = JSON.parse(conditionArray[i].conditionSymbol)
+          }
+        }
+      })
+      return {
+        list: res.data.records,
+        total: res.data.total
+      }
+    })
+  },
+  delete(data: any) {
+    return api.delMenuPermission({
+      ids: data.id
+    })
+  },
+  getRecord(data: any) {
+    return api.getMenuPermission(data.id).then(res => {
+      conditionJson.value = JSON.parse(res.data.conditionJson)
+      return res
+    })
+  }
+}
+
+const logtFormConfig = reactive<BasicForm>({
+  span: 12,
+  formItems: [
+    {
+      label: '方案名称',
+      value: '',
+      name: 'name',
+      type: 'input',
+      rules: [{ required: true, message: '方案名称不能为空', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '方案编码',
+      value: '',
+      name: 'code',
+      type: 'input',
+      rules: [{ required: true, message: '方案编码不能为空', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '规则实体类',
+      value: '',
+      name: 'ruleEntity',
+      type: 'input',
+      rules: [{ required: true, message: '规则实体类不能为空', trigger: 'blur' }],
+      search: false
+    },
+    {
+      label: '匹配逻辑',
+      value: '',
+      name: 'matchLogic',
+      rules: [{ required: true, message: '匹配逻辑不能为空', trigger: 'blur' }],
+      type: 'select',
+      options: [
+        { label: 'and', value: '0' },
+        { label: 'or', value: '1' }
+      ]
+    },
+    {
+      span: 24,
+      label: '过滤条件',
+      value: '',
+      name: '',
+      type: 'custom',
+      slots: [
+        {
+          name: 'default',
+          alias: 'condition'
+        }
+      ]
+    }
+  ]
+})
+
+const addConditionGroup = () => {
+  conditionJson.value.push({
+    logic: '',
+    groups: []
+  })
+}
+
+const addCondition = (index: any) => {
+  conditionJson.value[index].groups.push({})
+}
+const delCondition = (gropindex: any, index: any) => {
+  conditionJson.value[gropindex].groups.splice(index, 1)
+}
+const delConditionGroup = (index: any) => {
+  conditionJson.value.splice(index, 1)
+}
+
+const activeName = ref<any>(0)
+
+const selectData = ref<any>({
+  permissionJson: {
+    array: {}
+  },
+  conditionTextArray: [
+    { value: 'input', label: '任意文本' },
+    { value: '@userId', label: '当前用户' },
+    { value: '@organizeId', label: '当前组织' }
+  ],
+  fieldRuleArray: [
+    { value: 0, label: '主表规则' },
+    { value: 1, label: '副表规则' },
+    { value: 2, label: '子表规则' }
+  ],
+  conditionSymbolArray: [
+    { value: '>=', label: '大于等于' },
+    { value: '>', label: '大于' },
+    { value: '==', label: '等于' },
+    { value: '<=', label: '小于等于' },
+    { value: '<', label: '小于' },
+    { value: '<>', label: '不等于' },
+    { value: 'between', label: '介于' },
+    { value: 'null', label: '为空' },
+    { value: 'notNull', label: '不为空' },
+    { value: 'in', label: '包含任意一个' },
+    { value: 'notIn', label: '不包含任意一个' },
+    { value: 'like', label: '包含' },
+    { value: 'notLike', label: '不包含' },
+    { value: 'and', label: '并且' },
+    { value: 'or', label: '或者' },
+  ]
+})
+
+const rightLogtFormConfig = reactive<BasicForm>({
+  span: 12,
+  formItems: [
+    {
+      label: '字段名称',
+      value: '',
+      name: 'name',
+      type: 'select',
+      request: () => {
+        return mapi.getPermissionParam(props.classPath).then(res => {
+          nameList.value = res.data
+          return res.data
+        })
+      },
+      props: {
+        clearable: true,
+        filterable: true,
+        'default-first-option': true,
+        "allow-create": true
+      },
+      events: {
+        change: (el: any) => {
+          const field = nameList.value.find((item: any) => item.value == el)?.value
+          const entity = nameList.value.find((item: any) => item.value == el)?.table
+          const name = nameList.value.find((item: any) => item.value == el)?.type
+          nextTick(() => {
+            itemTableRef.value.formData.code = field
+            itemTableRef.value.formData.bindTable = entity
+            itemTableRef.value.formData.type = name
+          })
+        },
+      },
+      rules: [{ required: true, message: '字段名称不能为空', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '编码',
+      value: '',
+      name: 'code',
+      type: 'input',
+      rules: [{ required: true, message: '编码不能为空', trigger: 'blur' }],
+      search: true
+    },
+    {
+      label: '表别名',
+      value: '',
+      name: 'bindTable',
+      rules: [{ required: true, message: '表别名不能为空', trigger: 'blur' }],
+      type: 'input'
+    },
+    {
+      label: '字段类型',
+      value: '',
+      name: 'type',
+      rules: [{ required: true, message: '字段类型不能为空', trigger: 'blur' }],
+      type: 'select',
+      options: [
+        {
+          label: 'string',
+          value: 'string'
+        },
+        {
+          label: 'int',
+          value: 'int'
+        },
+        {
+          label: 'double',
+          value: 'double'
+        },
+        {
+          label: 'varchar',
+          value: 'varchar'
+        },
+        {
+          label: 'text',
+          value: 'text'
+        },
+        {
+          label: 'bigint',
+          value: 'bigint'
+        },
+      ]
+    },
+    {
+      label: '条件内容',
+      value: '',
+      name: 'conditionText',
+      rules: [{ required: true, message: '条件内容不能为空', trigger: 'blur' }],
+      type: 'select',
+      options: [
+        {
+          label: '当前用户',
+          value: '@userId'
+        },
+        {
+          label: '当前用户及下属',
+          value: '@userAraSubordinates'
+        },
+        {
+          label: '当前组织',
+          value: '@organizeId'
+        },
+        {
+          label: '当前组织及子组织',
+          value: '@organizationAndSuborganization'
+        },
+        {
+          label: '当前分管组织',
+          value: '@branchManageOrganize'
+        },
+        {
+          label: '当分管组织及子组织',
+          value: "@branchManageOrganizeAndSub",
+        },
+        {
+          label: '当前部门的上级部门',
+          value: "@parentOrganize",
+        },
+        {
+          label: '当前部门的上级部门的子部门',
+          value: '@parentOrganizeUnder'
+        },
+        {
+          label: '任意文本',
+          value: 'input'
+        },
+      ]
+    },
+    {
+      label: '条件符号',
+      value: '',
+      name: 'conditionSymbol',
+      props: {
+        multiple: true
+      },
+      rules: [{ required: true, message: '条件符号不能为空', trigger: 'blur' }],
+      type: 'select',
+      options: selectData.value.conditionSymbolArray
+    }
+  ]
+})
+
+const RIGHTCRUD: ICRUD = {
+  create(data: any) {
+    let conditionSymbol = data.conditionSymbol
+    let conditionSymbolArray = selectData.value.conditionSymbolArray
+    let conditionSymbolName = ''
+    for (let i = 0; i < conditionSymbol.length; i++) {
+      for (let j = 0; i < conditionSymbolArray.length; j++) {
+        if (conditionSymbol[i] === conditionSymbolArray[j].value) {
+          conditionSymbolName += conditionSymbolArray[j].label
+          break
+        }
+      }
+      if (i != conditionSymbol.length - 1) {
+        conditionSymbolName += ','
+      }
+    }
+    data.conditionSymbol = JSON.stringify(conditionSymbol)
+    data.conditionSymbolName = conditionSymbolName
+    data.menuId = props.id
+    return cindApi.addMenuPermissionCondition(data)
+  },
+  update(data: any) {
+    let conditionSymbol = data.conditionSymbol
+    let conditionSymbolArray = selectData.value.conditionSymbolArray
+    let conditionSymbolName = ''
+    for (let i = 0; i < conditionSymbol.length; i++) {
+      for (let j = 0; i < conditionSymbolArray.length; j++) {
+        if (conditionSymbol[i] === conditionSymbolArray[j].value) {
+          conditionSymbolName += conditionSymbolArray[j].label
+          break
+        }
+      }
+      if (i != conditionSymbol.length - 1) {
+        conditionSymbolName += ','
+      }
+    }
+    data.conditionSymbol = JSON.stringify(conditionSymbol)
+    data.conditionSymbolName = conditionSymbolName
+    data.menuId = props.id
+    return cindApi.updateMenuPermissionCondition(data)
+  },
+  getList(data: any) {
+    data.menuId = props.id
+    return cindApi.listMenuPermissionCondition(data).then((res: any) => {
+      return {
+        list: res.data.records,
+        total: res.data.total
+      }
+    })
+  },
+  delete(data: any) {
+    return cindApi.delMenuPermissionCondition(data.id)
+  },
+  getRecord(data: any) {
+    return cindApi.getMenuPermissionCondition(data.id).then((res: any) => {
+      res.data.conditionSymbol = JSON.parse(res.data.conditionSymbol)
+      return {
+        data: res.data
+      }
+    })
+  }
+}
+
+const changeCondition = (res: any, groupIndex: any, index: any) => {
+  selectArray.value.conditionArray.forEach((element: any) => {
+    if (element.id == res) {
+      console.log('表单字段', itemTableRef.value.formData)
+      const valueObject = ref<any>({
+        value: element.conditionText,
+        field: element.code,
+        type: itemTableRef.value.formData.name,
+        fieldRule: '',
+        bindTable: element.bindTable,
+        condition: element.code,
+        conditionText: element.conditionText,
+        childTableKey: '',
+        conditionId: element.id,
+      })
+
+
+      // element.field = element.conditionText,
+      // element.op = element.symbol,
+      // element.type = itemTableRef.value.formData.name,
+      // element.value = element.conditionText,
+      // element.fieldRule = '',
+      // element.bindTable = '',
+      // element.condition = res,
+      // element.childTableKey = ''
+
+      conditionJson.value[groupIndex].groups[index] = valueObject.value
+      conditionJson.value[groupIndex].groups[index].conditionType = element.conditionText
+      console.log('element', element)
+      console.log('选完后的数据', conditionJson.value[groupIndex].groups[index])
+    }
+  });
+}
+
+const handleCreate = () => {
+  conditionJson.value = []
+}
+
+
+
+const programmeList = ref<any>([])
+const queryList = () => {
+  api.findCommonSolutionsList({
+    sysData: 1
+  }).then(res => {
+    programmeList.value = res.data
+  })
+}
+
+const setProgramme = (e: any) => {
+  api.saveByCommonSolutions({
+    menuId: props.id,
+    commonSolutionsId: e.id
+  }).then((res: any) => {
+    if (res.code == 200) {
+      itemTableRef.value.refresh()
+    }
+  })
+}
+
+
+const dialogVisible = ref(false)
+
+const formData = ref<any>({})
+const orgFormConfig = reactive<BasicForm>({
+  span: 24,
+  formItems: [
+    {
+      label: '数据连接',
+      value: 'class',
+      name: 'type',
+      props: {
+        disabled: true
+      },
+      type: 'select',
+      options: [
+        {
+          label: '实体类',
+          value: 'class'
+        }]
+    },
+    {
+      label: '数据选择',
+      value: '',
+      name: 'name',
+      type: 'input',
+    },
+  ]
+})
+
+
+
+const dataLink = () => {
+
+  api.getMenuPermissionData({ menuId: props.id }).then(res => {
+  if(res.data == null){
+    formData.value = {
+      type:'class'
+    }
+  }else{
+    formData.value = res.data
+
+  }
+  })
+  dialogVisible.value = true
+
+}
+
+const create = (data: any) => {
+  data.menuId = props.id
+  return api.saveMenuPermissionData(data).then(() => {
+    dialogVisible.value = false
+  })
+}
+
+
+const handleEdit = (row: any) => {
+  itemTableRef.value.handleUpdate(row)
+}
+
+
+</script>
+
+<template>
+  <div>
+    <el-button-group class="mb-3">
+    <el-button @click="activeName = 0" :type="activeName == 0 ? 'primary' : 'info'">数据权限方案</el-button>
+    <el-button @click="activeName = 1" :type="activeName == 0 ? 'info' : 'primary'">数据权限字段</el-button>
+  </el-button-group>
+
+  <div v-if="activeName == 0">
+    <el-alert title="维护数据权限方案,通过配置的数据权限字段,自定义数据的筛选" type="warning" :closable="false" />
+    <el-alert title="快捷方案为系统提供的默认筛选方案" type="warning" :closable="false" />
+    <pro-table :crud="LEFTCRUD" :tree-config="{}" ref="itemTableRef" height="70vh"
+      :tableConfig="{ operateWidth: 230, showEdit: false, }" 
+      :formConfig="logtFormConfig" :selection="false" @click-create="handleCreate">
+      <template #toolbar="toolbar">
+        <el-dropdown trigger="click">
+          <el-button type="primary" class="ml-3" @click="queryList">
+            快捷方案<el-icon class="el-icon--right"><arrow-down /></el-icon>
+          </el-button>
+          <template #dropdown>
+            <el-dropdown-menu v-for="(item, index) in programmeList">
+              <el-dropdown-item @click="setProgramme(item)">
+                {{ item.name }}
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </template>
+      <template #condition>
+        <ElCard class="w-full mb-10px" v-for="(groupItem, groupIndex) in conditionJson" shadow="never">
+          <ElRow>
+            <div class="adddel">
+              <div class="w-300px mr-3">
+                <el-select v-model="groupItem.logic" sty>
+                  <el-option v-for="item in selectArray.conditionSymbolArray" :key="item.value" :label="item.label"
+                    :value="item.value" />
+                </el-select>
+              </div>
+
+              <ElButton @click="addCondition(groupIndex)" type="primary">添加字段</ElButton>
+              <ElButton @click="delConditionGroup(groupIndex)" type="danger">移除字段组</ElButton>
+            </div>
+
+            <ElCard v-for="(item, index) in groupItem.groups" class="w-full mb-10px" shadow="never">
+              <ElRow :gutter="24">
+                <ElCol :span="5">
+                  <el-select v-model="conditionJson[groupIndex].groups[index].conditionId"
+                    @change="(res: any) => changeCondition(res, groupIndex, index)">
+                    <el-option v-for="item in selectArray.conditionArray" :key="item.id" :label="item.name"
+                      :value="item.id" />
+                  </el-select>
+                </ElCol>
+                <ElCol :span="5">
+                  <el-select v-model="conditionJson[groupIndex].groups[index].op">
+                    <el-option v-for="itm in selectArray.condition[item.conditionId]" :key="itm" :label="itm"
+                      :value="itm" />
+                  </el-select>
+                </ElCol>
+                <ElCol :span="5">
+                  <ElInput v-model="conditionJson[groupIndex].groups[index].value"
+                    :disabled="conditionJson[groupIndex].groups[index].conditionType != 'input'" placeholder="请输入数据权限方案名称"
+                    show-word-limit minlength="1" maxlength="100" />
+                </ElCol>
+                <ElCol :span="4">
+                  <ElButton @click="delCondition(groupIndex, index)" class="border-style-dashed" type="danger">移除
+                  </ElButton>
+                </ElCol>
+              </ElRow>
+            </ElCard>
+          </ElRow>
+        </ElCard>
+        <ElButton @click="addConditionGroup()" class="mt-10px w-25% border-style-dashed" type="primary">添加字段组</ElButton>
+      </template>
+
+      <vxe-column field="name" title="方案名称" tree-node></vxe-column>
+      <vxe-column field="code" title="方案编码"></vxe-column>
+      <!-- <vxe-column field="conditionJson" title="多分组多条件json" width="150"></vxe-column> -->
+      <vxe-column field="matchLogic" title="匹配逻辑">
+        <template #default="{ row }">
+          <div>{{ row.matchLogic == '0' ? 'and' : 'or' }}</div>
+        </template>
+      </vxe-column>
+
+      <template #operateAfter="{ row }">
+        <el-button type="primary" plain size="small" v-if="row.source == 0" @click="handleEdit(row)"> 编辑 </el-button>
+      </template>
+    </pro-table>
+  </div>
+  <div v-else>
+    <el-alert title="维护数据权限方案要使用到的字段信息" type="warning" :closable="false" />
+    <el-alert title="数据连接设置要进行数据过滤的的实体类名(不含包名,例如:TenantQueryVO),将对findList和findAllList进行数据过滤。" type="warning"
+      :closable="false" />
+    <pro-table :crud="RIGHTCRUD" :tree-config="{}" height="70vh" ref="itemTableRef" :tableConfig="{ operateWidth: 150 }"
+       :formConfig="rightLogtFormConfig" :selection="false">
+      <template #toolbar="toolbar">
+        <el-button type="primary" @click="dataLink">数据连接</el-button>
+      </template>
+      <vxe-column field="name" title="字段名称" tree-node></vxe-column>
+      <vxe-column field="code" title="编码"></vxe-column>
+      <vxe-column field="bindTable" title="表别名"></vxe-column>
+      <vxe-column field="type" title="字段类型"></vxe-column>
+      <vxe-column field="conditionSymbolName" title="条件符号名称"></vxe-column>
+    </pro-table>
+    <dialog-form v-model="dialogVisible" :formConfig="orgFormConfig" :formData="formData" :create="create"
+      :update="create" v-if="dialogVisible" />
+  </div>
+  </div>
+  
+</template>
+
+<style lang="scss" scoped>
+.adddel {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  // margin-left: 2%;
+}
+@media only screen and (min-width: 1200px) {
+    :deep(.el-col-lg-6) {
+        flex: 0 0 50% !important;
+        max-width: 50% !important;
+       
+    }}
+</style>