feat(aihr): allow employees to complete onboarding tasks
This commit is contained in:
+9
@@ -15,6 +15,7 @@ import org.dromara.aihr.domain.AihrPracticeDto.PracticeAssignmentRequest;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.PracticeAssignmentResponse;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.PracticeTeamResponse;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.OnboardTaskResponse;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.OnboardTaskCompleteRequest;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.PromotionEvidenceResponse;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.QualificationResponse;
|
||||
import org.dromara.aihr.domain.AihrPracticeDto.RecordResponse;
|
||||
@@ -205,6 +206,14 @@ public class AihrMobileController {
|
||||
return R.ok(mobileSeedService.onboardTasks(ownMobileExtPartyId(null)));
|
||||
}
|
||||
|
||||
@PostMapping("/onboard/tasks/{id}/complete")
|
||||
public R<Void> completeOnboardTask(@PathVariable Long id,
|
||||
@RequestBody(required = false) OnboardTaskCompleteRequest request) {
|
||||
String identity = ownMobileExtPartyId(null);
|
||||
String evidenceRef = request == null ? null : request.evidenceRef();
|
||||
return mobileSeedService.completeOnboardTask(id, identity, evidenceRef) ? R.ok() : R.fail("任务不存在、已完成或无权操作");
|
||||
}
|
||||
|
||||
@GetMapping("/qualification")
|
||||
public R<QualificationResponse> qualification() {
|
||||
return R.ok(mobileSeedService.qualification(ownMobileExtPartyId(null)));
|
||||
|
||||
+3
@@ -293,6 +293,9 @@ public final class AihrPracticeDto {
|
||||
) {
|
||||
}
|
||||
|
||||
public record OnboardTaskCompleteRequest(String evidenceRef) {
|
||||
}
|
||||
|
||||
public record QualificationGateResponse(
|
||||
Long id,
|
||||
String projectCode,
|
||||
|
||||
+4
@@ -172,6 +172,10 @@ public class AihrMobileSeedService {
|
||||
return practiceSeedService.onboardTasks(extPartyId, 20);
|
||||
}
|
||||
|
||||
public boolean completeOnboardTask(Long taskId, String extPartyId, String evidenceRef) {
|
||||
return practiceSeedService.completeOnboardTask(taskId, extPartyId, evidenceRef);
|
||||
}
|
||||
|
||||
public QualificationResponse qualification(String extPartyId) {
|
||||
return practiceSeedService.qualification(extPartyId);
|
||||
}
|
||||
|
||||
+32
@@ -2086,6 +2086,38 @@ public class AihrPracticeSeedService {
|
||||
), args.toArray());
|
||||
}
|
||||
|
||||
public boolean completeOnboardTask(Long taskId, String extPartyId, String evidenceRef) {
|
||||
String identity = isBlank(extPartyId) ? "" : extPartyId.trim();
|
||||
if (taskId == null || taskId <= 0 || identity.isEmpty() || !formalPositionTablesExist("aihr_onboard_task")) {
|
||||
return false;
|
||||
}
|
||||
String normalizedEvidenceRef = isBlank(evidenceRef) ? null : evidenceRef.trim();
|
||||
if (normalizedEvidenceRef != null && normalizedEvidenceRef.length() > 500) {
|
||||
normalizedEvidenceRef = normalizedEvidenceRef.substring(0, 500);
|
||||
}
|
||||
boolean hasOrgSnapshot = orgSnapshotTableExists() && orgSnapshotColumnExists("person_phone");
|
||||
String identityPredicate = hasOrgSnapshot
|
||||
? "(ext_party_id = ? OR ext_party_id IN (SELECT o.ext_party_id FROM aihr_org_snapshot o WHERE o.tenant_id = ? AND o.employment_status = 'active' AND (o.ext_party_id = ? OR o.person_phone = ?)))"
|
||||
: "ext_party_id = ?";
|
||||
List<Object> args = new ArrayList<>();
|
||||
args.add(normalizedEvidenceRef);
|
||||
args.add(tenantId());
|
||||
args.add(taskId);
|
||||
args.add(identity);
|
||||
if (hasOrgSnapshot) {
|
||||
args.add(tenantId());
|
||||
args.add(identity);
|
||||
args.add(identity);
|
||||
}
|
||||
return jdbcTemplate.update("""
|
||||
UPDATE aihr_onboard_task
|
||||
SET status = '已完成', completed_time = now(),
|
||||
evidence_ref = COALESCE(NULLIF(?, ''), evidence_ref), update_time = now()
|
||||
WHERE tenant_id = ? AND id = ? AND %s
|
||||
AND status IN ('待完成', '进行中')
|
||||
""".formatted(identityPredicate), args.toArray()) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return qualification evidence for the current APP user without treating an
|
||||
* empty rules table as a pass. Formal qualification remains NOT_CONFIGURED until
|
||||
|
||||
+3
-2
@@ -660,7 +660,7 @@ public class AihrPracticeSeedServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formalOnboardingReadsAreLoginScopedAndReadOnly() throws Exception {
|
||||
public void formalOnboardingReadsAndCompletionAreLoginScoped() throws Exception {
|
||||
Path source = Path.of("src/main/java/org/dromara/aihr/controller/AihrMobileController.java");
|
||||
if (!Files.exists(source)) {
|
||||
source = Path.of("ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/controller/AihrMobileController.java");
|
||||
@@ -672,7 +672,8 @@ public class AihrPracticeSeedServiceTest {
|
||||
assertTrue(controllerSource.contains("@GetMapping(\"/qualification\")"));
|
||||
assertTrue(controllerSource.contains("mobileSeedService.onboardTasks(ownMobileExtPartyId(null))"));
|
||||
assertTrue(controllerSource.contains("mobileSeedService.qualification(ownMobileExtPartyId(null))"));
|
||||
assertFalse(controllerSource.contains("@PostMapping(\"/onboard/tasks\")"));
|
||||
assertTrue(controllerSource.contains("@PostMapping(\"/onboard/tasks/{id}/complete\")"));
|
||||
assertTrue(controllerSource.contains("mobileSeedService.completeOnboardTask(id, identity, evidenceRef)"));
|
||||
assertFalse(controllerSource.contains("@PostMapping(\"/qualification\")"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user