9 Incheckningar 2235567aca ... 972130ab48

Upphovsman SHA1 Meddelande Datum
  ZL 972130ab48 Merge branch 'ZL' into dev 2 månader sedan
  ZL 0a59047233 菜单管理应用隔离接口修改,样式修改 2 månader sedan
  danch d6e017e81f 高级查询代码优化 2 månader sedan
  ZL 528b325b18 list别名 2 månader sedan
  ZL a7b024b86e 授权表单改为模糊搜索 2 månader sedan
  ZL 650302ed14 Merge branch 'ZL' into dev 2 månader sedan
  ZL fa308a131a 角色列表list接口废弃修改 2 månader sedan
  ZL b95b4270a9 Merge branch 'ZL' into dev 2 månader sedan
  ZL a2ca7b23b2 问题修改1数据规则可清空2数据权限查询添加用户独立权限 2 månader sedan
15 ändrade filer med 405 tillägg och 318 borttagningar
  1. 14 4
      jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java
  2. 11 5
      jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java
  3. 12 10
      jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysPermissionDataRuleMapper.xml
  4. 1 1
      jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/ISysPermissionService.java
  5. 4 5
      jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/AppmanageServiceImpl.java
  6. 12 8
      jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java
  7. 1 1
      jeecgboot-vue3/src/api/common/api.ts
  8. 10 10
      jeecgboot-vue3/src/components/Lttc/BaseService/LTTCBaseServiceAdvancedSearch.vue
  9. 2 2
      jeecgboot-vue3/src/views/baseservice/advancedSearch/AdvancedSearchList.vue
  10. 28 6
      jeecgboot-vue3/src/views/system/menu/components/DataRuleDrawer.vue
  11. 11 5
      jeecgboot-vue3/src/views/system/menu/components/PermissionLeftTable.vue
  12. 238 224
      jeecgboot-vue3/src/views/system/menu/menu/index.vue
  13. 12 8
      jeecgboot-vue3/src/views/system/menu/menu/menu.data.ts
  14. 25 7
      jeecgboot-vue3/src/views/system/role/index.vue
  15. 24 22
      jeecgboot-vue3/src/views/system/role/role.data.ts

+ 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<>();
 
 			//如果有菜单名查询条件,则平铺数据 不做上下级

+ 11 - 5
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/SysRoleController.java

@@ -29,6 +29,7 @@ import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
 import org.jeecg.modules.base.service.BaseCommonService;
 import org.jeecg.modules.system.entity.*;
+import org.jeecg.modules.system.entity.AppmanageEntity.AppBaseInfo;
 import org.jeecg.modules.system.model.TreeModel;
 import org.jeecg.modules.system.service.*;
 import org.jeecg.modules.system.vo.SysUserRoleCountVo;
