feat(work-results): support historical project outcomes
This commit is contained in:
+2
-2
@@ -1387,9 +1387,9 @@ public class AihrMemoryService {
|
||||
return new java.util.LinkedHashSet<>(jdbcTemplate.queryForList("""
|
||||
select distinct project_code
|
||||
from aihr_org_snapshot
|
||||
where tenant_id = ? and ext_party_id = ? and employment_status = 'active'
|
||||
where tenant_id = ? and (ext_party_id = ? or person_phone = ?) and employment_status = 'active'
|
||||
and position_level in ('主管', '项目经理')
|
||||
""", String.class, principal.tenantId(), principal.extPartyId()));
|
||||
""", String.class, principal.tenantId(), principal.extPartyId(), principal.extPartyId()));
|
||||
}
|
||||
|
||||
private ServiceMemoryResponse mapServiceMemory(ResultSet rs, List<ServiceMemoryVersionResponse> versions)
|
||||
|
||||
+8
-3
@@ -212,21 +212,26 @@ public class AihrWorkResultService {
|
||||
if (!"app_user".equals(principal.userType())) return;
|
||||
Integer rows = jdbcTemplate.queryForObject("""
|
||||
select count(*) from aihr_org_snapshot
|
||||
where tenant_id = ? and ext_party_id = ? and project_code = ?
|
||||
where tenant_id = ? and (ext_party_id = ? or person_phone = ?) and project_code = ?
|
||||
and employment_status = 'active' and position_level in ('主管', '项目经理')
|
||||
""", Integer.class, principal.tenantId(), principal.extPartyId(), projectCode);
|
||||
""", Integer.class, principal.tenantId(), principal.extPartyId(), principal.extPartyId(), projectCode);
|
||||
if (rows == null || rows < 1) {
|
||||
throw new ServiceException("当前项目没有主管权限", HttpStatus.FORBIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
private static LocalDate workDate(String raw) {
|
||||
LocalDate date;
|
||||
if (raw == null || raw.isBlank()) return LocalDate.now(WORK_ZONE);
|
||||
try {
|
||||
return LocalDate.parse(raw.trim());
|
||||
date = LocalDate.parse(raw.trim());
|
||||
} catch (Exception ex) {
|
||||
throw new ServiceException("workDate 必须为 yyyy-MM-dd", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
if (date.isAfter(LocalDate.now(WORK_ZONE))) {
|
||||
throw new ServiceException("workDate 不能晚于当天", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
private String json(Object value) {
|
||||
|
||||
+22
@@ -9,6 +9,7 @@ import org.dromara.aihr.memory.AihrMemoryDto.ServiceMemoryVersionResponse;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.PreparedStatementCreator;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
@@ -25,6 +26,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
@@ -32,6 +34,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
|
||||
@Tag("dev")
|
||||
class AihrMemoryServiceTest {
|
||||
@@ -159,6 +164,23 @@ class AihrMemoryServiceTest {
|
||||
assertTrue(plan.missingFields().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void phoneMappedSupervisorCanReadProjectCaptureSource() {
|
||||
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
||||
AihrKnowledgePrincipalResolver resolver = mock(AihrKnowledgePrincipalResolver.class);
|
||||
AihrKnowledgePrincipal supervisor = new AihrKnowledgePrincipal(
|
||||
"000000", 7L, "app_user", "13900000101", Set.of("supervisor"), Set.of("P2"), "app");
|
||||
when(resolver.current()).thenReturn(supervisor);
|
||||
ArgumentCaptor<Object[]> projectsArgs = ArgumentCaptor.forClass(Object[].class);
|
||||
when(jdbc.queryForList(anyString(), eq(String.class), projectsArgs.capture())).thenReturn(List.of("P2"));
|
||||
when(jdbc.query(anyString(), any(RowMapper.class), any(Object[].class)))
|
||||
.thenReturn(List.of("{\"ossId\":123}"));
|
||||
AihrMemoryService service = new AihrMemoryService(jdbc, new ObjectMapper(), resolver);
|
||||
|
||||
assertEquals(123L, service.authorizedCaptureSourceOssId(9L));
|
||||
assertArrayEquals(new Object[]{"000000", "13900000101", "13900000101"}, projectsArgs.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void sameConversationLocationFollowupUpgradesOriginalNeedsInputCandidate() throws Exception {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
+39
-1
@@ -8,16 +8,21 @@ import org.dromara.aihr.workresult.AihrWorkResultDto.WorkResultResponse;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
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.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -52,13 +57,46 @@ class AihrWorkResultServiceTest {
|
||||
AihrKnowledgePrincipalResolver resolver = mock(AihrKnowledgePrincipalResolver.class);
|
||||
when(resolver.current()).thenReturn(new AihrKnowledgePrincipal(
|
||||
"000000", 7L, "app_user", "EMP-1", Set.of("employee", "supervisor"), Set.of("P1", "P2"), "app"));
|
||||
when(jdbc.queryForObject(anyString(), any(Class.class), any(Object[].class))).thenReturn(0);
|
||||
ArgumentCaptor<String> sql = ArgumentCaptor.forClass(String.class);
|
||||
when(jdbc.queryForObject(sql.capture(), any(Class.class), any(Object[].class))).thenReturn(0);
|
||||
AihrWorkResultService service = new AihrWorkResultService(jdbc, new ObjectMapper(), resolver);
|
||||
|
||||
ServiceException error = assertThrows(ServiceException.class, () -> service.project("P2", "2026-07-21"));
|
||||
|
||||
assertEquals(403, error.getCode());
|
||||
assertEquals("当前项目没有主管权限", error.getMessage());
|
||||
assertTrue(sql.getValue().contains("ext_party_id = ? or person_phone = ?"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void phoneMappedSupervisorCanReadOwnProject() {
|
||||
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
||||
AihrKnowledgePrincipalResolver resolver = mock(AihrKnowledgePrincipalResolver.class);
|
||||
when(resolver.current()).thenReturn(new AihrKnowledgePrincipal(
|
||||
"000000", 7L, "app_user", "13900000101", Set.of("supervisor"), Set.of("P2"), "app"));
|
||||
ArgumentCaptor<Object[]> args = ArgumentCaptor.forClass(Object[].class);
|
||||
when(jdbc.queryForObject(anyString(), any(Class.class), args.capture())).thenReturn(1);
|
||||
when(jdbc.queryForList(anyString(), any(Class.class), any(Object[].class))).thenReturn(List.of());
|
||||
AihrWorkResultService service = new AihrWorkResultService(jdbc, new ObjectMapper(), resolver);
|
||||
|
||||
service.project("P2", "2026-07-21");
|
||||
|
||||
assertArrayEquals(new Object[]{"000000", "13900000101", "13900000101", "P2"}, args.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void futureWorkDateIsRejectedBeforeAnyWrite() {
|
||||
JdbcTemplate jdbc = mock(JdbcTemplate.class);
|
||||
AihrKnowledgePrincipalResolver resolver = mock(AihrKnowledgePrincipalResolver.class);
|
||||
when(resolver.current()).thenReturn(new AihrKnowledgePrincipal(
|
||||
"000000", 7L, "app_user", "EMP-1", Set.of("employee"), Set.of("P1"), "app"));
|
||||
AihrWorkResultService service = new AihrWorkResultService(jdbc, new ObjectMapper(), resolver);
|
||||
|
||||
ServiceException error = assertThrows(ServiceException.class, () -> service.generateMine("P1",
|
||||
LocalDate.now(ZoneId.of("Asia/Shanghai")).plusDays(1).toString()));
|
||||
|
||||
assertEquals(400, error.getCode());
|
||||
assertEquals("workDate 不能晚于当天", error.getMessage());
|
||||
}
|
||||
|
||||
private static WorkResultResponse response(int version, String generatedAt, String status) {
|
||||
|
||||
Reference in New Issue
Block a user