修复访问统计部门名称变动,统计部门名称未变动的问题

This commit is contained in:
zjf committed 2026-05-26 18:27:02 +08:00
1 parent 1fb4ca2515
commit 402d9fa5c3
2 files changed
+234 -220

No files matched your search

@@ -1,217 +1,217 @@
package com.bsd.pjcloud.canteen.controller;
import com.bsd.pjcloud.canteen.service.CanteenDeliveryOrderService;
import com.bsd.pjcloud.canteen.vo.app.CanteenDeliveryOrderAppVO;
import com.bsd.pjcloud.common.core.constant.SecurityConstants;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.common.security.service.PjcloudUser;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.web.servlet.MockMvc;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.Collections;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* 本地可跑:不连库、不连 Nacos,仅校验 Controller 入参与路由。
* <pre>
* cd pjcloud-canteen/pjcloud-canteen-biz
* mvn test -Dtest=CanteenDeliveryOrderControllerTest
* </pre>
*/
@WebMvcTest(controllers = CanteenDeliveryOrderController.class)
@AutoConfigureMockMvc(addFilters = false)
class CanteenDeliveryOrderControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private CanteenDeliveryOrderService canteenDeliveryOrderService;
private static final long RIDER_USER_ID = 9001L;
@BeforeEach
void loginRider() {
PjcloudUser rider = new PjcloudUser(
RIDER_USER_ID,
"rider_test",
1L,
"13800000000",
null,
null,
"测试骑手",
null,
1L,
"nop",
true,
true,
null,
true,
true,
Collections.emptyList());
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(rider, rider.getPassword(), rider.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
}
@AfterEach
void clearSecurity() {
SecurityContextHolder.clearContext();
}
@Test
void innerSyncFromOrder_ok() throws Exception {
when(canteenDeliveryOrderService.syncFromOrder(any())).thenReturn(R.ok(12345L));
String body = """
{"id":"TEST-ORDER-001","deptId":100}
""";
mockMvc.perform(post("/canteenDeliveryOrder/inner/sync-from-order")
.header(SecurityConstants.FROM, SecurityConstants.FROM_IN)
.contentType(MediaType.APPLICATION_JSON)
.content(body))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(true))
.andExpect(jsonPath("$.data").value(12345));
verify(canteenDeliveryOrderService).syncFromOrder(any());
}
@Test
void innerSyncFromOrder_validationFail() throws Exception {
mockMvc.perform(post("/canteenDeliveryOrder/inner/sync-from-order")
.header(SecurityConstants.FROM, SecurityConstants.FROM_IN)
.contentType(MediaType.APPLICATION_JSON)
.content("{}"))
.andExpect(status().isBadRequest());
}
@Test
void innerCancel_ok() throws Exception {
when(canteenDeliveryOrderService.cancelBySourceOrderId("TEST-ORDER-001")).thenReturn(R.ok());
mockMvc.perform(post("/canteenDeliveryOrder/inner/cancel-by-source-id")
.header(SecurityConstants.FROM, SecurityConstants.FROM_IN)
.param("sourceOrderId", "TEST-ORDER-001"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(true));
verify(canteenDeliveryOrderService).cancelBySourceOrderId("TEST-ORDER-001");
}
@Test
void appList_delegatesToService() throws Exception {
// CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
// vo.setId(1L);
// vo.setSourceOrderId("SO-1");
// when(canteenDeliveryOrderService.listForRider(RIDER_USER_ID, "pending")).thenReturn(List.of(vo));
//package com.bsd.pjcloud.canteen.controller;
//
// mockMvc.perform(get("/canteenDeliveryOrder/app/list").param("tab", "pending"))
//import com.bsd.pjcloud.canteen.service.CanteenDeliveryOrderService;
//import com.bsd.pjcloud.canteen.vo.app.CanteenDeliveryOrderAppVO;
//import com.bsd.pjcloud.common.core.constant.SecurityConstants;
//import com.bsd.pjcloud.common.core.util.R;
//import com.bsd.pjcloud.common.security.service.PjcloudUser;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import org.junit.jupiter.api.AfterEach;
//import org.junit.jupiter.api.BeforeEach;
//import org.junit.jupiter.api.Test;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
//import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
//import org.springframework.boot.test.mock.mockito.MockBean;
//import org.springframework.http.MediaType;
//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.test.web.servlet.MockMvc;
//
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//
//import java.util.Collections;
//import java.util.List;
//
//import static org.mockito.ArgumentMatchers.any;
//import static org.mockito.ArgumentMatchers.eq;
//import static org.mockito.Mockito.verify;
//import static org.mockito.Mockito.when;
//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
//
///**
// * 本地可跑:不连库、不连 Nacos,仅校验 Controller 入参与路由。
// * <pre>
// * cd pjcloud-canteen/pjcloud-canteen-biz
// * mvn test -Dtest=CanteenDeliveryOrderControllerTest
// * </pre>
// */
//@WebMvcTest(controllers = CanteenDeliveryOrderController.class)
//@AutoConfigureMockMvc(addFilters = false)
//class CanteenDeliveryOrderControllerTest {
//
// @Autowired
// private MockMvc mockMvc;
//
// @Autowired
// private ObjectMapper objectMapper;
//
// @MockBean
// private CanteenDeliveryOrderService canteenDeliveryOrderService;
//
// private static final long RIDER_USER_ID = 9001L;
//
// @BeforeEach
// void loginRider() {
// PjcloudUser rider = new PjcloudUser(
// RIDER_USER_ID,
// "rider_test",
// 1L,
// "13800000000",
// null,
// null,
// "测试骑手",
// null,
// 1L,
// "nop",
// true,
// true,
// null,
// true,
// true,
// Collections.emptyList());
// UsernamePasswordAuthenticationToken auth =
// new UsernamePasswordAuthenticationToken(rider, rider.getPassword(), rider.getAuthorities());
// SecurityContextHolder.getContext().setAuthentication(auth);
// }
//
// @AfterEach
// void clearSecurity() {
// SecurityContextHolder.clearContext();
// }
//
// @Test
// void innerSyncFromOrder_ok() throws Exception {
// when(canteenDeliveryOrderService.syncFromOrder(any())).thenReturn(R.ok(12345L));
//
// String body = """
// {"id":"TEST-ORDER-001","deptId":100}
// """;
//
// mockMvc.perform(post("/canteenDeliveryOrder/inner/sync-from-order")
// .header(SecurityConstants.FROM, SecurityConstants.FROM_IN)
// .contentType(MediaType.APPLICATION_JSON)
// .content(body))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(true))
// .andExpect(jsonPath("$.data[0].id").value(1))
// .andExpect(jsonPath("$.data[0].sourceOrderId").value("SO-1"));
// .andExpect(jsonPath("$.data").value(12345));
//
// verify(canteenDeliveryOrderService).listForRider(RIDER_USER_ID, "pending");
}
@Test
void appDetail_ok() throws Exception {
CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
vo.setId(99L);
when(canteenDeliveryOrderService.detailForRider(eq(RIDER_USER_ID), eq(99L))).thenReturn(vo);
mockMvc.perform(get("/canteenDeliveryOrder/app/99"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(true))
.andExpect(jsonPath("$.data.id").value(99));
}
@Test
void appDetail_notFound() throws Exception {
when(canteenDeliveryOrderService.detailForRider(eq(RIDER_USER_ID), eq(404L))).thenReturn(null);
mockMvc.perform(get("/canteenDeliveryOrder/app/404"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(false));
}
@Test
void mchAppList_delegatesToService() throws Exception {
CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
vo.setId(2L);
vo.setSourceOrderId("SO-MCH");
Page<CanteenDeliveryOrderAppVO> page = new Page<>(1, 10, 1);
page.setRecords(List.of(vo));
when(canteenDeliveryOrderService.pageForMerchantApp(eq("pending"), any(Page.class))).thenReturn(R.ok(page));
mockMvc.perform(get("/canteenDeliveryOrder/app/mch/list").param("tab", "pending"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(true))
.andExpect(jsonPath("$.data.records[0].id").value(2))
.andExpect(jsonPath("$.data.records[0].sourceOrderId").value("SO-MCH"));
verify(canteenDeliveryOrderService).pageForMerchantApp(eq("pending"), any(Page.class));
}
@Test
void mchAppDetail_ok() throws Exception {
CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
vo.setId(88L);
when(canteenDeliveryOrderService.detailForMerchantApp(88L)).thenReturn(R.ok(vo));
mockMvc.perform(get("/canteenDeliveryOrder/app/mch/88"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(true))
.andExpect(jsonPath("$.data.id").value(88));
}
@Test
void pickup_ok() throws Exception {
when(canteenDeliveryOrderService.pickup(eq(RIDER_USER_ID), any())).thenReturn(R.ok());
mockMvc.perform(post("/canteenDeliveryOrder/app/pickup")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(
java.util.Map.of("id", 1L, "photoUrl", "https://example.com/a.jpg"))))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(true));
}
@Test
void deliver_ok() throws Exception {
when(canteenDeliveryOrderService.deliver(eq(RIDER_USER_ID), any())).thenReturn(R.ok());
mockMvc.perform(post("/canteenDeliveryOrder/app/deliver")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(
java.util.Map.of("id", 1L, "photoUrl", "https://example.com/b.jpg"))))
.andExpect(status().isOk())
.andExpect(jsonPath("$.ok").value(true));
}
}
// verify(canteenDeliveryOrderService).syncFromOrder(any());
// }
//
// @Test
// void innerSyncFromOrder_validationFail() throws Exception {
// mockMvc.perform(post("/canteenDeliveryOrder/inner/sync-from-order")
// .header(SecurityConstants.FROM, SecurityConstants.FROM_IN)
// .contentType(MediaType.APPLICATION_JSON)
// .content("{}"))
// .andExpect(status().isBadRequest());
// }
//
// @Test
// void innerCancel_ok() throws Exception {
// when(canteenDeliveryOrderService.cancelBySourceOrderId("TEST-ORDER-001")).thenReturn(R.ok());
//
// mockMvc.perform(post("/canteenDeliveryOrder/inner/cancel-by-source-id")
// .header(SecurityConstants.FROM, SecurityConstants.FROM_IN)
// .param("sourceOrderId", "TEST-ORDER-001"))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(true));
//
// verify(canteenDeliveryOrderService).cancelBySourceOrderId("TEST-ORDER-001");
// }
//
// @Test
// void appList_delegatesToService() throws Exception {
//// CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
//// vo.setId(1L);
//// vo.setSourceOrderId("SO-1");
//// when(canteenDeliveryOrderService.listForRider(RIDER_USER_ID, "pending")).thenReturn(List.of(vo));
////
//// mockMvc.perform(get("/canteenDeliveryOrder/app/list").param("tab", "pending"))
//// .andExpect(status().isOk())
//// .andExpect(jsonPath("$.ok").value(true))
//// .andExpect(jsonPath("$.data[0].id").value(1))
//// .andExpect(jsonPath("$.data[0].sourceOrderId").value("SO-1"));
////
//// verify(canteenDeliveryOrderService).listForRider(RIDER_USER_ID, "pending");
// }
//
// @Test
// void appDetail_ok() throws Exception {
// CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
// vo.setId(99L);
// when(canteenDeliveryOrderService.detailForRider(eq(RIDER_USER_ID), eq(99L))).thenReturn(vo);
//
// mockMvc.perform(get("/canteenDeliveryOrder/app/99"))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(true))
// .andExpect(jsonPath("$.data.id").value(99));
// }
//
// @Test
// void appDetail_notFound() throws Exception {
// when(canteenDeliveryOrderService.detailForRider(eq(RIDER_USER_ID), eq(404L))).thenReturn(null);
//
// mockMvc.perform(get("/canteenDeliveryOrder/app/404"))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(false));
// }
//
// @Test
// void mchAppList_delegatesToService() throws Exception {
// CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
// vo.setId(2L);
// vo.setSourceOrderId("SO-MCH");
// Page<CanteenDeliveryOrderAppVO> page = new Page<>(1, 10, 1);
// page.setRecords(List.of(vo));
// when(canteenDeliveryOrderService.pageForMerchantApp(eq("pending"), any(Page.class))).thenReturn(R.ok(page));
//
// mockMvc.perform(get("/canteenDeliveryOrder/app/mch/list").param("tab", "pending"))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(true))
// .andExpect(jsonPath("$.data.records[0].id").value(2))
// .andExpect(jsonPath("$.data.records[0].sourceOrderId").value("SO-MCH"));
//
// verify(canteenDeliveryOrderService).pageForMerchantApp(eq("pending"), any(Page.class));
// }
//
// @Test
// void mchAppDetail_ok() throws Exception {
// CanteenDeliveryOrderAppVO vo = new CanteenDeliveryOrderAppVO();
// vo.setId(88L);
// when(canteenDeliveryOrderService.detailForMerchantApp(88L)).thenReturn(R.ok(vo));
//
// mockMvc.perform(get("/canteenDeliveryOrder/app/mch/88"))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(true))
// .andExpect(jsonPath("$.data.id").value(88));
// }
//
// @Test
// void pickup_ok() throws Exception {
// when(canteenDeliveryOrderService.pickup(eq(RIDER_USER_ID), any())).thenReturn(R.ok());
//
// mockMvc.perform(post("/canteenDeliveryOrder/app/pickup")
// .contentType(MediaType.APPLICATION_JSON)
// .content(objectMapper.writeValueAsString(
// java.util.Map.of("id", 1L, "photoUrl", "https://example.com/a.jpg"))))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(true));
// }
//
// @Test
// void deliver_ok() throws Exception {
// when(canteenDeliveryOrderService.deliver(eq(RIDER_USER_ID), any())).thenReturn(R.ok());
//
// mockMvc.perform(post("/canteenDeliveryOrder/app/deliver")
// .contentType(MediaType.APPLICATION_JSON)
// .content(objectMapper.writeValueAsString(
// java.util.Map.of("id", 1L, "photoUrl", "https://example.com/b.jpg"))))
// .andExpect(status().isOk())
// .andExpect(jsonPath("$.ok").value(true));
// }
//}
@@ -417,7 +417,7 @@ public class AppAccessStatsServiceImpl implements AppAccessStatsService {
if (dept == null) {
return empty;
}
SysDept unitDept = resolveTopUnitDept(dept);
SysDept unitDept = resolveUnitDept(dept);
Long userTenantId = user.getTenantId();
DimUserOrgSnapshotEntity currentSnapshot = dimUserOrgSnapshotMapper.selectOne(new LambdaQueryWrapper<DimUserOrgSnapshotEntity>()
@@ -431,9 +431,7 @@ public class AppAccessStatsServiceImpl implements AppAccessStatsService {
return toOrgInfo(inserted);
}
boolean changed = !Objects.equals(currentSnapshot.getDeptId(), dept.getDeptId())
|| !Objects.equals(currentSnapshot.getUnitId(), unitDept.getDeptId());
if (changed) {
if (isOrgSnapshotOutdated(currentSnapshot, unitDept, dept)) {
DimUserOrgSnapshotEntity update = new DimUserOrgSnapshotEntity();
update.setSnapshotSk(currentSnapshot.getSnapshotSk());
update.setIsCurrent(0);
@@ -460,13 +458,22 @@ public class AppAccessStatsServiceImpl implements AppAccessStatsService {
return snapshot;
}
private SysDept resolveTopUnitDept(SysDept dept) {
/**
* 解析用户所属单位:从当前部门向上,取最近的 is_unit=1;若无则取组织树顶层。
*/
private SysDept resolveUnitDept(SysDept dept) {
SysDept current = dept;
int guard = 0;
while (current.getParentId() != null && guard < 20) {
while (guard < 20) {
if (current.getIsUnit() != null && current.getIsUnit() == 1) {
return current;
}
if (current.getParentId() == null) {
return current;
}
SysDept parent = sysDeptMapper.selectById(current.getParentId());
if (parent == null) {
break;
return current;
}
current = parent;
guard++;
@@ -474,6 +481,13 @@ public class AppAccessStatsServiceImpl implements AppAccessStatsService {
return current;
}
private boolean isOrgSnapshotOutdated(DimUserOrgSnapshotEntity snapshot, SysDept unitDept, SysDept dept) {
return !Objects.equals(snapshot.getDeptId(), dept.getDeptId())
|| !Objects.equals(snapshot.getUnitId(), unitDept.getDeptId())
|| !Objects.equals(snapshot.getDeptName(), dept.getName())
|| !Objects.equals(snapshot.getUnitName(), unitDept.getName());
}
private OrgInfo toOrgInfo(DimUserOrgSnapshotEntity snapshot) {
OrgInfo info = new OrgInfo();
info.snapshotSk = snapshot.getSnapshotSk();