From 4aadec6f1fcd223e327ee642916f38e6e5a358d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=9D=BE?= <8605635+zhang3064194730@user.noreply.gitee.com> Date: Sat, 10 May 2025 10:18:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9D=83=E9=99=90=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../czg/controller/admin/RoleController.java | 16 ++- .../user/UserAuthorizationController.java | 2 +- .../main/java/com/czg/task/StatisticTask.java | 2 +- .../src/main/java/com/czg/sa/MyStpLogic.java | 9 +- .../com/czg/account/dto/menu/MenuAddDTO.java | 14 +++ .../account/dto/menu/MenuApiInfoItemDTO.java | 18 +++ .../com/czg/account/dto/menu/MenuEditDTO.java | 16 ++- .../account/dto/role/RolePermissionDTO.java | 26 +++++ .../java/com/czg/account/entity/SysMenu.java | 21 ++++ .../com/czg/account/entity/SysRolesMenus.java | 5 + .../czg/account/service/SysRoleService.java | 5 +- .../src/main/java/com/czg/LoadingRole.java | 54 ++++++++- .../impl/AuthorizationServiceImpl.java | 4 +- .../service/impl/PadProdServiceImpl.java | 1 + .../service/impl/SysMenuServiceImpl.java | 12 +- .../service/impl/SysRoleServiceImpl.java | 106 ++++++++++++++++-- .../impl/UserAuthorizationServiceImpl.java | 2 +- .../main/resources/mapper/SysMenuMapper.xml | 2 +- 18 files changed, 287 insertions(+), 28 deletions(-) create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuApiInfoItemDTO.java create mode 100644 cash-common/cash-common-service/src/main/java/com/czg/account/dto/role/RolePermissionDTO.java diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/RoleController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/RoleController.java index ebcabbae..c09767af 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/RoleController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/RoleController.java @@ -3,6 +3,7 @@ package com.czg.controller.admin; import com.czg.account.dto.PageDTO; import com.czg.account.dto.role.RoleAddDTO; import com.czg.account.dto.role.RoleEditDTO; +import com.czg.account.dto.role.RolePermissionDTO; import com.czg.account.dto.role.RoleRemoveDTO; import com.czg.account.entity.SysRole; import com.czg.account.service.SysRoleService; @@ -44,12 +45,13 @@ public class RoleController { * 获取角色对应的菜单 * 权限标识: role:menu * @param id 角色id + * @param type 0管理端 1收银机 * @return 分页数据 */ @SaAdminCheckPermission(value = "role:menu", name = "角色菜单") @GetMapping("/menu") - public CzgResult> getRoleMenu(@RequestParam Integer id) { - return CzgResult.success(roleService.getRoleMenu(StpKit.USER.getLoginIdAsLong(), id)); + public CzgResult> getRoleMenu(@RequestParam Integer id, @RequestParam Integer type) { + return CzgResult.success(roleService.getRoleMenu(StpKit.USER.getLoginIdAsLong(), id, type)); } /** @@ -64,6 +66,16 @@ public class RoleController { return CzgResult.success(roleService.add(roleAddDTO)); } + /** + * 权限编辑 + * @param rolePermissionDTO 权限编辑 + * @return 是否成功 + */ + @PutMapping("/permission") + public CzgResult editPermission(@RequestBody @Validated RolePermissionDTO rolePermissionDTO) { + return CzgResult.success(roleService.editPermission(StpKit.USER.getLoginIdAsLong(), rolePermissionDTO)); + } + /** * 编辑角色 * 权限标识: role:edit diff --git a/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java b/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java index f35ad652..f9fa49b3 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java @@ -76,7 +76,7 @@ public class UserAuthorizationController { */ @PostMapping("/test") public CzgResult login(@RequestParam long id) { - StpKit.USER.login(id, "2342", null, "", MyStpLogic.LoginType.USER, false); + StpKit.USER.login(id, "2342", null, "", MyStpLogic.LoginType.USER, false, ""); return CzgResult.success(StpKit.USER.getTokenValue()); } } diff --git a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java index b79d7979..fe7b2377 100644 --- a/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java +++ b/cash-api/order-server/src/main/java/com/czg/task/StatisticTask.java @@ -95,7 +95,7 @@ public class StatisticTask { LocalDate endDate = LocalDate.now(); List shopIdList = DbChain.table("tb_shop_info").select("id").objListAs(Long.class); List> split = CollUtil.split(shopIdList, 10); - // 1.清除历史统计的数据 +// 1.清除历史统计的数据 for (List splitIdList : split) { splitIdList.parallelStream().forEach(shopId -> { shopOrderStatisticMapper.deleteByQuery(QueryWrapper.create().eq(ShopOrderStatistic::getShopId, shopId)); diff --git a/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java b/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java index 722672b6..7f3bd85c 100644 --- a/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java +++ b/cash-common/cash-common-sa-token/src/main/java/com/czg/sa/MyStpLogic.java @@ -91,13 +91,14 @@ public class MyStpLogic { * @param loginType 登录类型枚举 * @param isAdmin 是否为管理员账号 */ - public void login(Long id, String account, Long shopId, String shopName, LoginType loginType, boolean isAdmin) { + public void login(Long id, String account, Long shopId, String shopName, LoginType loginType, boolean isAdmin, String platForm) { StpLogic logic = getLogic(); logic.login(id); if (loginType.equals(LoginType.MANAGER) && shopId == null) { throw new ApiNotPrintException("管理端登录必须传递店铺id"); } SaSession session = logic.getSession().set("userId", id).set("isAdmin", isAdmin).set("isManager", loginType.equals(LoginType.MANAGER)) + .set("platForm", platForm) .set("loginType", loginType).set("account", account); if (shopId != null) { session.set("shopId", shopId); @@ -107,6 +108,12 @@ public class MyStpLogic { } } + public String getPlatForm() { + StpLogic logic = getLogic(); + Object platForm = logic.getSession().get("platForm"); + return platForm instanceof String s ? s : ""; + } + public void reLogin(long id) { StpLogic logic = getLogic(); String token = logic.getTokenValue(); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuAddDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuAddDTO.java index 58c560e5..4f9af613 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuAddDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuAddDTO.java @@ -6,6 +6,8 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; +import java.util.List; + /** * @author Administrator */ @@ -64,4 +66,16 @@ public class MenuAddDTO { * 权限表示 */ private String permission; + /** + * 小程序页面路径 + */ + private String miniPath; + /** + * 小程序组件 + */ + private String miniComponent; + /** + * 接口路径支持通配符, 多个逗号分割 + */ + private List apiInfo; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuApiInfoItemDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuApiInfoItemDTO.java new file mode 100644 index 00000000..84eaf025 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuApiInfoItemDTO.java @@ -0,0 +1,18 @@ +package com.czg.account.dto.menu; + +import lombok.Data; + +/** + * @author Administrator + */ +@Data +public class MenuApiInfoItemDTO { + /** + * 请求方式 ALL, POST, GET, DELETE, PUT + */ + private String method; + /** + * 接口地址,支持通配符*和? + */ + private String url; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuEditDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuEditDTO.java index 41c9ae0c..5541cbba 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuEditDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/menu/MenuEditDTO.java @@ -6,6 +6,8 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; +import java.util.List; + /** * @author Administrator */ @@ -55,7 +57,19 @@ public class MenuEditDTO { */ private String activeMenu; /** - * 权限表示 + * 权限标识 */ private String permission; + /** + * 小程序页面路径 + */ + private String miniPath; + /** + * 小程序组件 + */ + private String miniComponent; + /** + * 接口路径支持通配符 + */ + private List apiInfo; } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/role/RolePermissionDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/role/RolePermissionDTO.java new file mode 100644 index 00000000..2d9ef679 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/role/RolePermissionDTO.java @@ -0,0 +1,26 @@ +package com.czg.account.dto.role; + +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.util.List; + +/** + * @author Administrator + */ +@Data +public class RolePermissionDTO { + /** + * 角色id + */ + @NotNull + private Long roleId; + /** + * 管理员菜单id + */ + List adminMenuIdList; + /** + * 收银机菜单id + */ + List cashMenuIdList; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysMenu.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysMenu.java index b989f75b..55063c0a 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysMenu.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysMenu.java @@ -131,4 +131,25 @@ public class SysMenu implements Serializable { */ private Long isShop; + /** + * 小程序页面路径 + */ + private String miniPath; + /** + * 小程序组件 + */ + private String miniComponent; + /** + * 包含的接口 + */ + private String apiInfo; + /** + * 接口地址 + */ + private String url; + /** + * 请求方式 + */ + private String method; + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysRolesMenus.java b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysRolesMenus.java index a7e13249..08946a76 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysRolesMenus.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/entity/SysRolesMenus.java @@ -37,4 +37,9 @@ public class SysRolesMenus implements Serializable { @Id private Long roleId; + /** + * 0 管理端及小程序 1收银机 + */ + private Integer type; + } diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/SysRoleService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/SysRoleService.java index 6209d38a..ac486b31 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/SysRoleService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/SysRoleService.java @@ -3,6 +3,7 @@ package com.czg.account.service; import com.czg.account.dto.PageDTO; import com.czg.account.dto.role.RoleAddDTO; import com.czg.account.dto.role.RoleEditDTO; +import com.czg.account.dto.role.RolePermissionDTO; import com.czg.account.entity.SysRole; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.service.IService; @@ -25,5 +26,7 @@ public interface SysRoleService extends IService { Boolean edit(RoleEditDTO roleEditDTO); - List getRoleMenu(long loginIdAsLong, Integer id); + List getRoleMenu(long loginIdAsLong, Integer id, Integer type); + + Boolean editPermission(long userId, RolePermissionDTO rolePermissionDTO); } diff --git a/cash-common/cash-common-tools/src/main/java/com/czg/LoadingRole.java b/cash-common/cash-common-tools/src/main/java/com/czg/LoadingRole.java index bb9ed214..286d96fe 100644 --- a/cash-common/cash-common-tools/src/main/java/com/czg/LoadingRole.java +++ b/cash-common/cash-common-tools/src/main/java/com/czg/LoadingRole.java @@ -10,6 +10,7 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.*; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @@ -32,6 +33,45 @@ public class LoadingRole implements CommandLineRunner { Method method = value.getMethod(); try { + Class controllerClass = method.getDeclaringClass(); + // 获取类上的 @RequestMapping 路径 + String classPath = ""; + if (controllerClass.isAnnotationPresent(RequestMapping.class)) { + RequestMapping classMapping = controllerClass.getAnnotation(RequestMapping.class); + classPath = classMapping.value().length > 0 ? classMapping.value()[0] : ""; + } + + // 获取方法上的注解路径和请求方式 + String methodPaths = ""; + String httpMethod = "UNKNOWN"; + + if (method.isAnnotationPresent(GetMapping.class)) { + GetMapping mapping = method.getAnnotation(GetMapping.class); + methodPaths = mapping.value().length > 0 ? mapping.value()[0] : ""; + httpMethod = "GET"; + } else if (method.isAnnotationPresent(PostMapping.class)) { + PostMapping mapping = method.getAnnotation(PostMapping.class); + methodPaths = mapping.value().length > 0 ? mapping.value()[0] : ""; + httpMethod = "POST"; + } else if (method.isAnnotationPresent(PutMapping.class)) { + PutMapping mapping = method.getAnnotation(PutMapping.class); + methodPaths = mapping.value().length > 0 ? mapping.value()[0] : ""; + httpMethod = "PUT"; + } else if (method.isAnnotationPresent(DeleteMapping.class)) { + DeleteMapping mapping = method.getAnnotation(DeleteMapping.class); + methodPaths = mapping.value().length > 0 ? mapping.value()[0] : ""; + httpMethod = "DELETE"; + } else if (method.isAnnotationPresent(RequestMapping.class)) { + RequestMapping mapping = method.getAnnotation(RequestMapping.class); + methodPaths = mapping.value().length > 0 ? mapping.value()[0] : ""; + RequestMethod[] methods = mapping.method(); + httpMethod = methods.length > 0 ? methods[0].name() : "ALL"; + } + + // 拼接路径并输出 + String fullPath = (classPath + "/" + methodPaths).replaceAll("//+", "/"); + + // 使用反射获取注解(不 import SaAdminCheckPermission) Class annotationClass = Class.forName("com.czg.annotation.SaAdminCheckPermission"); Object annotation = AnnotationUtils.getAnnotation(method, (Class) annotationClass); @@ -51,6 +91,8 @@ public class LoadingRole implements CommandLineRunner { if (menu1 != null) { Long menuId = menu1.getLong("menu_id"); String title = menu1.getString("title"); + String url = menu1.getString("url"); + String method1 = menu1.getString("method"); String permission = menu1.getString("permission"); String listSql = "select * from sys_roles_menus where menu_id=? and role_id=?"; List count1 = Db.selectListBySql(listSql, menuId, 1L); @@ -61,17 +103,17 @@ public class LoadingRole implements CommandLineRunner { log.info("接口菜单添加成功, 菜单名称: {}, 菜单权限: {}", title, permission); } - if (StrUtil.isNotBlank(permissionName) && (title == null || !title.equals(permissionName))) { - sql = "update sys_menu set title=? where menu_id=?"; - Db.updateBySql(sql, permissionName, menuId); + if (!title.equals(permissionName) || !fullPath.equals(url) || !httpMethod.equals(method1)) { + sql = "update sys_menu set title=?, url=?, method=? where menu_id=?"; + Db.updateBySql(sql, permissionName, fullPath, httpMethod, menuId); log.info("接口菜单修改成功, 旧名称: {}, 新菜单名称: {}", title, permissionName); } continue; } - sql = "INSERT INTO `czg_cashier`.`sys_menu` ( `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`, `path`, `i_frame`, `cache`, `hidden`, `permission`, `create_by`, `update_by`, `create_time`, `update_time`, `active_menu`, `is_shop`) VALUES " + - "(0, 2, ?, NULL, '', 2, '', '', b'0', b'0', b'0', ?, NULL, NULL, ?, NULL, NULL, 0);"; - Db.insertBySql(sql, StrUtil.isNotBlank(permissionName) ? permissionName : s, s, DateUtil.date()); + sql = "INSERT INTO `czg_cashier`.`sys_menu` ( `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`, `path`, `i_frame`, `cache`, `hidden`, `permission`, `create_by`, `update_by`, `create_time`, `update_time`, `active_menu`, `is_shop`, 'url', 'method') VALUES " + + "(0, 2, ?, NULL, '', 2, '', '', b'0', b'0', b'0', ?, NULL, NULL, ?, NULL, NULL, 0, ?, ?);"; + Db.insertBySql(sql, StrUtil.isNotBlank(permissionName) ? permissionName : s, s, DateUtil.date(), fullPath, httpMethod); sql = "select * from sys_menu where permission=?"; Row info = Db.selectOneBySql(sql, s); Long menuId = info.getLong("menu_id"); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java index 849bc8e3..27f3805b 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/AuthorizationServiceImpl.java @@ -148,7 +148,7 @@ public class AuthorizationServiceImpl implements AuthorizationService { if (!isAllowAccountLogin) { throw new ApiNotPrintException("当前分店账号被禁止登录"); } - StpKit.USER.login(user.getId(), user.getAccount(), shopInfo.getId(), shopInfo.getShopName(), isStaff ? MyStpLogic.LoginType.STAFF : MyStpLogic.LoginType.MANAGER, user.getIsAdmin()); + StpKit.USER.login(user.getId(), user.getAccount(), shopInfo.getId(), shopInfo.getShopName(), isStaff ? MyStpLogic.LoginType.STAFF : MyStpLogic.LoginType.MANAGER, user.getIsAdmin(), platType); // 查询角色 List roleList = sysRoleService.getByUserId(user.getId()); List roleNames = roleList.stream().map(SysRole::getName).collect(Collectors.toList()); @@ -156,7 +156,7 @@ public class AuthorizationServiceImpl implements AuthorizationService { roleNames.add("admin"); } // 权限赋予 - List promissionList = sysMenuMapper.selectByUserId(user.getId(), null).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).collect(Collectors.toList()); + List promissionList = sysMenuMapper.selectByUserId(user.getId(), "PC".equals(platType) ? 1 : 0).stream().map(SysMenu::getPermission).filter(StrUtil::isNotBlank).collect(Collectors.toList()); // 加入员工权限 if (shopStaffPromissionList != null && !shopStaffPromissionList.isEmpty()) { promissionList.addAll(shopStaffPromissionList); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PadProdServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PadProdServiceImpl.java index 200dae8b..664cccb0 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PadProdServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PadProdServiceImpl.java @@ -124,6 +124,7 @@ public class PadProdServiceImpl implements PadProdService { return padDetailDTO; } + @Override public Boolean add(Long shopId, PadDetailAddDTO padDetailAddDTO) { long count = shopProdCategoryService.count(new QueryWrapper().eq(ShopProdCategory::getId, padDetailAddDTO.getProductCategoryId())); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java index 456b2157..b4238750 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysMenuServiceImpl.java @@ -3,6 +3,7 @@ package com.czg.service.account.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONObject; import com.czg.account.dto.menu.MenuAddDTO; import com.czg.account.dto.menu.MenuEditDTO; import com.czg.account.entity.SysMenu; @@ -38,7 +39,7 @@ public class SysMenuServiceImpl extends ServiceImpl impl @Override public List getMenu() { long sysUserId = StpKit.USER.getLoginIdAsLong(); - List allMenus = mapper.selectByUserId(sysUserId, null); + List allMenus = mapper.selectByUserId(sysUserId, "PC".equals(StpKit.USER.getPlatForm()) ? 1 : 0); List roleList = sysUsersRolesMapper.selectListByQuery(query().select(SysUsersRoles::getRoleId).eq(SysUsersRoles::getUserId, sysUserId)); List roleIdList = roleList.stream().map(SysUsersRoles::getRoleId).toList(); Long shopId = StpKit.USER.getShopId(0L); @@ -98,7 +99,11 @@ public class SysMenuServiceImpl extends ServiceImpl impl if (menuAddDTO.getType() == 3 && menuAddDTO.getPermission() == null) { throw new ApiNotPrintException("权限不为空"); } - return save(BeanUtil.copyProperties(menuAddDTO, SysMenu.class)); + SysMenu sysMenu = BeanUtil.copyProperties(menuAddDTO, SysMenu.class); + if (menuAddDTO.getApiInfo() != null && !menuAddDTO.getApiInfo().isEmpty()) { + sysMenu.setApiInfo(JSONObject.toJSONString(menuAddDTO.getApiInfo())); + } + return save(sysMenu); } @Override @@ -109,6 +114,9 @@ public class SysMenuServiceImpl extends ServiceImpl impl throw new ApiNotPrintException("菜单不存在"); } BeanUtil.copyProperties(menuEditDTO, menu); + if (menuEditDTO.getApiInfo() != null && !menuEditDTO.getApiInfo().isEmpty()) { + menu.setApiInfo(JSONObject.toJSONString(menuEditDTO.getApiInfo())); + } return updateById(menu); } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java index d55b4dc5..917aef03 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/SysRoleServiceImpl.java @@ -3,9 +3,12 @@ package com.czg.service.account.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSONArray; import com.czg.account.dto.PageDTO; +import com.czg.account.dto.menu.MenuApiInfoItemDTO; import com.czg.account.dto.role.RoleAddDTO; import com.czg.account.dto.role.RoleEditDTO; +import com.czg.account.dto.role.RolePermissionDTO; import com.czg.account.entity.SysMenu; import com.czg.account.entity.SysRole; import com.czg.account.entity.SysRolesMenus; @@ -24,6 +27,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import static com.mybatisflex.core.query.QueryMethods.column; @@ -45,6 +49,48 @@ public class SysRoleServiceImpl extends ServiceImpl imp return mapper.selectByUserId(id); } + /** + * 将单个路径通配符转为 SQL LIKE 模式 + */ + public static String toSqlLikePattern(String pathPattern) { + if (pathPattern == null) return null; + + // 转义 SQL 特殊字符 + String escaped = pathPattern + .replace("\\", "\\\\") + .replace("_", "\\_") + .replace("%", "\\%"); + + // 替换 ** 为占位,避免被 * 干扰 + String placeholder = "@@DOUBLE_STAR@@"; + escaped = escaped.replace("**", placeholder); + + // 替换 * 为单层路径匹配 + escaped = escaped.replace("*", "%"); + + // 替换 ? 为单字符匹配 + escaped = escaped.replace("?", "_"); + + // 替换回 ** + escaped = escaped.replace(placeholder, "%"); + + return escaped; + } + + /** + * 拼接多个路径通配符为 SQL OR 条件(适用于 MyBatis-Plus apply) + */ + public static String buildLikeSql(List apiInfoItemDTOS, String columnName) { + // 永不成立 + if (apiInfoItemDTOS == null || apiInfoItemDTOS.isEmpty()) { + return "1 = 0"; + } + + return apiInfoItemDTOS.stream() + .map(pattern -> StrUtil.format("({} LIKE '{}' ESCAPE '\\\\' and method = '{}')" , columnName, toSqlLikePattern(pattern.getUrl()), pattern.getMethod())) + .collect(Collectors.joining(" OR ")); + } + @Override public Page getList(Long shopId, PageDTO pageDTO, String key, String startTime, String endTime) { QueryWrapper queryWrapper = new QueryWrapper(); @@ -70,27 +116,69 @@ public class SysRoleServiceImpl extends ServiceImpl imp } @Override - public List getRoleMenu(long userId, Integer id) { + public List getRoleMenu(long userId, Integer id, Integer type) { SysRole role = queryChain().eq(SysRole::getId, id).eq(SysRole::getCreateUserId, userId).one(); if (role == null) { throw new ApiNotPrintException("角色不存在"); } - return sysRolesMenusService.queryChain().eq(SysRolesMenus::getRoleId, id).list().stream().map(SysRolesMenus::getMenuId).toList(); + return sysRolesMenusService.queryChain().eq(SysRolesMenus::getRoleId, id).eq(SysRolesMenus::getType, type).list().stream().map(SysRolesMenus::getMenuId).toList(); } - public boolean addMenu(Long roleId, List menuIds) { - long count = sysMenuService.queryChain().in(SysMenu::getMenuId, menuIds).count(); - if (count != menuIds.size()) { + public boolean addMenu(Long roleId, List menuIds, boolean isAdmin) { + List sysMenuList = sysMenuService.queryChain().in(SysMenu::getMenuId, menuIds).list(); + if (sysMenuList.size() != menuIds.size()) { throw new ApiNotPrintException("菜单id包含错误id"); } + ArrayList apiPathList = new ArrayList<>(); + sysMenuList.forEach(item -> { + if (StrUtil.isNotBlank(item.getApiInfo())) { + List itemDTOS = JSONArray.parseArray(item.getApiInfo()).toJavaList(MenuApiInfoItemDTO.class); + if (!itemDTOS.isEmpty()) { + apiPathList.addAll(itemDTOS); + } + } + }); + + if (!apiPathList.isEmpty()) { + String string = buildLikeSql(apiPathList, "url"); + QueryWrapper wrapper = new QueryWrapper(); + wrapper.where(string); + List sysMenus = sysMenuService.list(wrapper); + if (!sysMenus.isEmpty()) { + sysMenuList.addAll(sysMenus); + } + } + ArrayList rolesMenus = new ArrayList<>(); - for (Long id : menuIds) { - rolesMenus.add(new SysRolesMenus(id, roleId)); + for (SysMenu sysMenu : sysMenuList) { + long count = sysRolesMenusService.count(new QueryWrapper().eq(SysRolesMenus::getMenuId, sysMenu.getMenuId()) + .eq(SysRolesMenus::getRoleId, roleId) + .eq(SysRolesMenus::getType, isAdmin ? 0 : 1)); + if (count == 0) { + rolesMenus.add(new SysRolesMenus(sysMenu.getMenuId(), roleId, isAdmin ? 0 : 1)); + } } return sysRolesMenusService.saveBatch(rolesMenus); } + @Override + public Boolean editPermission(long userId, RolePermissionDTO rolePermissionDTO) { + long count = count(new QueryWrapper().eq(SysRole::getId, rolePermissionDTO.getRoleId()).eq(SysRole::getCreateUserId, userId)); + if (count == 0) { + throw new ApiNotPrintException("角色不存在"); + } + + if (rolePermissionDTO.getAdminMenuIdList() != null && !rolePermissionDTO.getAdminMenuIdList().isEmpty()) { + addMenu(rolePermissionDTO.getRoleId(), rolePermissionDTO.getAdminMenuIdList(), true); + } + + if (rolePermissionDTO.getCashMenuIdList() != null && !rolePermissionDTO.getCashMenuIdList().isEmpty()) { + addMenu(rolePermissionDTO.getRoleId(), rolePermissionDTO.getCashMenuIdList(), false); + } + return true; + } + @Override @Transactional(rollbackFor = Exception.class) public Boolean add(RoleAddDTO roleAddDTO) { @@ -110,7 +198,7 @@ public class SysRoleServiceImpl extends ServiceImpl imp sysRole.setCreateTime(DateUtil.date().toLocalDateTime()); boolean save = save(sysRole); if (save) { - return addMenu(sysRole.getId(), roleAddDTO.menuIdList()); + return addMenu(sysRole.getId(), roleAddDTO.menuIdList(), true); } throw new ApiNotPrintException("保存失败"); @@ -134,7 +222,7 @@ public class SysRoleServiceImpl extends ServiceImpl imp boolean b = updateById(role); if (b) { sysRolesMenusService.updateChain().eq(SysRolesMenus::getRoleId, role.getId()).remove(); - return addMenu(role.getId(), roleEditDTO.getMenuIdList()); + return addMenu(role.getId(), roleEditDTO.getMenuIdList(), true); } throw new ApiNotPrintException("保存失败"); } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java index 0789aab1..df63b805 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java @@ -117,7 +117,7 @@ public class UserAuthorizationServiceImpl implements UserAuthorizationService { userInfo.setLastLoginTime(DateUtil.date().toLocalDateTime()); userInfoService.saveOrUpdate(userInfo); // StpKit.USER.login(userInfo.getId()); - StpKit.USER.login(userInfo.getId(), openId, null, null, MyStpLogic.LoginType.USER, false); + StpKit.USER.login(userInfo.getId(), openId, null, null, MyStpLogic.LoginType.USER, false, "userMini"); return new LoginTokenDTO(StpKit.USER.getTokenValue(), userInfo); } } diff --git a/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml b/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml index 707b09fa..aac89845 100644 --- a/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml +++ b/cash-service/account-service/src/main/resources/mapper/SysMenuMapper.xml @@ -11,7 +11,7 @@ left join sys_menu as c on c.menu_id = b.menu_id where a.user_id = #{userId} and c.menu_id is not null - and c.type=#{type} + and b.type=#{type} order by menu_sort desc