@@ -98,12 +99,13 @@ public class SysRoleController {
 	 * @param req
 	 * @return
 	 */
-	@RequiresPermissions("system:role:list")
+//	@RequiresPermissions("system:role:list")
 	@RequestMapping(value = "/list", method = RequestMethod.GET)
 	public Result<IPage<SysRole>> queryPageList(SysRole role,
 									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
 									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
 									  HttpServletRequest req) {
+		log.info("----------此接口已废弃-------请改用listByApp接口----------------------");
 		Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
 		//QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
 		//IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
@@ -122,7 +124,7 @@ public class SysRoleController {
 	 * @param req
 	 * @return
 	 */
-	@RequiresPermissions("system:role:list")
+//	@RequiresPermissions("system:role:list")
 	@PermissionData
 	@RequestMapping(value = "/listByApp", method = RequestMethod.GET)
 	public Result<IPage<SysRole>> listByApp(SysRole role,
@@ -131,13 +133,17 @@ public class SysRoleController {
 												HttpServletRequest req) {
 
 		Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
-		if (role.getAppId().isEmpty()){
+		String appId = role.getAppId();
+		LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+		Boolean isAdmin = loginUser.getUsername().equals("admin");
+		if (appId==null && !isAdmin){
 			result.setSuccess(true);
 			result.setResult(new Page<SysRole>());
+			return result;
 		}
 		QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
-		String s = QueryGenerator.installAuthJdbc(SysRole.class);
-		queryWrapper.orderByDesc("create_time");
+
+//		queryWrapper.orderByDesc("create_time");
 		Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
 		IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
 

+ 12 - 10
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/SysPermissionDataRuleMapper.xml

@@ -11,16 +11,18 @@
 			join sys_user_role d on d.role_id = c.id
 			join sys_user e on d.user_id = e.id
 			where e.username = #{username} and b.id =  #{permissionId}
-		<!--update begin Author:lvdandan  Date:20200213 for:加入部门权限 -->
-		union
-		select data_rule_ids
-			from sys_depart_role_permission a
-			join sys_permission b on a.permission_id = b.id
-			join sys_depart_role c on a.role_id = c.id
-			join sys_depart_role_user d on d.drole_id = c.id
-			join sys_user e on d.user_id = e.id
-			where e.username = #{username} and b.id = #{permissionId}
-		<!--update end Author:lvdandan  Date:20200213 for:加入部门权限 -->
+
+		<!-- 修改为加入用户独立数据权限 -->
+		UNION
+		SELECT
+		data_rule_ids
+		FROM
+		sys_user_permission a
+		JOIN sys_permission b ON a.permission_id = b.id
+		JOIN sys_user e ON a.user_id = e.id
+		WHERE
+		e.username = #{username} and b.id =  #{permissionId}
+		<!-- 修改为加入用户独立数据权限 -->
 	</select>
 
 </mapper>

+ 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);
 
 	/**
      * 真实删除

+ 4 - 5
jeecg-boot/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/service/impl/AppmanageServiceImpl.java

@@ -653,18 +653,17 @@ public class AppmanageServiceImpl implements AppmanageService {
     public List<AppBaseInfo> appList() {
         String sql = QueryGenerator.installAuthJdbc(AppBaseInfo.class);
         //对sql进行处理避免注入
-        StringBuilder inSql = new StringBuilder("AND id IN (");
-        System.out.println("sql----------------------->"
-                +sql);
         if (sql.startsWith(" and id in (")&& sql.endsWith(")")){
+            StringBuilder inSql = new StringBuilder("AND id IN (");
             String inClause = sql.substring(" and id in (".length(), sql.length() - 1);
             List<String> ids = Arrays.asList(inClause.split(","));
             if (!ids.isEmpty()){
                 ids.forEach(id -> inSql.append(id).append(","));
                 inSql.deleteCharAt(inSql.length() - 1);
             }else inSql.append(inClause);
+            inSql .append(") ");
+            return baseInfoMapper.appList(inSql.toString());
         }
-        inSql .append(") ");
-        return baseInfoMapper.appList(inSql.toString());
+        return baseInfoMapper.appList("");
     }
 }

+ 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+";

+ 1 - 1
jeecgboot-vue3/src/api/common/api.ts

@@ -6,7 +6,7 @@ const baseUploadUrl = globSetting.uploadUrl;
 enum Api {
   positionList = '/sys/position/list',
   userList = '/sys/user/list',
-  roleList = '/sys/role/list',
+  roleList = '/sys/role/listByApp',
   queryDepartTreeSync = '/sys/sysDepart/queryDepartTreeSync',
   queryTreeList = '/sys/sysDepart/queryTreeList',
   loadTreeData = '/sys/category/loadTreeData',

+ 10 - 10
jeecgboot-vue3/src/components/Lttc/BaseService/LTTCBaseServiceAdvancedSearch.vue

@@ -5,7 +5,7 @@
       <template #header>
         高级查询方案:
         <a-button type="link" v-for="(item, index) in savedQueries.slice(0, visibleCount)"
-                  :key="index" @click.stop="() => handleQueryNameClick(item)">
+                  :key="index" @click.stop="() => handleQueryNameClick(item)"  @dblclick.stop="resetQuery">
           {{ truncateText(item.queryName) }}
         </a-button>
         <a-button type="link" v-if="savedQueries.length > visibleCount" @click.stop="quickQuery">更多
@@ -18,7 +18,7 @@
 
             <!-- 查询模式选择 -->
             <a-col :span="3">
-              <a-form-item>
+              <a-form-item style="width:90%">
                 <a-select v-model:value="query.mode" placeholder="请选择查询模式">
                   <a-select-option v-for="mode in modeOptions" :key="mode.value"
                                    :value="mode.value">
@@ -29,7 +29,7 @@
             </a-col>
             <!-- 查询列选择 -->
             <a-col :span="6">
-              <a-form-item>
+              <a-form-item  style="width:90%">
                 <a-select v-model:value="query.column" class="a-select" placeholder="请选择查询列">
                   <a-select-option class="a-select" v-for="col in fieldOptions" :key="col.value"
                                    :value="col.value">
@@ -40,7 +40,7 @@
             </a-col>
             <!-- 查询条件选择 -->
             <a-col :span="3">
-              <a-form-item>
+              <a-form-item  style="width:90%">
                 <a-select v-model:value="query.condition" placeholder="请选择查询条件"
                           class="a-select">
                   <a-select-option class="a-select" v-for="condition in conditionOptions"
@@ -53,7 +53,7 @@
             </a-col>
             <!-- 查询内容输入,根据列的类型显示不同的输入控件 -->
             <a-col :span="6">
-              <a-form-item>
+              <a-form-item  style="width:90%">
                 <template v-if="getColumnType(query.column).toLowerCase() === 'date'">
                   <a-date-picker v-model:value="query.term" format="YYYY-MM-DD"
                                  placeholder="请选择日期"/>
@@ -79,18 +79,18 @@
             <!-- 添加和删除查询条件按钮 -->
             <a-col :span="6">
               <a-form-item>
-                <a-button v-if="queries.length > 1" @click="removeQuery(index)" type="danger">删除
+                <a-button v-if="queries.length > 1" @click="removeQuery(index)" type="danger" style="margin-right: 1vh">删除
                 </a-button>
-                <a-button @click="addQuery" type="primary">添加</a-button>
+                <a-button @click="addQuery" type="primary"  style="margin-right: 1vh">添加</a-button>
               </a-form-item>
             </a-col>
           </a-row>
         </div>
         <!-- 提交、保存和加载查询条件按钮 -->
         <a-form-item>
-          <a-button @click="resetQuery" type="default">重置</a-button>
-          <a-button type="primary" html-type="submit">查询</a-button>
-          <a-button @click="showModal" type="default">保存</a-button>
+          <a-button @click="resetQuery" type="default" style="margin-right: 1vh">重置</a-button>
+          <a-button type="primary" html-type="submit"  style="margin-right: 1vh">查询</a-button>
+          <a-button @click="showModal" type="default"  style="margin-right: 1vh">保存</a-button>
         </a-form-item>
       </a-form>
       <!--查询高级查询方案-->

+ 2 - 2
jeecgboot-vue3/src/views/baseservice/advancedSearch/AdvancedSearchList.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <div>
+    <a-card :bordered="false">
       <a-row>
         <a-col :span="12">
           <LTTCBaseServiceAdvancedSearch
@@ -17,7 +17,7 @@
           />
         </a-col>
       </a-row>
-    </div>
+    </a-card>
     <!--引用表格-->
     <BasicTable @register="registerTable" :rowSelection="rowSelection">
       <!--插槽:table标题-->

+ 28 - 6
jeecgboot-vue3/src/views/system/menu/components/DataRuleDrawer.vue

@@ -10,7 +10,17 @@
 
             <a-col :span="24">
               <div style="width: 100%; margin-top: 15px">
-                <a-button @click="saveDataRuleForRole" type="primary" size="small"> <Icon icon="ant-design:save-outlined"></Icon>点击保存</a-button>
+                <a-popconfirm
+                  title="请注意,现未勾选任何数据权限!"
+                  :open="visible"
+                  @confirm="saveDataRuleForRole"
+                  @cancel="cancel"
+                  @openChange="handleVisibleChange"
+                >
+                <a-button  type="primary" size="small"> <Icon icon="ant-design:save-outlined"></Icon>点击保存</a-button>
+
+                  </a-popconfirm
+                >
               </div>
             </a-col>
           </a-row>
@@ -34,6 +44,10 @@ const selectId = ref('');
 const dataRuleList = ref([]);
 const dataRuleChecked = ref([]);
 const ruleType = ref('');
+const visible = ref<boolean>(false);
+const cancel = () => {
+  visible.value = false;
+};
 /**
  * 数据
  */
@@ -44,8 +58,8 @@ const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (
   functionId.value = data.functionId;
   //角色的id
   selectId.value = data.selectId;
-
   ruleType.value = data.ruleType;
+  visible.value = false;
 
   try {
     let params;
@@ -83,10 +97,7 @@ function reset() {
  * 提交
  */
 async function saveDataRuleForRole() {
-  if (!unref(dataRuleChecked) || unref(dataRuleChecked).length == 0) {
-    createMessage.warning('请注意,现未勾选任何数据权限!');
-    return;
-  }
+  visible.value = false;
   if (!unref(selectId)) {
     createMessage.warning('请先选择配置对象!');
     return;
@@ -111,4 +122,15 @@ async function saveDataRuleForRole() {
   //刷新列表
   emit('success');
 }
+
+const handleVisibleChange = (bool: boolean) => {
+  if(!bool){
+    visible.value = false;
+  }
+  if (!unref(dataRuleChecked) || unref(dataRuleChecked).length == 0 ) {
+    visible.value = true;
+  }else{
+    saveDataRuleForRole();
+  }
+};
 </script>

+ 11 - 5
jeecgboot-vue3/src/views/system/menu/components/PermissionLeftTable.vue

@@ -13,9 +13,9 @@ import type { SelectProps } from 'ant-design-vue';
 import { BasicTable, useTable } from '/@/components/Table';
 // import { JSelectInput } from '/@/components/Form';
 import { useListPage } from '/@/hooks/system/useListPage';
-import { list as roleList } from '../../role/role.api';
+import { list as getroleList } from '../../role/role.api';
 import { roleColumns, userColumns, roleSchema, userSchema } from '../permission/permission.data';
-import { list as userList } from '../../user/user.api';
+import { listNoCareTenant as getuserList } from '../../user/user.api';
 // import AppSelect from './AppSelect.vue';
 
 const props = defineProps({
@@ -37,7 +37,7 @@ type Key = string | number;
 const appList = ref<SelectProps['options']>([]);
 const handleClick = () => {
   emit('update:clickParam', { ...props.clickParam, appId: appId.value });
-  setProps({ api: appId.value ? (tabType.value === 'role' ? roleList : userList) : undefined, dataSource: appId.value ? undefined : [] });
+  setProps({ api: appId.value ? (tabType.value === 'role' ? getroleList : getuserList) : undefined, dataSource: appId.value ? undefined : [] });
   reload();
 };
 
@@ -47,8 +47,7 @@ watch(tabType, () => deleteSelect());
 // 列表页面公共参数、方法
 const { prefixCls, tableContext } = useListPage({
   tableProps: {
-    // api: tabType.value === 'role' ? roleList : userList,
-    api: appId.value ? (tabType.value === 'role' ? roleList : userList) : undefined,
+    api: appId.value ? (tabType.value === 'role' ? getroleList : getuserList) : undefined,
     dataSource: appId.value ? undefined : [],
     columns: tabType.value === 'role' ? roleColumns : userColumns,
     size: 'small',
@@ -62,6 +61,13 @@ const { prefixCls, tableContext } = useListPage({
     tableSetting: { fullScreen: true },
     beforeFetch: (params) => {
       params.appId = appId.value;
+      //模糊查询
+      if(params.roleName){
+        params.roleName ='*'+ params.roleName.trim()+'*';
+      }
+      if(params.realname){
+        params.realname ='*'+ params.realname.trim()+'*';
+      }      
     },
     formConfig: {
       schemas: tabType.value === 'role' ? roleSchema : userSchema,

+ 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: '请选择应用',
     },
   },

+ 25 - 7
jeecgboot-vue3/src/views/system/role/index.vue

@@ -35,7 +35,7 @@
   <RoleIndexModal @register="registerIndexModal" />
 </template>
 <script lang="ts" name="system-role" setup>
-import { ref } from 'vue';
+import { ref, onMounted, watch } from 'vue';
 import { BasicTable, TableAction } from '/@/components/Table';
 import { useDrawer } from '/@/components/Drawer';
 import { useModal } from '/@/components/Modal';
@@ -45,7 +45,7 @@ import RolePermissionDrawer from './components/RolePermissionDrawer.vue';
 import RoleIndexModal from './components/RoleIndexModal.vue';
 import RoleUserTable from './components/RoleUserTable.vue';
 import { columns, searchFormSchema } from './role.data';
-import { list, deleteRole, batchDeleteRole, getExportUrl, getImportUrl } from './role.api';
+import { list as getrolelist, deleteRole, batchDeleteRole, getExportUrl, getImportUrl } from './role.api';
 import { appList } from '../menu/menu/menu.api';
 import { useListPage } from '/@/hooks/system/useListPage';
 const showFooter = ref(true);
@@ -54,15 +54,28 @@ const [registerDrawer, { openDrawer }] = useDrawer();
 const [registerIndexModal, { openModal: openIndexModal }] = useModal();
 const [rolePermissionDrawer, { openDrawer: openRolePermissionDrawer }] = useDrawer();
 const [registerDesc, { openDrawer: openRoleDesc }] = useDrawer();
+const isFirst = ref(true);
+const apps = ref([]);
+onMounted(async () => {
+  apps.value = await appList();
+});
+watch(() => apps.value,(newVal) => {
+    if (newVal.length > 0) {
+      reload();
+    }
+  }
+);
 
 // 列表页面公共参数、方法
 const { prefixCls, tableContext, onImportXls, onExportXls } = useListPage({
   designScope: 'role-template',
   tableProps: {
     title: '系统角色列表',
-    api: list,
+    api: getrolelist,
     columns: columns,
     striped: true,
+    immediate: false,
+    
     formConfig: {
       labelWidth: 65,
       rowProps: { gutter: 24 },
@@ -77,8 +90,14 @@ const { prefixCls, tableContext, onImportXls, onExportXls } = useListPage({
       column: 'createTime',
       order: 'desc',
     },
+    beforeFetch: async (params) => {
+      if (isFirst.value) {
+        params.appId = apps.value[0].id;
+        isFirst.value = false;
+      }
+    },
     afterFetch: async (record) => {
-      const app = await appList();
+      const app = apps.value;
       record.forEach((item) => {
         // 获取当前角色的appName
         const rightApp = app.find((m) => m.id === item.appId);
@@ -142,7 +161,7 @@ async function batchHandleDelete() {
  * 角色授权弹窗
  */
 function handlePerssion(record) {
-  openRolePermissionDrawer(true, { roleId: record.id,appId: record.appId,appName: record.appName });
+  openRolePermissionDrawer(true, { roleId: record.id, appId: record.appId, appName: record.appName });
 }
 /**
  * 首页配置弹窗
@@ -162,7 +181,7 @@ function handleUser(record) {
  */
 function getTableAction(record) {
   return [
-  {
+    {
       label: '授权',
       onClick: handlePerssion.bind(null, record),
     },
@@ -170,7 +189,6 @@ function getTableAction(record) {
       label: '分配用户',
       onClick: handleUser.bind(null, record),
     },
-    
   ];
 }
 

+ 24 - 22
jeecgboot-vue3/src/views/system/role/role.data.ts

@@ -1,6 +1,7 @@
 
 import { FormSchema } from '/@/components/Table';
 import { isRoleExist } from './role.api';
+import { appList } from '../menu/menu/menu.api';
 export const columns = [
   {
     title: '所属应用',
@@ -51,11 +52,12 @@ export const searchFormSchema: FormSchema[] = [
   {
     label: '应用',
     field: 'appId',
-    component: 'JDictSelectTag',
+    component: 'ApiSelect',
     componentProps: {
-      dictCode: 'app_base_info,name,id',
+      api: appList,
+      labelField: 'name',
+      valueField: 'id',
       placeholder: '请选择应用',
-      
     },
     colProps: { span: 6 },
   },
@@ -92,11 +94,11 @@ export const searchUserFormSchema: FormSchema[] = [
     field: 'deptId',
     label: '部门',
     component: 'JSelectDept',
-    componentProps:{
-      labelKey:'departName',
-      multiple:false,
-      rowKey:'id'
-  },
+    componentProps: {
+      labelKey: 'departName',
+      multiple: false,
+      rowKey: 'id'
+    },
     colProps: { span: 15 },
   },
 ];
@@ -114,11 +116,11 @@ export const searchUsermodelSchema: FormSchema[] = [
     field: 'deptId',
     label: '部门',
     component: 'JSelectDept',
-    componentProps:{
-      labelKey:'departName',
-      multiple:false,
-      rowKey:'id'
-  },
+    componentProps: {
+      labelKey: 'departName',
+      multiple: false,
+      rowKey: 'id'
+    },
     colProps: { span: 12, },
   },
   {
@@ -127,17 +129,17 @@ export const searchUsermodelSchema: FormSchema[] = [
     component: 'Input',
     colProps: { span: 12 },
   },
-  
+
 ];
 
 export const onCleanCode = (formRef: any) => {
   console.log('cleanCode');
-  console.log('formRef.value',formRef);
+  console.log('formRef.value', formRef);
   if (formRef) {
     formRef.setFieldsValue({
       roleCode: '',
     })
-    console.log('formRef.value',formRef.validate);
+    console.log('formRef.value', formRef.validate);
 
   }
 };
@@ -161,7 +163,7 @@ export const formSchema: FormSchema[] = [
         onCleanCode();
       },
     },
-    
+
   },
 
   {
@@ -175,14 +177,14 @@ export const formSchema: FormSchema[] = [
     label: '角色编码',
     required: true,
     component: 'Input',
-    componentProps: {placeholder: '请先选择应用'},
-    
+    componentProps: { placeholder: '请先选择应用' },
+
     dynamicDisabled: ({ values }) => {
       return !values.appId;
     },
     dynamicRules: ({ values, model }) => {
       console.log('values:', values);
-      
+
       return [
         {
           required: true,
@@ -190,14 +192,14 @@ export const formSchema: FormSchema[] = [
             if (!value) {
               return Promise.reject('请输入角色编码');
             }
-            
+
             if (values) {
               // console.log('values:', values.appId);
               // if (!values.appId) {
               //   return Promise.reject('请先选择应用');
               // }
               return new Promise((resolve, reject) => {
-                isRoleExist({ id: model.id, roleCode: value ,appId:model.appId})
+                isRoleExist({ id: model.id, roleCode: value, appId: model.appId })
                   .then((res) => {
                     res.success ? resolve() : reject(res.message || '校验失败');
                   })