From fe30345045d25a218ab4f73b6afdbbcd979ae4de Mon Sep 17 00:00:00 2001 From: caojia <1301869380@qq.com> Date: Tue, 27 Oct 2026 15:28:52 +0800 Subject: [PATCH] =?UTF-8?q?Revert=20":sparkles:=20=E5=BA=94=E6=94=B6?= =?UTF-8?q?=E8=B4=A6=E5=8D=95=E6=8E=A5=E5=85=A5=E8=A7=92=E8=89=B2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90=E5=B9=B6=E5=90=8C=E6=AD=A5=E5=9C=A8?= =?UTF-8?q?=E7=BA=BF=E7=BC=93=E5=AD=98"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4659c63ef94799227852cdc069bed22d7e19e0ca. --- .../controller/system/SysRoleController.java | 8 +- .../java/com/bms/ar/ArBillDataScopeTest.java | 378 ------------------ .../system/SysRoleDataScopeRefreshTest.java | 68 ---- .../framework/web/service/TokenService.java | 12 - .../ar/mapper/ArBillGenerateTaskMapper.java | 4 +- .../com/bms/ar/mapper/ArBillLogMapper.java | 3 +- .../java/com/bms/ar/mapper/ArBillMapper.java | 4 - .../ar/service/ArBillDataScopeService.java | 82 ---- .../ar/service/impl/ArBillLogServiceImpl.java | 6 +- .../ar/service/impl/ArBillServiceImpl.java | 51 +-- .../mapper/ar/ArBillGenerateTaskMapper.xml | 6 - .../resources/mapper/ar/ArBillLogMapper.xml | 17 +- .../main/resources/mapper/ar/ArBillMapper.xml | 34 -- 13 files changed, 24 insertions(+), 649 deletions(-) delete mode 100644 bms-back/bms-admin/src/test/java/com/bms/ar/ArBillDataScopeTest.java delete mode 100644 bms-back/bms-admin/src/test/java/com/bms/system/SysRoleDataScopeRefreshTest.java delete mode 100644 bms-back/bms-system/src/main/java/com/bms/ar/service/ArBillDataScopeService.java diff --git a/bms-back/bms-admin/src/main/java/com/bms/web/controller/system/SysRoleController.java b/bms-back/bms-admin/src/main/java/com/bms/web/controller/system/SysRoleController.java index 9c34b0e9..b06236d5 100644 --- a/bms-back/bms-admin/src/main/java/com/bms/web/controller/system/SysRoleController.java +++ b/bms-back/bms-admin/src/main/java/com/bms/web/controller/system/SysRoleController.java @@ -143,13 +143,7 @@ public class SysRoleController extends BaseController { roleService.checkRoleAllowed(role); roleService.checkRoleDataScope(role.getRoleId()); - int rows = roleService.authDataScope(role); - if (rows > 0) - { - SysRole savedRole = roleService.selectRoleById(role.getRoleId()); - tokenService.refreshPermissionByRoleId(role.getRoleId(), permissionService, savedRole.getDataScope()); - } - return toAjax(rows); + return toAjax(roleService.authDataScope(role)); } /** diff --git a/bms-back/bms-admin/src/test/java/com/bms/ar/ArBillDataScopeTest.java b/bms-back/bms-admin/src/test/java/com/bms/ar/ArBillDataScopeTest.java deleted file mode 100644 index 93ef3a2c..00000000 --- a/bms-back/bms-admin/src/test/java/com/bms/ar/ArBillDataScopeTest.java +++ /dev/null @@ -1,378 +0,0 @@ -package com.bms.ar; - -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.ibatis.builder.xml.XMLMapperBuilder; -import org.apache.ibatis.session.Configuration; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.function.Executable; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; -import org.springframework.aop.aspectj.annotation.AspectJProxyFactory; -import org.springframework.core.io.ClassPathResource; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.test.util.ReflectionTestUtils; -import com.github.pagehelper.Page; -import com.github.pagehelper.PageHelper; -import com.bms.ar.domain.ArBill; -import com.bms.ar.domain.ArBillExport; -import com.bms.ar.domain.ArBillGenerateTask; -import com.bms.ar.domain.ArBillLog; -import com.bms.ar.domain.vo.ArBillGenerateQuery; -import com.bms.ar.domain.vo.ArBillGenerateRequest; -import com.bms.ar.domain.vo.ArBillQuery; -import com.bms.ar.mapper.ArBillDetailFeeMapper; -import com.bms.ar.mapper.ArBillDetailMapper; -import com.bms.ar.mapper.ArBillExportMapper; -import com.bms.ar.mapper.ArBillGenerateTaskMapper; -import com.bms.ar.mapper.ArBillLogMapper; -import com.bms.ar.mapper.ArBillMapper; -import com.bms.ar.service.ArBillDataScopeService; -import com.bms.ar.service.impl.ArBillServiceImpl; -import com.bms.common.core.domain.entity.SysRole; -import com.bms.common.core.domain.entity.SysUser; -import com.bms.common.core.domain.model.LoginUser; -import com.bms.common.exception.ServiceException; -import com.bms.common.utils.file.OssStorage; -import com.bms.framework.aspectj.DataScopeAspect; -import com.bms.price.mapper.PrcOrderBillMapper; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -/** 不启动应用或连接业务数据库,验证真实切面、Mapper SQL 和业务入口的越权阻断。 */ -class ArBillDataScopeTest { - private ArBillMapper billMapper; - private ArBillDetailMapper detailMapper; - private ArBillDetailFeeMapper feeMapper; - private ArBillExportMapper exportMapper; - private ArBillGenerateTaskMapper taskMapper; - private ArBillLogMapper logMapper; - private PrcOrderBillMapper sourceMapper; - private ArBillDataScopeService scopeService; - private ArBillServiceImpl service; - - @BeforeEach - void setUp() { - RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(new MockHttpServletRequest())); - billMapper = mock(ArBillMapper.class); - detailMapper = mock(ArBillDetailMapper.class); - feeMapper = mock(ArBillDetailFeeMapper.class); - exportMapper = mock(ArBillExportMapper.class); - taskMapper = mock(ArBillGenerateTaskMapper.class); - logMapper = mock(ArBillLogMapper.class); - sourceMapper = mock(PrcOrderBillMapper.class); - ArBillDataScopeService scopeTarget = new ArBillDataScopeService(); - ReflectionTestUtils.setField(scopeTarget, "billMapper", billMapper); - ReflectionTestUtils.setField(scopeTarget, "logMapper", logMapper); - ReflectionTestUtils.setField(scopeTarget, "generateTaskMapper", taskMapper); - scopeService = proxy(scopeTarget); - - ArBillServiceImpl target = new ArBillServiceImpl(); - ReflectionTestUtils.setField(target, "billMapper", billMapper); - ReflectionTestUtils.setField(target, "detailMapper", detailMapper); - ReflectionTestUtils.setField(target, "detailFeeMapper", feeMapper); - ReflectionTestUtils.setField(target, "exportMapper", exportMapper); - ReflectionTestUtils.setField(target, "generateTaskMapper", taskMapper); - ReflectionTestUtils.setField(target, "logMapper", logMapper); - ReflectionTestUtils.setField(target, "sourceBillMapper", sourceMapper); - ReflectionTestUtils.setField(target, "dataScopeService", scopeService); - service = proxy(target); - login(42L, role(10L, "5", "ar:bill:list")); - } - - @AfterEach - void cleanUp() { - SecurityContextHolder.clearContext(); - RequestContextHolder.resetRequestAttributes(); - PageHelper.clearPage(); - } - - @ParameterizedTest - @CsvSource({"1, ALL", "2, role_id = 10", "3, ar_scope_user.dept_id = 200", - "4, ancestors", "5, ar_scope_user.user_id = 42"}) - void appliesAllFiveRoleScopesAndClearsClientSuppliedSql(String scope, String expected) { - login(42L, role(10L, scope, "ar:bill:list")); - ArBillQuery query = new ArBillQuery(); - query.getParams().put("dataScope", " OR 1=1 /* client supplied */"); - service.selectArBillList(query); - String sql = scope(query); - if ("ALL".equals(expected)) { - assertEquals("", sql); - } else { - assertTrue(sql.contains(expected), sql); - } - assertFalse(sql.contains("client supplied")); - verify(billMapper).selectArBillList(same(query)); - } - - @Test - void mergesOnlyRolesWithBillListPermissionAndIgnoresDisabledRoles() { - SysRole disabled = role(13L, "1", "ar:bill:list"); - disabled.setStatus("1"); - login(42L, role(10L, "5", "ar:bill:list"), role(11L, "3", "ar:bill:list"), - role(12L, "1", "other:list"), disabled); - ArBillQuery query = new ArBillQuery(); - service.selectArBillList(query); - assertTrue(scope(query).contains("ar_scope_user.user_id = 42")); - assertTrue(scope(query).contains("ar_scope_user.dept_id = 200")); - assertTrue(scope(query).contains(" OR ")); - - login(42L, role(10L, "5", "ar:bill:list"), role(11L, "1", "ar:bill:list")); - service.selectArBillList(query); - assertEquals("", scope(query)); - } - - @Test - void superAdminIsUnrestrictedButNoMatchingRoleGetsNoRows() { - ArBillQuery query = new ArBillQuery(); - login(1L); - service.selectArBillList(query); - assertEquals("", scope(query)); - login(42L, role(10L, "1", "other:list")); - service.selectArBillList(query); - assertTrue(scope(query).contains("ar_scope_user.dept_id = 0")); - } - - @Test - void combinesCustomDepartmentRoles() { - login(42L, role(10L, "2", "ar:bill:list"), role(11L, "2", "ar:bill:list")); - ArBillQuery query = new ArBillQuery(); - service.selectArBillList(query); - assertTrue(scope(query).contains("role_id in (10,11)")); - } - - @Test - void rejectsBillIdsBeforeReadingDetailsOrRunningActions() { - forbidden(() -> service.selectArBillById(80L)); - forbidden(() -> service.selectArBillDetails(80L)); - forbidden(() -> service.selectArBillDetailFees(80L, 1L)); - forbidden(() -> service.selectExports(80L)); - forbidden(() -> service.confirmBill(80L, null, "tester", "confirm")); - forbidden(() -> service.voidBill(80L, null, "tester", "void")); - forbidden(() -> service.exportBill(80L, "tester", "export")); - verifyNoInteractions(detailMapper, feeMapper, exportMapper, logMapper); - verify(billMapper, never()).selectArBillByIdForUpdate(anyLong()); - } - - @Test - void checksExportAndGenerateTaskOwnershipThroughTheirBill() throws Exception { - ArBillExport export = new ArBillExport(); - export.setArBillId(80L); - export.setExportStatus("SUCCESS"); - export.setStorageKey("oss://test/bill.xlsx"); - when(exportMapper.selectById(9L)).thenReturn(export); - MockHttpServletResponse response = new MockHttpServletResponse(); - forbidden(() -> service.selectExport(9L)); - forbidden(() -> service.downloadExport(9L, response)); - assertEquals(0, response.getContentAsByteArray().length); - assertNull(response.getHeader("Content-Disposition")); - - ArBillGenerateTask task = new ArBillGenerateTask(); - task.setArBillId(80L); - when(taskMapper.selectById(3L)).thenReturn(task); - forbidden(() -> service.selectGenerateTask(3L)); - forbidden(() -> service.cancelGenerateTask(3L, "tester", "cancel")); - forbidden(() -> service.retryGenerateTask(3L, "tester", "retry")); - verify(taskMapper, never()).markCancelRequested(anyLong()); - } - - @Test - void authorizedBillStillReturnsMaskedAccountAndDownloadsItsExport() throws Exception { - ArBill bill = new ArBill(); - bill.setArBillId(80L); - bill.setBankAccountNo("123456780504"); - when(billMapper.selectArBillByDataScope(any())).thenReturn(bill); - assertEquals("****0504", service.selectArBillById(80L).getBankAccountNo()); - ArBillExport export = new ArBillExport(); - export.setArBillId(80L); - export.setExportStatus("SUCCESS"); - export.setStorageKey("oss://test/bill.xlsx"); - export.setFileName("bill.xlsx"); - when(exportMapper.selectById(9L)).thenReturn(export); - OssStorage storage = mock(OssStorage.class); - ReflectionTestUtils.setField(service, "ossStorage", storage); - doAnswer(invocation -> { - ((OutputStream) invocation.getArgument(1)).write(new byte[] {1, 2, 3}); - return null; - }).when(storage).download(eq("oss://test/bill.xlsx"), any(OutputStream.class)); - MockHttpServletResponse response = new MockHttpServletResponse(); - service.downloadExport(9L, response); - assertArrayEquals(new byte[] {1, 2, 3}, response.getContentAsByteArray()); - assertTrue(response.getHeader("Content-Disposition").contains("bill.xlsx")); - } - - @Test - void permissionLookupPreservesDetailPaginationAndClearsItOnDenial() { - Page page = PageHelper.startPage(3, 20); - page.setOrderBy("detail_no desc"); - when(billMapper.selectArBillByDataScope(any())).thenAnswer(invocation -> { - assertNull(PageHelper.getLocalPage(), "权限校验不能消耗明细分页"); - assertTrue(scope(invocation.getArgument(0)).contains("ar_scope_user.user_id = 42")); - return new ArBill(); - }); - when(detailMapper.selectByBillId(80L)).thenAnswer(invocation -> { - assertSame(page, PageHelper.getLocalPage()); - assertEquals("detail_no desc", page.getOrderBy()); - PageHelper.clearPage(); - return Collections.emptyList(); - }); - service.selectArBillDetails(80L); - assertNull(PageHelper.getLocalPage()); - - doReturn(null).when(billMapper).selectArBillByDataScope(any()); - PageHelper.startPage(3, 20); - forbidden(() -> service.selectArBillDetails(81L)); - assertNull(PageHelper.getLocalPage(), "拒绝请求后不能向下一请求遗留分页"); - } - - @Test - void rejectsCustomerPreviewAndGenerationBeforeReadingSourceOrders() { - ArBillGenerateQuery preview = new ArBillGenerateQuery(); - preview.setCustomerId(100L); - preview.setBillPeriodEnd(new Date()); - forbidden(() -> service.previewBill(preview)); - forbidden(() -> service.sumPreviewBill(preview)); - ArBillGenerateRequest request = new ArBillGenerateRequest(); - request.setCustomerId(100L); - request.setBillName("test"); - request.setBillPeriodEnd(new Date()); - forbidden(() -> service.generateBill(request, "tester", "generate")); - verifyNoInteractions(sourceMapper, taskMapper); - } - - @Test - void authorizedCustomerPreviewRetainsItsOriginalPagination() { - Page page = PageHelper.startPage(2, 10); - when(billMapper.selectCustomerIdByDataScope(any())).thenAnswer(invocation -> { - assertNull(PageHelper.getLocalPage()); - return 100L; - }); - doAnswer(invocation -> { - assertSame(page, PageHelper.getLocalPage()); - PageHelper.clearPage(); - return Collections.emptyList(); - }).when(sourceMapper).selectPrcOrderBillByCustomerPeriod(eq(100L), any(), anyList(), anyList(), - any(), any(), anyList(), any(), any()); - ArBillGenerateQuery preview = new ArBillGenerateQuery(); - preview.setCustomerId(100L); - preview.setBillPeriodEnd(new Date()); - service.previewBill(preview); - assertNull(PageHelper.getLocalPage()); - } - - @Test - void exportIdempotencyCannotReturnAnExportFromAnotherBill() { - when(billMapper.selectArBillByDataScope(any())).thenReturn(new ArBill()); - ArBillLog previous = new ArBillLog(); - previous.setObjectId("9"); - when(logMapper.selectSuccessByRequestId(anyString(), anyString(), anyString())).thenReturn(previous); - ArBillExport export = new ArBillExport(); - export.setArBillId(81L); - when(exportMapper.selectById(9L)).thenReturn(export); - ServiceException denied = assertThrows(ServiceException.class, - () -> service.exportBill(80L, "tester", "reused")); - assertTrue(denied.getMessage().contains("其他账单")); - verify(exportMapper, never()).insert(any()); - } - - @Test - void logAndActiveTaskQueriesUseTheSameRoleScope() { - scopeService.selectLogs(new ArBillQuery(), new ArBillLog()); - scopeService.selectActiveGenerateTasks(new ArBillQuery(), "tester"); - verify(logMapper).selectList(any(), argThat(params -> - params.get("dataScope").toString().contains("ar_scope_user.user_id = 42"))); - verify(taskMapper).selectActiveByCreateBy(eq("tester"), argThat(params -> - params.get("dataScope").toString().contains("ar_scope_user.user_id = 42"))); - } - - @Test - void allReadMappersRenderScopedSqlAndKeepNormalFilters() throws Exception { - Configuration configuration = new Configuration(); - configuration.getTypeAliasRegistry().registerAlias("ArBill", ArBill.class); - configuration.getTypeAliasRegistry().registerAlias("ArBillLog", ArBillLog.class); - configuration.getTypeAliasRegistry().registerAlias("ArBillGenerateTask", ArBillGenerateTask.class); - for (String name : List.of("ArBillMapper", "ArBillLogMapper", "ArBillGenerateTaskMapper")) { - String resource = "mapper/ar/" + name + ".xml"; - try (InputStream input = new ClassPathResource(resource).getInputStream()) { - new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse(); - } - } - ArBillQuery query = new ArBillQuery(); - query.setArBillId(80L); - query.setCustomerId(100L); - query.setStatus("CONFIRMED"); - service.selectArBillList(query); - String listSql = sql(configuration, "ArBillMapper.selectArBillList", query); - assertTrue(listSql.contains("status = ?")); - assertTrue(listSql.contains("customer_id = ?")); - assertTrue(listSql.contains("ar_scope_customer.customer_id = ar_bill.customer_id")); - assertTrue(listSql.contains("ar_scope_id_user.user_id is null"), "历史工号仅在ID不存在时兜底"); - assertTrue(listSql.contains("exists ("), "EXISTS 避免业务员关联放大列表和分页总数"); - assertFalse(listSql.contains("${")); - for (String statement : List.of("ArBillMapper.selectArBillByDataScope", "ArBillMapper.selectCustomerIdByDataScope")) { - assertTrue(sql(configuration, statement, query).contains("ar_scope_user.user_id = 42")); - } - Map logs = Map.of("query", new ArBillLog(), "params", query.getParams()); - assertTrue(sql(configuration, "ArBillLogMapper.selectList", logs).contains("ar_scope_customer.customer_id = b.customer_id")); - Map tasks = Map.of("createBy", "tester", "params", query.getParams()); - assertTrue(sql(configuration, "ArBillGenerateTaskMapper.selectActiveByCreateBy", tasks) - .contains("b.ar_bill_id = ar_bill_generate_task.ar_bill_id")); - login(42L, role(10L, "1", "ar:bill:list")); - service.selectArBillList(query); - assertFalse(sql(configuration, "ArBillMapper.selectArBillList", query).contains("ar_scope_customer")); - } - - private String sql(Configuration configuration, String statement, Object parameters) { - return configuration.getMappedStatement("com.bms.ar.mapper." + statement).getBoundSql(parameters) - .getSql().replaceAll("\\s+", " "); - } - - private String scope(ArBillQuery query) { - return String.valueOf(query.getParams().get("dataScope")); - } - - private void forbidden(Executable action) { - assertEquals(403, assertThrows(ServiceException.class, action).getCode()); - } - - private SysRole role(Long id, String scope, String permission) { - SysRole role = new SysRole(id); - role.setDataScope(scope); - role.setStatus("0"); - role.setPermissions(Set.of(permission)); - return role; - } - - private void login(Long userId, SysRole... roles) { - SysUser user = new SysUser(userId); - user.setDeptId(200L); - user.setUserName("tester"); - user.setRoles(List.of(roles)); - LoginUser login = new LoginUser(userId, 200L, user, Set.of("ar:bill:list")); - SecurityContextHolder.getContext().setAuthentication( - new UsernamePasswordAuthenticationToken(login, null, Collections.emptyList())); - } - - @SuppressWarnings("unchecked") - private T proxy(T target) { - AspectJProxyFactory factory = new AspectJProxyFactory(target); - factory.setProxyTargetClass(true); - factory.addAspect(new DataScopeAspect()); - return (T) factory.getProxy(); - } -} diff --git a/bms-back/bms-admin/src/test/java/com/bms/system/SysRoleDataScopeRefreshTest.java b/bms-back/bms-admin/src/test/java/com/bms/system/SysRoleDataScopeRefreshTest.java deleted file mode 100644 index ed094eab..00000000 --- a/bms-back/bms-admin/src/test/java/com/bms/system/SysRoleDataScopeRefreshTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.bms.system; - -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.Test; -import org.springframework.test.util.ReflectionTestUtils; -import com.bms.common.constant.CacheConstants; -import com.bms.common.core.domain.entity.SysRole; -import com.bms.common.core.domain.entity.SysUser; -import com.bms.common.core.domain.model.LoginUser; -import com.bms.common.core.redis.RedisCache; -import com.bms.framework.web.service.SysPermissionService; -import com.bms.framework.web.service.TokenService; -import com.bms.system.service.ISysRoleService; -import com.bms.web.controller.system.SysRoleController; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -class SysRoleDataScopeRefreshTest { - @Test - void savingDataScopeRefreshesOnlineUsersWithPersistedScope() { - ISysRoleService roles = mock(ISysRoleService.class); - TokenService tokens = mock(TokenService.class); - SysPermissionService permissions = mock(SysPermissionService.class); - SysRoleController controller = new SysRoleController(); - ReflectionTestUtils.setField(controller, "roleService", roles); - ReflectionTestUtils.setField(controller, "tokenService", tokens); - ReflectionTestUtils.setField(controller, "permissionService", permissions); - SysRole submitted = new SysRole(10L); - submitted.setDataScope("5"); - SysRole persisted = new SysRole(10L); - persisted.setDataScope("5"); - when(roles.authDataScope(submitted)).thenReturn(1); - when(roles.selectRoleById(10L)).thenReturn(persisted); - controller.dataScope(submitted); - verify(tokens).refreshPermissionByRoleId(10L, permissions, "5"); - } - - @Test - void replacesCachedDataScopeBeforeSavingSessionAndPreservesOtherRoles() { - RedisCache redis = mock(RedisCache.class); - SysPermissionService permissions = mock(SysPermissionService.class); - TokenService tokens = spy(new TokenService()); - ReflectionTestUtils.setField(tokens, "redisCache", redis); - doNothing().when(tokens).refreshToken(any()); - SysRole target = new SysRole(10L); - target.setDataScope("1"); - SysRole other = new SysRole(11L); - other.setDataScope("3"); - SysUser user = new SysUser(42L); - user.setRoles(List.of(target, other)); - LoginUser login = new LoginUser(42L, 200L, user, Set.of("ar:bill:list")); - String key = CacheConstants.LOGIN_TOKEN_KEY + "test"; - when(redis.keys(CacheConstants.LOGIN_TOKEN_KEY + "*")).thenReturn(List.of(key)); - when(redis.getCacheObject(key)).thenReturn(login); - when(permissions.getMenuPermission(user)).thenAnswer(invocation -> { - assertEquals("5", target.getDataScope()); - return Set.of("ar:bill:list"); - }); - tokens.refreshPermissionByRoleId(10L, permissions, "5"); - assertEquals("5", login.getUser().getRoles().get(0).getDataScope()); - assertEquals("3", other.getDataScope()); - verify(tokens).refreshToken(login); - } -} diff --git a/bms-back/bms-framework/src/main/java/com/bms/framework/web/service/TokenService.java b/bms-back/bms-framework/src/main/java/com/bms/framework/web/service/TokenService.java index 0394280d..0c3cbc39 100644 --- a/bms-back/bms-framework/src/main/java/com/bms/framework/web/service/TokenService.java +++ b/bms-back/bms-framework/src/main/java/com/bms/framework/web/service/TokenService.java @@ -238,12 +238,6 @@ public class TokenService * @param permissionService 权限服务 */ public void refreshPermissionByRoleId(Long roleId, SysPermissionService permissionService) - { - refreshPermissionByRoleId(roleId, permissionService, null); - } - - /** 数据范围变更时同步更新在线登录信息中的角色快照。 */ - public void refreshPermissionByRoleId(Long roleId, SysPermissionService permissionService, String dataScope) { // 扫描所有在线 token String pattern = CacheConstants.LOGIN_TOKEN_KEY + "*"; @@ -267,12 +261,6 @@ public class TokenService { continue; } - if (dataScope != null) - { - loginUser.getUser().getRoles().stream() - .filter(r -> roleId.equals(r.getRoleId())) - .forEach(r -> r.setDataScope(dataScope)); - } // 刷新权限缓存 loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); refreshToken(loginUser); diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillGenerateTaskMapper.java b/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillGenerateTaskMapper.java index fe76c088..5e0d9af4 100644 --- a/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillGenerateTaskMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillGenerateTaskMapper.java @@ -2,7 +2,6 @@ package com.bms.ar.mapper; import java.util.Date; import java.util.List; -import java.util.Map; import org.apache.ibatis.annotations.Param; import com.bms.ar.domain.ArBillGenerateTask; @@ -15,8 +14,7 @@ public interface ArBillGenerateTaskMapper { ArBillGenerateTask selectByRequestToken(String requestToken); - List selectActiveByCreateBy(@Param("createBy") String createBy, - @Param("params") Map params); + List selectActiveByCreateBy(@Param("createBy") String createBy); List selectWaiting(@Param("limit") int limit); diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillLogMapper.java b/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillLogMapper.java index 973d668b..d98f5087 100644 --- a/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillLogMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillLogMapper.java @@ -1,13 +1,12 @@ package com.bms.ar.mapper; import java.util.List; -import java.util.Map; import org.apache.ibatis.annotations.Param; import com.bms.ar.domain.ArBillLog; public interface ArBillLogMapper { - List selectList(@Param("query") ArBillLog query, @Param("params") Map params); + List selectList(ArBillLog query); ArBillLog selectSuccessByRequestId(@Param("requestId") String requestId, @Param("objectType") String objectType, diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillMapper.java b/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillMapper.java index 7b2514be..be476768 100644 --- a/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/ar/mapper/ArBillMapper.java @@ -11,10 +11,6 @@ import com.bms.ar.domain.vo.ArBillQuery; public interface ArBillMapper { List selectArBillList(ArBillQuery query); - ArBill selectArBillByDataScope(ArBillQuery query); - - Long selectCustomerIdByDataScope(ArBillQuery query); - ArBill selectArBillById(Long arBillId); ArBill selectArBillByBillNo(String billNo); diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/service/ArBillDataScopeService.java b/bms-back/bms-system/src/main/java/com/bms/ar/service/ArBillDataScopeService.java deleted file mode 100644 index dad5a6ee..00000000 --- a/bms-back/bms-system/src/main/java/com/bms/ar/service/ArBillDataScopeService.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.bms.ar.service; - -import java.util.List; -import java.util.function.Supplier; - -import com.github.pagehelper.Page; -import com.github.pagehelper.PageHelper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import com.bms.ar.domain.ArBill; -import com.bms.ar.domain.ArBillGenerateTask; -import com.bms.ar.domain.ArBillLog; -import com.bms.ar.domain.vo.ArBillQuery; -import com.bms.ar.mapper.ArBillGenerateTaskMapper; -import com.bms.ar.mapper.ArBillLogMapper; -import com.bms.ar.mapper.ArBillMapper; -import com.bms.common.annotation.DataScope; -import com.bms.common.constant.HttpStatus; -import com.bms.common.exception.ServiceException; - -/** - * 按客户归属业务员和其部门校验账单可见范围。 - * 独立 Bean 保证内部业务调用也经过 DataScope 切面;范围始终取具有账单列表权限的角色。 - */ -@Service -public class ArBillDataScopeService { - @Autowired - private ArBillMapper billMapper; - @Autowired - private ArBillLogMapper logMapper; - @Autowired - private ArBillGenerateTaskMapper generateTaskMapper; - - @DataScope(deptAlias = "ar_scope_user", userAlias = "ar_scope_user", permission = "ar:bill:list") - public ArBill requireBill(ArBillQuery query) { - return withoutPagination(() -> { - ArBill bill = query.getArBillId() == null ? null : billMapper.selectArBillByDataScope(query); - if (bill == null) { - throw new ServiceException("应收账单不存在或无权访问", HttpStatus.FORBIDDEN); - } - return bill; - }); - } - - @DataScope(deptAlias = "ar_scope_user", userAlias = "ar_scope_user", permission = "ar:bill:list") - public void requireCustomer(ArBillQuery query) { - withoutPagination(() -> { - Long customerId = query.getCustomerId() == null || query.getCustomerId() <= 0 - ? null : billMapper.selectCustomerIdByDataScope(query); - if (customerId == null || customerId <= 0) { - throw new ServiceException("客户不存在或无权访问该客户的应收账单", HttpStatus.FORBIDDEN); - } - return customerId; - }); - } - - @DataScope(deptAlias = "ar_scope_user", userAlias = "ar_scope_user", permission = "ar:bill:list") - public List selectLogs(ArBillQuery scope, ArBillLog query) { - return logMapper.selectList(query, scope.getParams()); - } - - @DataScope(deptAlias = "ar_scope_user", userAlias = "ar_scope_user", permission = "ar:bill:list") - public List selectActiveGenerateTasks(ArBillQuery scope, String operator) { - return generateTaskMapper.selectActiveByCreateBy(operator, scope.getParams()); - } - - /** 权限校验 SQL 不消耗调用方为明细/订单预览设置的分页,拒绝访问时清理分页。 */ - private T withoutPagination(Supplier lookup) { - Page pendingPage = PageHelper.getLocalPage(); - PageHelper.clearPage(); - try { - T result = lookup.get(); - if (pendingPage != null) { - PageHelper.setLocalPage(pendingPage); - } - return result; - } catch (RuntimeException | Error e) { - PageHelper.clearPage(); - throw e; - } - } -} diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillLogServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillLogServiceImpl.java index 53fe7363..b98e5b38 100644 --- a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillLogServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillLogServiceImpl.java @@ -13,20 +13,16 @@ import com.bms.ar.enums.ArLogOperationType; import com.bms.ar.enums.ArLogResult; import com.bms.ar.mapper.ArBillLogMapper; import com.bms.ar.service.IArBillLogService; -import com.bms.ar.service.ArBillDataScopeService; -import com.bms.ar.domain.vo.ArBillQuery; import com.bms.common.utils.uuid.IdUtils; @Service public class ArBillLogServiceImpl implements IArBillLogService { @Autowired private ArBillLogMapper logMapper; - @Autowired - private ArBillDataScopeService dataScopeService; @Override public List selectLogList(ArBillLog query) { - return dataScopeService.selectLogs(new ArBillQuery(), query); + return logMapper.selectList(query); } @Override diff --git a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java index 96f43f56..9259d29c 100644 --- a/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/ar/service/impl/ArBillServiceImpl.java @@ -75,13 +75,11 @@ import com.bms.ar.mapper.ArBankAccountMapper; import com.bms.ar.mapper.ArExportTemplateMapper; import com.bms.ar.service.IArBillLogService; import com.bms.ar.service.IArBillService; -import com.bms.ar.service.ArBillDataScopeService; import com.bms.ar.domain.vo.ArBillActionRequest; import com.bms.ar.domain.vo.ArBillGenerateQuery; import com.bms.ar.domain.vo.ArBillGenerateRequest; import com.bms.ar.domain.vo.ArBillQuery; import com.bms.common.config.BmsConfig; -import com.bms.common.annotation.DataScope; import com.bms.common.exception.ServiceException; import com.bms.common.utils.DateUtils; import com.bms.common.utils.SecurityUtils; @@ -199,8 +197,6 @@ public class ArBillServiceImpl implements IArBillService { @Autowired private IArBillLogService logService; @Autowired - private ArBillDataScopeService dataScopeService; - @Autowired private ApplicationEventPublisher eventPublisher; @Autowired private PrcOrderBillMapper sourceBillMapper; @@ -215,7 +211,6 @@ public class ArBillServiceImpl implements IArBillService { * 查询账单列表,并对返回给前端的收款账号做脱敏。 */ @Override - @DataScope(deptAlias = "ar_scope_user", userAlias = "ar_scope_user", permission = "ar:bill:list") public List selectArBillList(ArBillQuery query) { long startedAt = System.nanoTime(); List bills = billMapper.selectArBillList(query); @@ -234,7 +229,10 @@ public class ArBillServiceImpl implements IArBillService { @Override public ArBill selectArBillById(Long arBillId) { long startedAt = System.nanoTime(); - ArBill bill = requireBillDataScope(arBillId); + ArBill bill = billMapper.selectArBillById(arBillId); + if (bill == null) { + throw new ServiceException("应收账单不存在"); + } bill.setBankAccountNo(maskAccount(bill.getBankAccountNo())); bill.setExports(exportMapper.selectByBillId(arBillId)); log.debug("应收账单详情查询完成,arBillId={}, status={}, exportCount={}, costMs={}", @@ -249,7 +247,6 @@ public class ArBillServiceImpl implements IArBillService { @Override public List selectArBillDetails(Long arBillId) { long startedAt = System.nanoTime(); - requireBillDataScope(arBillId); List details = detailMapper.selectByBillId(arBillId); log.debug("应收账单明细查询完成,arBillId={}, resultCount={}, costMs={}", arBillId, details.size(), elapsedMillis(startedAt)); @@ -262,7 +259,6 @@ public class ArBillServiceImpl implements IArBillService { @Override public List selectArBillDetailFees(Long arBillId, Long detailId) { long startedAt = System.nanoTime(); - requireBillDataScope(arBillId); List fees = detailFeeMapper.selectByBillIdAndDetailId(arBillId, detailId); log.debug("应收账单费用明细查询完成,arBillId={}, detailId={}, resultCount={}, costMs={}", arBillId, detailId, fees.size(), elapsedMillis(startedAt)); @@ -303,7 +299,6 @@ public class ArBillServiceImpl implements IArBillService { public List previewBill(ArBillGenerateQuery query) { long startedAt = System.nanoTime(); validatePreviewQuery(query); - requireCustomerDataScope(query.getCustomerId()); List orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo()); List excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo()); List result = sourceBillMapper.selectPrcOrderBillByCustomerPeriod(query.getCustomerId(), @@ -332,7 +327,6 @@ public class ArBillServiceImpl implements IArBillService { public BigDecimal sumPreviewBill(ArBillGenerateQuery query) { long startedAt = System.nanoTime(); validatePreviewQuery(query); - requireCustomerDataScope(query.getCustomerId()); List orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo()); List excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo()); BigDecimal total = nvl(sourceBillMapper.sumPrcOrderBillIncomeByCustomerPeriod(query.getCustomerId(), @@ -356,13 +350,8 @@ public class ArBillServiceImpl implements IArBillService { long startedAt = System.nanoTime(); Long createUserId = SecurityUtils.getUserId(); validatePeriod(request); - requireCustomerDataScope(request.getCustomerId()); ArBillGenerateTask existed = generateTaskMapper.selectByRequestToken(requestId); if (existed != null) { - ArBill existedBill = requireBillDataScope(existed.getArBillId()); - if (!request.getCustomerId().equals(existedBill.getCustomerId())) { - throw new ServiceException("请求标识已用于其他客户,请重新发起"); - } log.info("应收账单生成请求命中幂等记录,operator={}, requestId={}, taskId={}, status={}, costMs={}", safeLogValue(operator), safeLogValue(requestId), existed.getTaskId(), existed.getStatus(), elapsedMillis(startedAt)); @@ -482,7 +471,6 @@ public class ArBillServiceImpl implements IArBillService { if (task == null) { throw new ServiceException("账单生成任务不存在"); } - requireBillDataScope(task.getArBillId()); log.debug("应收账单生成任务状态查询,taskId={}, status={}, processedCount={}, totalCount={}, costMs={}", taskId, task.getStatus(), task.getProcessedCount(), task.getTotalCount(), elapsedMillis(startedAt)); return task; @@ -494,7 +482,7 @@ public class ArBillServiceImpl implements IArBillService { @Override public List selectActiveGenerateTasks(String operator) { long startedAt = System.nanoTime(); - List tasks = dataScopeService.selectActiveGenerateTasks(new ArBillQuery(), operator); + List tasks = generateTaskMapper.selectActiveByCreateBy(operator); log.debug("当前用户应收账单生成任务查询,operator={}, taskCount={}, costMs={}", safeLogValue(operator), tasks.size(), elapsedMillis(startedAt)); return tasks; @@ -925,7 +913,6 @@ public class ArBillServiceImpl implements IArBillService { @Transactional(rollbackFor = Exception.class) public ArBill confirmBill(Long arBillId, ArBillActionRequest request, String operator, String requestId) { long startedAt = System.nanoTime(); - requireBillDataScope(arBillId); ArBill bill = billMapper.selectArBillByIdForUpdate(arBillId); if (bill == null) { throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.CONFIRM, @@ -970,7 +957,6 @@ public class ArBillServiceImpl implements IArBillService { @Transactional(rollbackFor = Exception.class) public ArBill voidBill(Long arBillId, ArBillActionRequest request, String operator, String requestId) { long startedAt = System.nanoTime(); - requireBillDataScope(arBillId); String remark = request == null ? null : request.getRemark(); if (StringUtils.isEmpty(remark)) { throw failure(arBillId, ArLogObjectType.BILL, String.valueOf(arBillId), ArLogOperationType.VOID, @@ -1015,22 +1001,23 @@ public class ArBillServiceImpl implements IArBillService { @Transactional(rollbackFor = Exception.class) public ArBillExport exportBill(Long arBillId, String operator, String requestId) { long startedAt = System.nanoTime(); - ArBill bill = requireBillDataScope(arBillId); Long exportUserId = SecurityUtils.getUserId(); ArBillLog previous = logMapper.selectSuccessByRequestId(requestId, ArLogObjectType.EXPORT.getCode(), ArLogResult.SUCCESS.getCode()); if (previous != null && isNumber(previous.getObjectId())) { ArBillExport previousExport = exportMapper.selectById(Long.valueOf(previous.getObjectId())); if (previousExport != null) { - if (!arBillId.equals(previousExport.getArBillId())) { - throw new ServiceException("请求标识已用于其他账单,请重新发起"); - } log.info("应收账单导出请求命中幂等记录,operator={}, requestId={}, arBillId={}, exportId={}, status={}, costMs={}", safeLogValue(operator), safeLogValue(requestId), arBillId, previousExport.getExportId(), previousExport.getExportStatus(), elapsedMillis(startedAt)); return previousExport; } } + ArBill bill = billMapper.selectArBillById(arBillId); + if (bill == null) { + throw failure(arBillId, ArLogObjectType.EXPORT, String.valueOf(arBillId), ArLogOperationType.EXPORT, + null, "应收账单不存在", operator, requestId); + } if (!ArBillGenerationStatus.READY.equals(bill.getGenerationStatus())) { throw failure(arBillId, ArLogObjectType.EXPORT, String.valueOf(arBillId), ArLogOperationType.EXPORT, bill.getStatus(), "账单尚未生成完成,暂不能导出", operator, requestId); @@ -1091,7 +1078,6 @@ public class ArBillServiceImpl implements IArBillService { if (export == null) { throw new ServiceException("导出任务不存在"); } - requireBillDataScope(export.getArBillId()); log.debug("应收账单导出任务状态查询,exportId={}, status={}, costMs={}", exportId, export.getExportStatus(), elapsedMillis(startedAt)); return export; @@ -1172,7 +1158,6 @@ public class ArBillServiceImpl implements IArBillService { @Override public List selectExports(Long arBillId) { long startedAt = System.nanoTime(); - requireBillDataScope(arBillId); List exports = exportMapper.selectByBillId(arBillId); log.debug("应收账单导出记录查询,arBillId={}, exportCount={}, costMs={}", arBillId, exports.size(), elapsedMillis(startedAt)); @@ -1182,8 +1167,8 @@ public class ArBillServiceImpl implements IArBillService { @Override public void downloadExport(Long exportId, HttpServletResponse response) throws Exception { long startedAt = System.nanoTime(); - ArBillExport export = selectExport(exportId); - if (!ArExportStatus.SUCCESS.getCode().equals(export.getExportStatus()) || StringUtils.isEmpty(export.getStorageKey())) { + ArBillExport export = exportMapper.selectById(exportId); + if (export == null || !ArExportStatus.SUCCESS.getCode().equals(export.getExportStatus()) || StringUtils.isEmpty(export.getStorageKey())) { throw new ServiceException("导出文件不存在或尚未生成成功"); } String resource = export.getStorageKey(); @@ -1212,18 +1197,6 @@ public class ArBillServiceImpl implements IArBillService { return logs; } - private ArBill requireBillDataScope(Long arBillId) { - ArBillQuery query = new ArBillQuery(); - query.setArBillId(arBillId); - return dataScopeService.requireBill(query); - } - - private void requireCustomerDataScope(Long customerId) { - ArBillQuery query = new ArBillQuery(); - query.setCustomerId(customerId); - dataScopeService.requireCustomer(query); - } - private String exportFailureMessage(Exception e) { String message = StringUtils.isEmpty(e.getMessage()) ? "账单导出失败" : e.getMessage(); return message.length() > 500 ? message.substring(0, 500) : message; diff --git a/bms-back/bms-system/src/main/resources/mapper/ar/ArBillGenerateTaskMapper.xml b/bms-back/bms-system/src/main/resources/mapper/ar/ArBillGenerateTaskMapper.xml index 76548d68..27d3b0be 100644 --- a/bms-back/bms-system/src/main/resources/mapper/ar/ArBillGenerateTaskMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/ar/ArBillGenerateTaskMapper.xml @@ -66,12 +66,6 @@ where create_by = #{createBy} and status in ('WAITING', 'RUNNING', 'CANCEL_REQUESTED') - - and exists ( - select 1 from ar_bill b where b.ar_bill_id = ar_bill_generate_task.ar_bill_id - - ) - order by create_time desc, task_id desc diff --git a/bms-back/bms-system/src/main/resources/mapper/ar/ArBillLogMapper.xml b/bms-back/bms-system/src/main/resources/mapper/ar/ArBillLogMapper.xml index 786c5eac..4254aa23 100644 --- a/bms-back/bms-system/src/main/resources/mapper/ar/ArBillLogMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/ar/ArBillLogMapper.xml @@ -26,7 +26,7 @@ - select l.log_id, l.ar_bill_id, l.object_type, l.object_id, l.operation_type, l.operation_desc, case l.object_type when 'BILL' then b.bill_no @@ -43,15 +43,14 @@ left join ar_balance_writeoff bw on bw.writeoff_id = case when l.object_type = 'BALANCE_WRITEOFF' then cast(l.object_id as unsigned) end - and l.ar_bill_id = #{query.arBillId} - and l.object_type = #{query.objectType} - and l.object_id = #{query.objectId} - and l.operation_type = #{query.operationType} - and l.operation_source = #{query.operationSource} + and l.ar_bill_id = #{arBillId} + and l.object_type = #{objectType} + and l.object_id = #{objectId} + and l.operation_type = #{operationType} + and l.operation_source = #{operationSource} - and l.request_id = #{query.requestId} - and l.result = #{query.result} - + and l.request_id = #{requestId} + and l.result = #{result} order by l.create_time desc, l.log_id desc diff --git a/bms-back/bms-system/src/main/resources/mapper/ar/ArBillMapper.xml b/bms-back/bms-system/src/main/resources/mapper/ar/ArBillMapper.xml index 139533e5..aa835a73 100644 --- a/bms-back/bms-system/src/main/resources/mapper/ar/ArBillMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/ar/ArBillMapper.xml @@ -67,27 +67,6 @@ from ar_bill - - - - and exists ( - select 1 from ctr_customer ar_scope_customer - left join sys_user ar_scope_id_user - on ar_scope_customer.sales_user_id regexp '^[0-9]+$' - and ar_scope_id_user.user_id = ar_scope_customer.sales_user_id + 0 - left join sys_user ar_scope_user - on ar_scope_user.del_flag = '0' - and (ar_scope_user.user_id = ar_scope_id_user.user_id - or (ar_scope_id_user.user_id is null - and ar_scope_user.user_name = ar_scope_customer.sales_user_id)) - where ar_scope_customer.customer_id = ${customerIdColumn} - ${params.dataScope} - ) - - - - - - - -