fix(mcp): 修复商城订单工具 CR 问题——时区固定/严格日期校验/权限单测 (REQ-20260909-0004)
- OrderTools: startOrderTime/endOrderTime 解析与输出时间格式化统一固定 Asia/Shanghai;
endOrderTime 边界改为 < 次日零点(LocalDate.atStartOfDay),不再用 23:59:59 写法
- 日期入参严格校验:正则 ^\d{4}-\d{2}-\d{2}$ 全串匹配 + ISO_LOCAL_DATE/STRICT 解析,
拒绝 "2026-09-09junk" 尾部垃圾字符与 2026-02-30 等非法日历日
- 新增 PermissionServiceOrderRowFilterTest:applyOrderRowFilter 直接单测,
覆盖总部不过滤/代理自己+下级+代管/代管物业 OR 分支/销售非负责人收窄/agentId 缺失拒绝
This commit is contained in:
@@ -25,14 +25,18 @@ import org.springframework.ai.tool.annotation.ToolParam;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.format.ResolverStyle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -44,7 +48,13 @@ public class OrderTools implements ToolObject {
|
||||
|
||||
private static final int DEFAULT_ROWS = 20;
|
||||
private static final int MAX_ROWS = 100;
|
||||
private static final String DATE_FORMAT = "yyyy-MM-dd";
|
||||
/** 商城业务时区固定 Asia/Shanghai,日期解析与时间格式化统一走该时区。 */
|
||||
private static final ZoneId BUSINESS_ZONE = ZoneId.of("Asia/Shanghai");
|
||||
private static final Pattern DATE_PATTERN = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$");
|
||||
private static final DateTimeFormatter DATE_FORMATTER =
|
||||
DateTimeFormatter.ISO_LOCAL_DATE.withResolverStyle(ResolverStyle.STRICT);
|
||||
private static final DateTimeFormatter TIME_FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(BUSINESS_ZONE);
|
||||
|
||||
final MallGoodsOrderMapper orderMapper;
|
||||
final MallOrderDetailsMapper orderDetailsMapper;
|
||||
@@ -95,7 +105,7 @@ public class OrderTools implements ToolObject {
|
||||
@ToolParam(required = false, description = "页码,从 1 开始,默认 1") Integer page,
|
||||
@ToolParam(required = false, description = "每页条数,默认 20,上限 100(超出截断为 100)") Integer rows) {
|
||||
Date startTime = parseDate(startOrderTime, "startOrderTime");
|
||||
Date endTime = parseDate(endOrderTime, "endOrderTime");
|
||||
Date endTimeExclusive = parseNextDayStart(endOrderTime, "endOrderTime");
|
||||
User user = AuthContextHolder.get().getUser();
|
||||
int pageNo = page == null || page < 1 ? 1 : page;
|
||||
boolean truncated = rows != null && rows > MAX_ROWS;
|
||||
@@ -124,8 +134,8 @@ public class OrderTools implements ToolObject {
|
||||
if (startTime != null) {
|
||||
wrapper.ge(MallGoodsOrder::getOrderTime, startTime);
|
||||
}
|
||||
if (endTime != null) {
|
||||
wrapper.le(MallGoodsOrder::getOrderTime, endOfDay(endTime));
|
||||
if (endTimeExclusive != null) {
|
||||
wrapper.lt(MallGoodsOrder::getOrderTime, endTimeExclusive);
|
||||
}
|
||||
permissionService.applyOrderRowFilter(wrapper, user);
|
||||
|
||||
@@ -142,13 +152,12 @@ public class OrderTools implements ToolObject {
|
||||
|
||||
Map<Long, String> agentJinideNames = agentJinideNames(orders);
|
||||
Map<Long, String> propertyJinideNames = propertyJinideNames(orders);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
List<Map<String, Object>> records = new ArrayList<>();
|
||||
for (MallGoodsOrder order : orders) {
|
||||
Map<String, Object> record = new LinkedHashMap<>();
|
||||
record.put("id", order.getId());
|
||||
record.put("orderNo", order.getOrderNo());
|
||||
record.put("orderTime", order.getOrderTime() == null ? null : sdf.format(order.getOrderTime()));
|
||||
record.put("orderTime", order.getOrderTime() == null ? null : formatTime(order.getOrderTime()));
|
||||
record.put("orderType", order.getOrderType());
|
||||
record.put("agentName", order.getAgentName());
|
||||
record.put("propertyName", order.getPropertyName());
|
||||
@@ -206,11 +215,10 @@ public class OrderTools implements ToolObject {
|
||||
.eq(MallOrderDetails::getOrderNo, orderNo)
|
||||
.orderByAsc(MallOrderDetails::getId));
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Map<String, Object> record = new LinkedHashMap<>();
|
||||
record.put("id", order.getId());
|
||||
record.put("orderNo", order.getOrderNo());
|
||||
record.put("orderTime", order.getOrderTime() == null ? null : sdf.format(order.getOrderTime()));
|
||||
record.put("orderTime", order.getOrderTime() == null ? null : formatTime(order.getOrderTime()));
|
||||
record.put("orderType", order.getOrderType());
|
||||
record.put("agentId", order.getAgentId());
|
||||
record.put("agentName", order.getAgentName());
|
||||
@@ -237,11 +245,11 @@ public class OrderTools implements ToolObject {
|
||||
record.put("warehouseState", order.getWarehouseState());
|
||||
record.put("orderInvoiceState", order.getOrderInvoiceState());
|
||||
record.put("payNo", order.getPayNo());
|
||||
record.put("payTime", order.getPayTime() == null ? null : sdf.format(order.getPayTime()));
|
||||
record.put("receiptTime", order.getReceiptTime() == null ? null : sdf.format(order.getReceiptTime()));
|
||||
record.put("signTime", order.getSignTime() == null ? null : sdf.format(order.getSignTime()));
|
||||
record.put("payTime", order.getPayTime() == null ? null : formatTime(order.getPayTime()));
|
||||
record.put("receiptTime", order.getReceiptTime() == null ? null : formatTime(order.getReceiptTime()));
|
||||
record.put("signTime", order.getSignTime() == null ? null : formatTime(order.getSignTime()));
|
||||
record.put("memo", order.getMemo());
|
||||
record.put("createTime", order.getCreateTime() == null ? null : sdf.format(order.getCreateTime()));
|
||||
record.put("createTime", order.getCreateTime() == null ? null : formatTime(order.getCreateTime()));
|
||||
record.put("reveiveName", address == null ? null : address.getReveiveName());
|
||||
record.put("reveiveNumber", address == null ? null : address.getReveiveNumber());
|
||||
record.put("province", address == null ? null : address.getProvince());
|
||||
@@ -302,7 +310,6 @@ public class OrderTools implements ToolObject {
|
||||
.last("LIMIT 1"));
|
||||
MallOrderLogistics logistics = logisticsList.isEmpty() ? null : logisticsList.get(0);
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
if (logistics == null) {
|
||||
result.put("logistics", null);
|
||||
} else {
|
||||
@@ -313,7 +320,7 @@ public class OrderTools implements ToolObject {
|
||||
logisticsMap.put("state", logistics.getState());
|
||||
logisticsMap.put("deliverName", logistics.getDeliverName());
|
||||
logisticsMap.put("deliverNumber", logistics.getDeliverNumber());
|
||||
logisticsMap.put("sendTime", logistics.getModifyTime() == null ? null : sdf.format(logistics.getModifyTime()));
|
||||
logisticsMap.put("sendTime", logistics.getModifyTime() == null ? null : formatTime(logistics.getModifyTime()));
|
||||
logisticsMap.put("receivingGoodsName", logistics.getReceivingGoodsName());
|
||||
logisticsMap.put("reveiveName", logistics.getReveiveName());
|
||||
logisticsMap.put("reveiveNumber", logistics.getReveiveNumber());
|
||||
@@ -333,7 +340,7 @@ public class OrderTools implements ToolObject {
|
||||
track.put("memo", detai.getMemo());
|
||||
track.put("state", detai.getState());
|
||||
track.put("picList", detai.getPicList());
|
||||
track.put("createTime", detai.getCreateTime() == null ? null : sdf.format(detai.getCreateTime()));
|
||||
track.put("createTime", detai.getCreateTime() == null ? null : formatTime(detai.getCreateTime()));
|
||||
tracks.add(track);
|
||||
}
|
||||
result.put("tracks", tracks);
|
||||
@@ -386,20 +393,34 @@ public class OrderTools implements ToolObject {
|
||||
property -> property.getJinideName() == null ? "" : property.getJinideName(), (a, b) -> a));
|
||||
}
|
||||
|
||||
/** 严格校验 yyyy-MM-dd:先正则挡掉尾部垃圾字符,再 STRICT 解析(拒绝 2026-02-30 之类)。 */
|
||||
private static Date parseDate(String value, String name) {
|
||||
LocalDate date = parseLocalDate(value, name);
|
||||
return date == null ? null : Date.from(date.atStartOfDay(BUSINESS_ZONE).toInstant());
|
||||
}
|
||||
|
||||
/** 结束边界取「< 次日零点」,避免 23:59:59 写法漏掉当天末秒内的记录。 */
|
||||
private static Date parseNextDayStart(String value, String name) {
|
||||
LocalDate date = parseLocalDate(value, name);
|
||||
return date == null ? null : Date.from(date.plusDays(1).atStartOfDay(BUSINESS_ZONE).toInstant());
|
||||
}
|
||||
|
||||
private static LocalDate parseLocalDate(String value, String name) {
|
||||
if (!StringUtils.hasText(value)) {
|
||||
return null;
|
||||
}
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
|
||||
sdf.setLenient(false);
|
||||
String trimmed = value.trim();
|
||||
if (!DATE_PATTERN.matcher(trimmed).matches()) {
|
||||
throw new IllegalArgumentException(name + " 格式必须为 yyyy-MM-dd");
|
||||
}
|
||||
try {
|
||||
return sdf.parse(value.trim());
|
||||
} catch (ParseException e) {
|
||||
return LocalDate.parse(trimmed, DATE_FORMATTER);
|
||||
} catch (DateTimeParseException e) {
|
||||
throw new IllegalArgumentException(name + " 格式必须为 yyyy-MM-dd");
|
||||
}
|
||||
}
|
||||
|
||||
private static Date endOfDay(Date date) {
|
||||
return new Date(date.getTime() + 24L * 3600 * 1000 - 1000);
|
||||
private static String formatTime(Date date) {
|
||||
return TIME_FORMATTER.format(date.toInstant());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -47,6 +49,10 @@ import static org.mockito.Mockito.when;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class OrderToolsTest {
|
||||
|
||||
private static final ZoneId BUSINESS_ZONE = ZoneId.of("Asia/Shanghai");
|
||||
private static final DateTimeFormatter TIME_FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(BUSINESS_ZONE);
|
||||
|
||||
@Mock
|
||||
MallGoodsOrderMapper orderMapper;
|
||||
@Mock
|
||||
@@ -178,7 +184,7 @@ class OrderToolsTest {
|
||||
assertEquals("13800000000", record.get("reveiveNumber"));
|
||||
assertEquals("南山区", record.get("countyseat"));
|
||||
assertEquals("科技园 1 栋", record.get("address"));
|
||||
assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(1700000000000L)),
|
||||
assertEquals(TIME_FORMATTER.format(new Date(1700000000000L).toInstant()),
|
||||
record.get("orderTime"));
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> items = (List<Map<String, Object>>) result.get("items");
|
||||
@@ -239,7 +245,7 @@ class OrderToolsTest {
|
||||
List<Map<String, Object>> tracks = (List<Map<String, Object>>) result.get("tracks");
|
||||
assertEquals(1, tracks.size());
|
||||
assertEquals("包裹已到达深圳转运中心", tracks.get(0).get("memo"));
|
||||
assertEquals(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(1700000200000L)),
|
||||
assertEquals(TIME_FORMATTER.format(new Date(1700000200000L).toInstant()),
|
||||
tracks.get(0).get("createTime"));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -254,6 +260,47 @@ class OrderToolsTest {
|
||||
verify(permissionService).applyOrderRowFilter(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void listAppliesDateRangeInShanghaiZoneWithExclusiveEnd() {
|
||||
when(orderMapper.selectCount(any())).thenReturn(0L);
|
||||
when(orderMapper.selectList(any())).thenReturn(List.of());
|
||||
|
||||
Map<String, Object> result = tools.mallOrderListQuery(
|
||||
null, null, null, null, null, null, "2026-09-01", "2026-09-09", null, null);
|
||||
|
||||
assertEquals(0L, result.get("total"));
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<LambdaQueryWrapper<MallGoodsOrder>> captor = ArgumentCaptor.forClass(LambdaQueryWrapper.class);
|
||||
verify(orderMapper).selectList(captor.capture());
|
||||
LambdaQueryWrapper<MallGoodsOrder> wrapper = captor.getValue();
|
||||
String where = wrapper.getSqlSegment();
|
||||
assertTrue(where.contains("order_time >="));
|
||||
assertTrue(where.contains("order_time <"));
|
||||
Date expectedStart = Date.from(LocalDate.of(2026, 9, 1).atStartOfDay(BUSINESS_ZONE).toInstant());
|
||||
// 结束边界为「< 次日零点」(Asia/Shanghai),而非 <= 当天 23:59:59
|
||||
Date expectedEndExclusive = Date.from(LocalDate.of(2026, 9, 10).atStartOfDay(BUSINESS_ZONE).toInstant());
|
||||
assertTrue(wrapper.getParamNameValuePairs().values().contains(expectedStart));
|
||||
assertTrue(wrapper.getParamNameValuePairs().values().contains(expectedEndExclusive));
|
||||
}
|
||||
|
||||
@Test
|
||||
void listRejectsDateParamWithTrailingJunk() {
|
||||
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () ->
|
||||
tools.mallOrderListQuery(null, null, null, null, null, null, "2026-09-09junk", null, null, null));
|
||||
assertEquals("startOrderTime 格式必须为 yyyy-MM-dd", ex.getMessage());
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
tools.mallOrderListQuery(null, null, null, null, null, null, null, "2026-9-9", null, null));
|
||||
verifyNoInteractions(orderMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void listRejectsNonexistentCalendarDate() {
|
||||
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () ->
|
||||
tools.mallOrderListQuery(null, null, null, null, null, null, null, "2026-02-30", null, null));
|
||||
assertEquals("endOrderTime 格式必须为 yyyy-MM-dd", ex.getMessage());
|
||||
verifyNoInteractions(orderMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void detailAndLogisticsRequireOrderNo() {
|
||||
assertThrows(IllegalArgumentException.class, () -> tools.mallOrderDetailQuery(null));
|
||||
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
package me.iiv.agent.permission;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import me.iiv.agent.entity.m0.Agent;
|
||||
import me.iiv.agent.entity.m0.AgentManageDistrictAuth;
|
||||
import me.iiv.agent.entity.m0.Authority;
|
||||
import me.iiv.agent.entity.m0.Properyt;
|
||||
import me.iiv.agent.entity.m0.User;
|
||||
import me.iiv.agent.entity.m1.MallGoodsOrder;
|
||||
import me.iiv.agent.entity.m2.WarehouseAgentAuth;
|
||||
import me.iiv.agent.mapper.m0.AgentManageDistrictAuthMapper;
|
||||
import me.iiv.agent.mapper.m0.AgentMapper;
|
||||
import me.iiv.agent.mapper.m0.AuthorityMapper;
|
||||
import me.iiv.agent.mapper.m0.ProperytMapper;
|
||||
import me.iiv.agent.mapper.m2.WarehouseAgentAuthMapper;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/** PermissionService.applyOrderRowFilter 直接单测:商城订单(mall_goods_order)行级权限各分支。 */
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PermissionServiceOrderRowFilterTest {
|
||||
|
||||
@Mock
|
||||
AuthorityMapper authorityMapper;
|
||||
@Mock
|
||||
AgentMapper agentMapper;
|
||||
@Mock
|
||||
WarehouseAgentAuthMapper warehouseAgentAuthMapper;
|
||||
@Mock
|
||||
AgentManageDistrictAuthMapper agentManageDistrictAuthMapper;
|
||||
@Mock
|
||||
ProperytMapper properytMapper;
|
||||
@Mock
|
||||
StringRedisTemplate redisTemplate;
|
||||
@Mock
|
||||
HashOperations<String, Object, Object> hashOperations;
|
||||
|
||||
PermissionService permissionService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""),
|
||||
MallGoodsOrder.class);
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), ""),
|
||||
Properyt.class);
|
||||
permissionService = new PermissionService(authorityMapper, agentMapper,
|
||||
warehouseAgentAuthMapper, agentManageDistrictAuthMapper, properytMapper, redisTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
void headquartersOrderFilterAddsNoBoundary() {
|
||||
User user = user(46L, 1L, null);
|
||||
when(authorityMapper.selectById(1L)).thenReturn(authority(1L, 0));
|
||||
|
||||
LambdaQueryWrapper<MallGoodsOrder> wrapper = new LambdaQueryWrapper<>();
|
||||
permissionService.applyOrderRowFilter(wrapper, user);
|
||||
|
||||
assertTrue(wrapper.getSqlSegment().isBlank());
|
||||
}
|
||||
|
||||
@Test
|
||||
void agentOrderFilterUsesSelfSubordinateAndManagedSaleCompanies() {
|
||||
User user = user(1000L, 108L, 1L);
|
||||
when(authorityMapper.selectById(108L)).thenReturn(authority(108L, 1));
|
||||
Agent subordinate = new Agent();
|
||||
subordinate.setId(2L);
|
||||
when(agentMapper.selectList(any())).thenReturn(List.of(subordinate));
|
||||
WarehouseAgentAuth managedAuth = new WarehouseAgentAuth();
|
||||
managedAuth.setManagerAgentId(3L);
|
||||
when(warehouseAgentAuthMapper.selectList(any())).thenReturn(List.of(managedAuth));
|
||||
when(agentManageDistrictAuthMapper.selectList(any())).thenReturn(List.of());
|
||||
|
||||
LambdaQueryWrapper<MallGoodsOrder> wrapper = new LambdaQueryWrapper<>();
|
||||
permissionService.applyOrderRowFilter(wrapper, user);
|
||||
|
||||
String sql = wrapper.getSqlSegment();
|
||||
Collection<Object> values = wrapper.getParamNameValuePairs().values();
|
||||
assertTrue(sql.contains("sale_company_id IN"));
|
||||
assertFalse(sql.contains("property_id"));
|
||||
assertTrue(values.contains(1L));
|
||||
assertTrue(values.contains(2L));
|
||||
assertTrue(values.contains(3L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void agentOrderFilterAddsManagedPropertyOrBranch() {
|
||||
User user = user(1000L, 108L, 1L);
|
||||
when(authorityMapper.selectById(108L)).thenReturn(authority(108L, 1));
|
||||
when(agentMapper.selectList(any())).thenReturn(List.of());
|
||||
when(warehouseAgentAuthMapper.selectList(any())).thenReturn(List.of());
|
||||
AgentManageDistrictAuth districtAuth = new AgentManageDistrictAuth();
|
||||
districtAuth.setPropertyId(44L);
|
||||
when(agentManageDistrictAuthMapper.selectList(any())).thenReturn(List.of(districtAuth));
|
||||
|
||||
LambdaQueryWrapper<MallGoodsOrder> wrapper = new LambdaQueryWrapper<>();
|
||||
permissionService.applyOrderRowFilter(wrapper, user);
|
||||
|
||||
String sql = wrapper.getSqlSegment();
|
||||
Collection<Object> values = wrapper.getParamNameValuePairs().values();
|
||||
assertTrue(sql.contains("sale_company_id IN"));
|
||||
assertTrue(sql.contains("property_id IN"));
|
||||
assertTrue(sql.contains("OR"));
|
||||
assertTrue(values.contains(1L));
|
||||
assertTrue(values.contains(44L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void salesNonLeaderOrderFilterUsesOwnCreatedPropertyIds() {
|
||||
User user = user(1000L, 108L, 1L);
|
||||
user.setDeptId(5L);
|
||||
user.setPostId(7L);
|
||||
when(authorityMapper.selectById(108L)).thenReturn(authority(108L, 1));
|
||||
when(agentMapper.selectList(any())).thenReturn(List.of());
|
||||
when(warehouseAgentAuthMapper.selectList(any())).thenReturn(List.of());
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(hashOperations.get("Dictionary", "authDeptId")).thenReturn(",5,");
|
||||
when(hashOperations.get("Dictionary", "authDeptPostId")).thenReturn("8,");
|
||||
Properyt property = new Properyt();
|
||||
property.setId(55L);
|
||||
when(properytMapper.selectList(any())).thenReturn(List.of(property));
|
||||
|
||||
LambdaQueryWrapper<MallGoodsOrder> wrapper = new LambdaQueryWrapper<>();
|
||||
permissionService.applyOrderRowFilter(wrapper, user);
|
||||
|
||||
String sql = wrapper.getSqlSegment();
|
||||
assertTrue(sql.contains("property_id IN"));
|
||||
assertFalse(sql.contains("sale_company_id"));
|
||||
assertTrue(wrapper.getParamNameValuePairs().values().contains(55L));
|
||||
verifyNoInteractions(agentManageDistrictAuthMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void salesNonLeaderWithoutVisiblePropertiesFiltersToZero() {
|
||||
User user = user(1000L, 108L, 1L);
|
||||
user.setDeptId(5L);
|
||||
user.setPostId(7L);
|
||||
when(authorityMapper.selectById(108L)).thenReturn(authority(108L, 1));
|
||||
when(agentMapper.selectList(any())).thenReturn(List.of());
|
||||
when(warehouseAgentAuthMapper.selectList(any())).thenReturn(List.of());
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(hashOperations.get("Dictionary", "authDeptId")).thenReturn(",5,");
|
||||
when(hashOperations.get("Dictionary", "authDeptPostId")).thenReturn("8,");
|
||||
when(properytMapper.selectList(any())).thenReturn(List.of());
|
||||
|
||||
LambdaQueryWrapper<MallGoodsOrder> wrapper = new LambdaQueryWrapper<>();
|
||||
permissionService.applyOrderRowFilter(wrapper, user);
|
||||
|
||||
String sql = wrapper.getSqlSegment();
|
||||
assertTrue(sql.contains("property_id IN"));
|
||||
assertFalse(sql.contains("sale_company_id"));
|
||||
assertTrue(wrapper.getParamNameValuePairs().values().contains(0L));
|
||||
verifyNoInteractions(agentManageDistrictAuthMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
void agentUserWithoutAgentIdIsDeniedForOrderFilter() {
|
||||
User user = user(1000L, 108L, null);
|
||||
when(authorityMapper.selectById(108L)).thenReturn(authority(108L, 1));
|
||||
|
||||
assertThrows(IllegalStateException.class,
|
||||
() -> permissionService.applyOrderRowFilter(new LambdaQueryWrapper<>(), user));
|
||||
}
|
||||
|
||||
private static Authority authority(Long id, int isAgent) {
|
||||
Authority authority = new Authority();
|
||||
authority.setId(id);
|
||||
authority.setIsagent(isAgent);
|
||||
authority.setSoftDelete(0);
|
||||
return authority;
|
||||
}
|
||||
|
||||
private static User user(Long id, Long authorityId, Long agentId) {
|
||||
User user = new User();
|
||||
user.setId(id);
|
||||
user.setAuthorityId(authorityId);
|
||||
user.setAgentId(agentId);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user