Pārlūkot izejas kodu

菜单管理应用隔离接口修改,样式修改

ZL 2 mēneši atpakaļ
vecāks
revīzija
0a59047233

+ 14 - 4
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java

@@ -14,7 +14,6 @@ import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.constant.SymbolConstant;
 import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.system.vo.LoginUser;
-import org.jeecg.common.util.IpUtils;
 import org.jeecg.common.util.Md5Util;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.config.JeecgBaseConfig;
@@ -22,7 +21,6 @@ import org.jeecg.config.shiro.ShiroRealm;
 import org.jeecg.modules.base.service.BaseCommonService;
 import org.jeecg.modules.system.constant.DefIndexConst;
 import org.jeecg.modules.system.entity.*;
-import org.jeecg.modules.system.entity.AppmanageEntity.AppBaseInfo;
 import org.jeecg.modules.system.model.SysPermissionTree;
 import org.jeecg.modules.system.model.TreeModel;
 import org.jeecg.modules.system.service.*;
@@ -92,13 +90,25 @@ public class SysPermissionController {
 	@RequiresPermissions("system:permission:list")
 	@RequestMapping(value = "/sqlList", method = RequestMethod.GET)
 	@PermissionData
-	public Result<List<SysPermissionTree>> list(SysPermission sysPermission, HttpServletRequest req) {
+	public Result<List<SysPermissionTree>> list(SysPermission sysPermission, HttpServletRequest req,@RequestParam(name = "ids", required = false)String appIds) {
         long start = System.currentTimeMillis();
 		Result<List<SysPermissionTree>> result = new Result<>();
+		//应用数据隔离
+		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+		Boolean isAdmin = loginUser.getUsername().equals("admin");
+		String appSql = "";
+		if(oConvertUtils.isEmpty(appIds)&&!isAdmin){
+			result.setSuccess(true);
+			result.setResult(new ArrayList<>());
+			return result;
+		}
 		try {
+			if (oConvertUtils.isNotEmpty(appIds)) {
+				appSql = appIds;
+			}
 			sysPermission.setDelFlag(CommonConstant.DEL_FLAG_0);
 //			List<SysPermission> list = sysPermissionService.listAndAppName(sysPermission);
-			List<SysPermission> list = sysPermissionService.listAndAppNameWithPermission(sysPermission);
+			List<SysPermission> list = sysPermissionService.listAndAppNameWithPermission(sysPermission, appSql);
 			List<SysPermissionTree> treeList = new ArrayList<>();
 
 			//如果有菜单名查询条件,则平铺数据 不做上下级

+ 1 - 1
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysPermissionService.java

@@ -31,7 +31,7 @@ public interface ISysPermissionService extends IService<SysPermission> {
 	public List<TreeModel> queryListByParentId(String parentId);
 //	public List<SysPermission> joinList(MPJLambdaWrapper<SysPermission> querywrapper);
 	public List<SysPermission> listAndAppName( SysPermission sysPermission);
-	public List<SysPermission> listAndAppNameWithPermission( SysPermission sysPermission);
+	public List<SysPermission> listAndAppNameWithPermission( SysPermission sysPermission,String sql);
 
 	/**
      * 真实删除

+ 12 - 8
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java

@@ -79,15 +79,19 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
 	public List<SysPermission> listAndAppName( SysPermission sysPermission) {
 		return sysPermissionMapper.listAndAppName(sysPermission);
 	}
-	public List<SysPermission> listAndAppNameWithPermission( SysPermission sysPermission) {
-		String sql = QueryGenerator.installAuthJdbc(SysPermission.class);
-		//处理sql格式,避免注入风险
-		//只对应用进行数据隔离
-		if (sql!= null){
-			String modifiedSql = modifySql(sql);
-			sql = modifiedSql;
+	public List<SysPermission> listAndAppNameWithPermission( SysPermission sysPermission,String permissionSql) {
+		//此处修改为前台控制应用隔离
+//		String sql = QueryGenerator.installAuthJdbc(SysPermission.class);
+//		//处理sql格式,避免注入风险
+//		//只对应用进行数据隔离
+//		if (sql!= null){
+//			String modifiedSql = modifySql(sql);
+//			sql = modifiedSql;
+//		}
+		if(permissionSql.length()>0){
+			permissionSql = "AND  p.app_id IN ("+permissionSql+")";
 		}
-		return sysPermissionMapper.listAndAppNameWithPermission(sysPermission,sql);
+		return sysPermissionMapper.listAndAppNameWithPermission(sysPermission,permissionSql);
 	}
 	public static String modifySql(String sql) {
 		String regex ="(?i)\\s+AND\\s+";

+ 238 - 224
jeecgboot-vue3/src/views/system/menu/menu/index.vue

@@ -30,253 +30,267 @@
   </div>
 </template>
 <script lang="ts" name="system-menu" setup>
-  import { nextTick, ref,onMounted } from 'vue';
-  import { BasicTable, useTable, TableAction } from '/@/components/Table';
-  import { useListPage } from '/@/hooks/system/useListPage';
-  import { useDrawer } from '/@/components/Drawer';
-  import MenuDrawer from './MenuDrawer.vue';
-  import DataRuleList from '../components/DataRuleList.vue';
-  import { columns,searchFormSchema } from './menu.data';
-  import { list, deleteMenu, batchDeleteMenu } from './menu.api';
-  import { useDefIndexStore } from "@/store/modules/defIndex";
-  import { useI18n } from "/@/hooks/web/useI18n";
+import { nextTick, ref, onMounted, watch } from 'vue';
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
+import { useListPage } from '/@/hooks/system/useListPage';
+import { useDrawer } from '/@/components/Drawer';
+import MenuDrawer from './MenuDrawer.vue';
+import DataRuleList from '../components/DataRuleList.vue';
+import { columns, searchFormSchema } from './menu.data';
+import { list, deleteMenu, batchDeleteMenu, appList as getAppList } from './menu.api';
+import { useDefIndexStore } from '@/store/modules/defIndex';
+import { useI18n } from '/@/hooks/web/useI18n';
 
-  const checkedKeys = ref<Array<string | number>>([]);
-  const showFooter = ref(true);
-  const [registerDrawer, { openDrawer }] = useDrawer();
-  const [registerDrawer1, { openDrawer: openDataRule }] = useDrawer();
-  const { t } = useI18n();
+const checkedKeys = ref<Array<string | number>>([]);
+const showFooter = ref(true);
+const [registerDrawer, { openDrawer }] = useDrawer();
+const [registerDrawer1, { openDrawer: openDataRule }] = useDrawer();
+const { t } = useI18n();
 
-  // 自定义菜单名称列渲染
-  columns[0].customRender = function ({text, record}) {
-    const isDefIndex = checkDefIndex(record)
-    if (isDefIndex) {
-      text += '(默认首页)'
+// 自定义菜单名称列渲染
+columns[0].customRender = function ({ text, record }) {
+  const isDefIndex = checkDefIndex(record);
+  if (isDefIndex) {
+    text += '(默认首页)';
+  }
+  // update-begin--author:liaozhiyang---date:20240306---for:【QQYUN-8379】菜单管理页菜单国际化
+  if (text.includes("t('") && t) {
+    return new Function('t', `return ${text}`)(t);
+  }
+  // update-end--author:liaozhiyang---date:20240306---for:【QQYUN-8379】菜单管理页菜单国际化
+  return text;
+};
+const appList = ref([]);
+import { useAppStore } from '/@/store/modules/app';
+const appStore = useAppStore();
+onMounted(async () => {
+  initHrefModal();
+  appList.value = await getAppList();
+});
+function initHrefModal() {
+  let params = appStore.getMessageHrefParams;
+  if (params) {
+    let anntId = params.id;
+    if (anntId) {
+      alert('消息跳转' + anntId);
     }
-    // update-begin--author:liaozhiyang---date:20240306---for:【QQYUN-8379】菜单管理页菜单国际化
-    if (text.includes("t('") && t) {
-      return new Function('t', `return ${text}`)(t);
+    let detailId = params.detailId;
+    if (detailId) {
+      alert('消息跳转' + detailId);
     }
-    // update-end--author:liaozhiyang---date:20240306---for:【QQYUN-8379】菜单管理页菜单国际化
-    return text
+    appStore.setMessageHrefParams('');
   }
+}
 
-  import { useAppStore } from '/@/store/modules/app';
-  const appStore = useAppStore();
-  onMounted(()=>{
-    initHrefModal();
-  });
-  function initHrefModal(){
-    let params = appStore.getMessageHrefParams;
-    if(params){
-      let anntId = params.id;
-      if(anntId){
-        alert('消息跳转'+anntId)
-      }
-      let detailId = params.detailId;
-      if(detailId){
-        alert('消息跳转'+detailId)
-      }
-        appStore.setMessageHrefParams('')
-    }
-  }
+watch(appList, () => loadData());
 
-  // 列表页面公共参数、方法
-  const { prefixCls, tableContext } = useListPage({
-    tableProps: {
-      title: '菜单列表',
-      api: list,
-      columns: columns,
-      size: 'small',
-      pagination: false,
-      isTreeTable: true,
-      expandIconColumnIndex:1,
-      striped: true,
-      useSearchForm: true,
-      showTableSetting: true,
-      bordered: true,
-      showIndexColumn: false,
-      tableSetting: { fullScreen: true },
-      formConfig: {
-        // update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-5873】查询区域lablel默认居左
-        labelWidth:60,
-        owProps: { gutter: 24 },
-        // update-end--author:liaozhiyang---date:20230803---for:【QQYUN-5873】查询区域lablel默认居左
-        schemas: searchFormSchema,
-        autoAdvancedCol: 4,
-        baseColProps: { xs: 24, sm: 12, md: 6, lg: 6, xl: 6, xxl: 6 },
-        actionColOptions: { xs: 24, sm: 12, md: 6, lg: 6, xl: 6, xxl: 6 },
-      },
-      actionColumn: {
-        width: 120,
-      },
+function loadData() {
+  reload();
+}
+// 列表页面公共参数、方法
+const { prefixCls, tableContext } = useListPage({
+  tableProps: {
+    title: '菜单列表',
+    api: list,
+    columns: columns,
+    immediate: false,
+    beforeFetch: (params) => {
+      if (appList.value.length > 0) {
+        const ids = appList.value.map((item) => item.id);
+        const idsString = ids.join(',');
+        params.ids = idsString;
+      }
     },
-  });
-  //注册table数据
-  const [registerTable, { reload, expandAll, collapseAll,getForm }] = tableContext;
+    size: 'small',
+    pagination: false,
+    isTreeTable: true,
+    expandIconColumnIndex: 1,
+    striped: true,
+    useSearchForm: true,
+    showTableSetting: true,
+    bordered: true,
+    showIndexColumn: false,
+    tableSetting: { fullScreen: true },
+    formConfig: {
+      // update-begin--author:liaozhiyang---date:20230803---for:【QQYUN-5873】查询区域lablel默认居左
+      labelWidth: 70,
+      owProps: { gutter: 24 },
+      // update-end--author:liaozhiyang---date:20230803---for:【QQYUN-5873】查询区域lablel默认居左
+      schemas: searchFormSchema,
+      autoAdvancedCol: 4,
+      baseColProps: { xs: 24, sm: 12, md: 6, lg: 6, xl: 6, xxl: 6 },
+      actionColOptions: { push:1,xs: 24, sm: 12, md: 6, lg: 6, xl: 6, xxl: 6 },
+    },
+    actionColumn: {
+      width: 120,
+    },
+  },
+});
+//注册table数据
+const [registerTable, { reload, expandAll, collapseAll, getForm }] = tableContext;
 
-  /**
-   * 选择列配置
-   */
-  const rowSelection = {
-    type: 'checkbox',
-    columnWidth: 25,
-    selectedRowKeys: checkedKeys,
-    onChange: onSelectChange,
-  };
+/**
+ * 选择列配置
+ */
+const rowSelection = {
+  type: 'checkbox',
+  columnWidth: 25,
+  selectedRowKeys: checkedKeys,
+  onChange: onSelectChange,
+};
 
-  /**
-   * 选择事件
-   */
-  function onSelectChange(selectedRowKeys: (string | number)[]) {
-    checkedKeys.value = selectedRowKeys;
-  }
+/**
+ * 选择事件
+ */
+function onSelectChange(selectedRowKeys: (string | number)[]) {
+  checkedKeys.value = selectedRowKeys;
+}
 
-  /**
-   * 新增
-   */
-  function handleCreate() {
-    showFooter.value = true;
-    let {getFieldsValue} = getForm();
-    openDrawer(true, {
-      record: {  appId:getFieldsValue().appId?getFieldsValue().appId:'0' },
-      isUpdate: false,
-    });
-  }
+/**
+ * 新增
+ */
+function handleCreate() {
+  showFooter.value = true;
+  let { getFieldsValue } = getForm();
+  openDrawer(true, {
+    record: { appId: getFieldsValue().appId ? getFieldsValue().appId : '0' },
+    isUpdate: false,
+  });
+}
 
-  /**
-   * 编辑
-   */
-  function handleEdit(record) {
-    showFooter.value = true;
-    openDrawer(true, {
-      record,
-      isUpdate: true,
-    });
-  }
-  /**
-   * 详情
-   */
-  function handleDetail(record) {
-    showFooter.value = false;
-    openDrawer(true, {
-      record,
-      isUpdate: true,
-    });
-  }
-  /**
-   * 添加下级
-   */
-  function handleAddSub(record) {
-    openDrawer(true, {
-      record: { parentId: record.id, menuType: 1,appId:record.appId },
-      isUpdate: false,
-    });
-  }
-  /**
-   * 数据权限弹窗
-   */
-  function handleDataRule(record) {
-    openDataRule(true, { id: record.id });
-  }
+/**
+ * 编辑
+ */
+function handleEdit(record) {
+  showFooter.value = true;
+  openDrawer(true, {
+    record,
+    isUpdate: true,
+  });
+}
+/**
+ * 详情
+ */
+function handleDetail(record) {
+  showFooter.value = false;
+  openDrawer(true, {
+    record,
+    isUpdate: true,
+  });
+}
+/**
+ * 添加下级
+ */
+function handleAddSub(record) {
+  openDrawer(true, {
+    record: { parentId: record.id, menuType: 1, appId: record.appId },
+    isUpdate: false,
+  });
+}
+/**
+ * 数据权限弹窗
+ */
+function handleDataRule(record) {
+  openDataRule(true, { id: record.id });
+}
 
-  /**
-   * 删除
-   */
-  async function handleDelete(record) {
-    await deleteMenu({ id: record.id }, reload);
-  }
-  /**
-   * 批量删除事件
-   */
-  async function batchHandleDelete() {
-    await batchDeleteMenu({ ids: checkedKeys.value }, reload);
-  }
-  /**
-   * 成功回调
-   */
-  function handleSuccess() {
-    reload();
-    reloadDefIndex();
-  }
+/**
+ * 删除
+ */
+async function handleDelete(record) {
+  await deleteMenu({ id: record.id }, reload);
+}
+/**
+ * 批量删除事件
+ */
+async function batchHandleDelete() {
+  await batchDeleteMenu({ ids: checkedKeys.value }, reload);
+}
+/**
+ * 成功回调
+ */
+function handleSuccess() {
+  reload();
+  reloadDefIndex();
+}
 
-  function onFetchSuccess() {
-    // 演示默认展开所有表项
-    nextTick(expandAll);
-  }
+function onFetchSuccess() {
+  // 演示默认展开所有表项
+  nextTick(expandAll);
+}
 
-  // --------------- begin 默认首页配置 ------------
+// --------------- begin 默认首页配置 ------------
 
-  const defIndexStore = useDefIndexStore()
+const defIndexStore = useDefIndexStore();
 
-  // 设置默认主页
-  async function handleSetDefIndex(record: Recordable) {
-    defIndexStore.update(record.url, record.component, record.route)
-  }
+// 设置默认主页
+async function handleSetDefIndex(record: Recordable) {
+  defIndexStore.update(record.url, record.component, record.route);
+}
 
-  /**
-   * 检查是否为默认主页
-   * @param record
-   */
-  function checkDefIndex(record: Recordable) {
-    return defIndexStore.check(record.url)
-  }
+/**
+ * 检查是否为默认主页
+ * @param record
+ */
+function checkDefIndex(record: Recordable) {
+  return defIndexStore.check(record.url);
+}
 
-  // 重新加载默认首页配置
-  function reloadDefIndex() {
-    try {
-      defIndexStore.query();
-    } catch (e) {
-      console.error(e)
-    }
+// 重新加载默认首页配置
+function reloadDefIndex() {
+  try {
+    defIndexStore.query();
+  } catch (e) {
+    console.error(e);
   }
+}
 
-  reloadDefIndex()
+reloadDefIndex();
 
-  // --------------- end 默认首页配置 ------------
+// --------------- end 默认首页配置 ------------
 
-  /**
-   * 操作栏
-   */
-  function getTableAction(record) {
-    return [
-      {
-        label: '编辑',
-        onClick: handleEdit.bind(null, record),
-      },
-    ];
-  }
+/**
+ * 操作栏
+ */
+function getTableAction(record) {
+  return [
+    {
+      label: '编辑',
+      onClick: handleEdit.bind(null, record),
+    },
+  ];
+}
 
-  /**
-   * 下拉操作栏
-   */
-  function getDropDownAction(record) {
-    return [
-      // {
-      //   label: '详情',
-      //   onClick: handleDetail.bind(null, record),
-      // },
-      {
-        label: '添加下级',
-        onClick: handleAddSub.bind(null, record),
-      },
-      {
-        label: '数据规则',
-        onClick: handleDataRule.bind(null, record),
-      },
-      {
-        label: '设为默认首页',
-        onClick: handleSetDefIndex.bind(null, record),
-        ifShow: () => !record.internalOrExternal && record.component && !checkDefIndex(record),
-      },
-      {
-        label: '删除',
-        color: 'error',
-        popConfirm: {
-          title: '是否确认删除',
-          confirm: handleDelete.bind(null, record),
-        },
+/**
+ * 下拉操作栏
+ */
+function getDropDownAction(record) {
+  return [
+    // {
+    //   label: '详情',
+    //   onClick: handleDetail.bind(null, record),
+    // },
+    {
+      label: '添加下级',
+      onClick: handleAddSub.bind(null, record),
+    },
+    {
+      label: '数据规则',
+      onClick: handleDataRule.bind(null, record),
+    },
+    {
+      label: '设为默认首页',
+      onClick: handleSetDefIndex.bind(null, record),
+      ifShow: () => !record.internalOrExternal && record.component && !checkDefIndex(record),
+    },
+    {
+      label: '删除',
+      color: 'error',
+      popConfirm: {
+        title: '是否确认删除',
+        confirm: handleDelete.bind(null, record),
       },
-    ];
-  }
+    },
+  ];
+}
 </script>

+ 12 - 8
jeecgboot-vue3/src/views/system/menu/menu/menu.data.ts

@@ -2,7 +2,8 @@ import { BasicColumn } from '/@/components/Table';
 import { FormSchema } from '/@/components/Table';
 import { h } from 'vue';
 import { Icon } from '/@/components/Icon';
-import { ajaxGetDictItems, checkPermDuplication } from './menu.api';
+
+import { ajaxGetDictItems, checkPermDuplication,appList as getAppList } from './menu.api';
 import { render } from '/@/utils/common/renderUtils';
 
 const isDir = (type) => type === 0;
@@ -67,18 +68,20 @@ export const searchFormSchema: FormSchema[] = [
   {
     label: '应用',
     field: 'appId',
-    component: 'JDictSelectTag',
+    component: 'ApiSelect',
     componentProps: {
-      dictCode: 'app_base_info,name,id',
+      api: getAppList,
+      labelField: 'name',
+      valueField: 'id',
       placeholder: '请选择应用',
     },
-    colProps: { span: 6 },
+    
   },
   {
     field: 'name',
     label: '菜单名称',
     component: 'Input',
-    colProps: { span: 6 },
+    
   },
 ];
 
@@ -92,10 +95,11 @@ export const formSchema: FormSchema[] = [
   {
     label: '应用',
     field: 'appId',
-    component: 'JDictSelectTag',
-    required: true,
+    component: 'ApiSelect',
     componentProps: {
-      dictCode: 'app_base_info,name,id',
+      api: getAppList,
+      labelField: 'name',
+      valueField: 'id',
       placeholder: '请选择应用',
     },
   },