mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-09 10:00:30 +08:00
feat: add M9 ReportService + ReportController
This commit is contained in:
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package cn.craftlabs.platform.api.report;
|
||||||
|
|
||||||
|
import cn.craftlabs.platform.api.service.ReportService;
|
||||||
|
import cn.craftlabs.platform.api.web.dto.CallbackStatsResponse;
|
||||||
|
import cn.craftlabs.platform.api.web.dto.ContractSnReportRow;
|
||||||
|
import cn.craftlabs.platform.api.web.dto.ProjectHealthRow;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/reports")
|
||||||
|
public class ReportController {
|
||||||
|
|
||||||
|
private final ReportService reportService;
|
||||||
|
|
||||||
|
public ReportController(ReportService reportService) {
|
||||||
|
this.reportService = reportService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/contract-sn")
|
||||||
|
public List<ContractSnReportRow> getContractSnReport(
|
||||||
|
@RequestParam(value = "projectId", required = false) Long projectId,
|
||||||
|
@RequestParam(value = "contractId", required = false) Long contractId) {
|
||||||
|
return reportService.getContractSnReport(projectId, contractId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/callback-stats")
|
||||||
|
public CallbackStatsResponse getCallbackStats(
|
||||||
|
@RequestParam(value = "from", required = false) String from,
|
||||||
|
@RequestParam(value = "to", required = false) String to) {
|
||||||
|
return reportService.getCallbackStats(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/project-health")
|
||||||
|
public List<ProjectHealthRow> getProjectHealth() {
|
||||||
|
return reportService.getProjectHealth();
|
||||||
|
}
|
||||||
|
}
|
||||||
+131
@@ -0,0 +1,131 @@
|
|||||||
|
package cn.craftlabs.platform.api.service;
|
||||||
|
|
||||||
|
import cn.craftlabs.platform.api.persistence.callback.PlatformCallbackInbox;
|
||||||
|
import cn.craftlabs.platform.api.persistence.callback.PlatformCallbackInboxMapper;
|
||||||
|
import cn.craftlabs.platform.api.persistence.contract.PlatformContract;
|
||||||
|
import cn.craftlabs.platform.api.persistence.contract.PlatformContractLine;
|
||||||
|
import cn.craftlabs.platform.api.persistence.contract.PlatformContractLineMapper;
|
||||||
|
import cn.craftlabs.platform.api.persistence.contract.PlatformContractMapper;
|
||||||
|
import cn.craftlabs.platform.api.persistence.customer.PlatformCustomer;
|
||||||
|
import cn.craftlabs.platform.api.persistence.customer.PlatformCustomerMapper;
|
||||||
|
import cn.craftlabs.platform.api.persistence.license.PlatformLicenseSn;
|
||||||
|
import cn.craftlabs.platform.api.persistence.license.PlatformLicenseSnMapper;
|
||||||
|
import cn.craftlabs.platform.api.persistence.project.PlatformProject;
|
||||||
|
import cn.craftlabs.platform.api.persistence.project.PlatformProjectMapper;
|
||||||
|
import cn.craftlabs.platform.api.web.dto.CallbackStatsResponse;
|
||||||
|
import cn.craftlabs.platform.api.web.dto.ContractSnReportRow;
|
||||||
|
import cn.craftlabs.platform.api.web.dto.ProjectHealthRow;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ReportService {
|
||||||
|
|
||||||
|
private final PlatformContractMapper contractMapper;
|
||||||
|
private final PlatformContractLineMapper contractLineMapper;
|
||||||
|
private final PlatformLicenseSnMapper licenseSnMapper;
|
||||||
|
private final PlatformCallbackInboxMapper callbackInboxMapper;
|
||||||
|
private final PlatformProjectMapper projectMapper;
|
||||||
|
private final PlatformCustomerMapper customerMapper;
|
||||||
|
|
||||||
|
public ReportService(
|
||||||
|
PlatformContractMapper contractMapper,
|
||||||
|
PlatformContractLineMapper contractLineMapper,
|
||||||
|
PlatformLicenseSnMapper licenseSnMapper,
|
||||||
|
PlatformCallbackInboxMapper callbackInboxMapper,
|
||||||
|
PlatformProjectMapper projectMapper,
|
||||||
|
PlatformCustomerMapper customerMapper) {
|
||||||
|
this.contractMapper = contractMapper;
|
||||||
|
this.contractLineMapper = contractLineMapper;
|
||||||
|
this.licenseSnMapper = licenseSnMapper;
|
||||||
|
this.callbackInboxMapper = callbackInboxMapper;
|
||||||
|
this.projectMapper = projectMapper;
|
||||||
|
this.customerMapper = customerMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<ContractSnReportRow> getContractSnReport(Long projectId, Long contractId) {
|
||||||
|
LambdaQueryWrapper<PlatformContract> q = Wrappers.lambdaQuery(PlatformContract.class)
|
||||||
|
.eq(projectId != null, PlatformContract::getProjectId, projectId)
|
||||||
|
.eq(contractId != null, PlatformContract::getId, contractId)
|
||||||
|
.orderByDesc(PlatformContract::getId);
|
||||||
|
List<PlatformContract> contracts = contractMapper.selectList(q);
|
||||||
|
List<ContractSnReportRow> rows = new ArrayList<>();
|
||||||
|
for (PlatformContract contract : contracts) {
|
||||||
|
String customerName = resolveCustomerName(contract.getCustomerId());
|
||||||
|
LambdaQueryWrapper<PlatformContractLine> lineQ = Wrappers.lambdaQuery(PlatformContractLine.class)
|
||||||
|
.eq(PlatformContractLine::getContractId, contract.getId());
|
||||||
|
List<PlatformContractLine> lines = contractLineMapper.selectList(lineQ);
|
||||||
|
for (PlatformContractLine line : lines) {
|
||||||
|
LambdaQueryWrapper<PlatformLicenseSn> snQ = Wrappers.lambdaQuery(PlatformLicenseSn.class)
|
||||||
|
.eq(PlatformLicenseSn::getContractLineId, line.getId());
|
||||||
|
List<PlatformLicenseSn> sns = licenseSnMapper.selectList(snQ);
|
||||||
|
int issuedCount = sns.size();
|
||||||
|
int activatedCount = (int) sns.stream().filter(sn -> "ACTIVATED".equals(sn.getStatus())).count();
|
||||||
|
int expectedCount = line.getQuantity() != null ? line.getQuantity().intValue() : 0;
|
||||||
|
int gapCount = Math.max(0, expectedCount - issuedCount);
|
||||||
|
|
||||||
|
ContractSnReportRow row = new ContractSnReportRow();
|
||||||
|
row.setContractId(contract.getId());
|
||||||
|
row.setContractTitle(contract.getTitle());
|
||||||
|
row.setCustomerName(customerName);
|
||||||
|
row.setLineItemName(line.getItemName());
|
||||||
|
row.setExpectedCount(expectedCount);
|
||||||
|
row.setIssuedCount(issuedCount);
|
||||||
|
row.setActivatedCount(activatedCount);
|
||||||
|
row.setGapCount(gapCount);
|
||||||
|
row.setStatus(gapCount > 0 ? "缺额" : "正常");
|
||||||
|
rows.add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public CallbackStatsResponse getCallbackStats(String from, String to) {
|
||||||
|
List<PlatformCallbackInbox> all = callbackInboxMapper.selectList(Wrappers.lambdaQuery(PlatformCallbackInbox.class));
|
||||||
|
long totalEvents = all.size();
|
||||||
|
long processedCount = all.stream().filter(c -> "PROCESSED".equals(c.getStatus())).count();
|
||||||
|
long pendingCount = all.stream().filter(c -> "PENDING".equals(c.getStatus())).count();
|
||||||
|
double successRate = totalEvents > 0 ? (double) processedCount / totalEvents * 100 : 0.0;
|
||||||
|
|
||||||
|
Map<String, Long> typeGroup = all.stream()
|
||||||
|
.collect(Collectors.groupingBy(PlatformCallbackInbox::getEventType, Collectors.counting()));
|
||||||
|
List<Map<String, Object>> eventTypeDistribution = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, Long> entry : typeGroup.entrySet()) {
|
||||||
|
Map<String, Object> item = new HashMap<>();
|
||||||
|
item.put("eventType", entry.getKey());
|
||||||
|
item.put("count", entry.getValue());
|
||||||
|
eventTypeDistribution.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
CallbackStatsResponse resp = new CallbackStatsResponse();
|
||||||
|
resp.setTotalEvents(totalEvents);
|
||||||
|
resp.setSuccessRate(successRate);
|
||||||
|
resp.setPendingCount(pendingCount);
|
||||||
|
resp.setEventTypeDistribution(eventTypeDistribution);
|
||||||
|
resp.setTopFailureReasons(new ArrayList<>());
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<ProjectHealthRow> getProjectHealth() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveCustomerName(Long customerId) {
|
||||||
|
if (customerId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
PlatformCustomer c = customerMapper.selectById(customerId);
|
||||||
|
return c != null ? c.getName() : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
package cn.craftlabs.platform.api.web.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CallbackStatsResponse {
|
||||||
|
|
||||||
|
private long totalEvents;
|
||||||
|
private double successRate;
|
||||||
|
private long pendingCount;
|
||||||
|
private List<Map<String, Object>> eventTypeDistribution;
|
||||||
|
private List<Map<String, Object>> topFailureReasons;
|
||||||
|
|
||||||
|
public long getTotalEvents() {
|
||||||
|
return totalEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalEvents(long totalEvents) {
|
||||||
|
this.totalEvents = totalEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSuccessRate() {
|
||||||
|
return successRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccessRate(double successRate) {
|
||||||
|
this.successRate = successRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPendingCount() {
|
||||||
|
return pendingCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPendingCount(long pendingCount) {
|
||||||
|
this.pendingCount = pendingCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getEventTypeDistribution() {
|
||||||
|
return eventTypeDistribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventTypeDistribution(List<Map<String, Object>> eventTypeDistribution) {
|
||||||
|
this.eventTypeDistribution = eventTypeDistribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Map<String, Object>> getTopFailureReasons() {
|
||||||
|
return topFailureReasons;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopFailureReasons(List<Map<String, Object>> topFailureReasons) {
|
||||||
|
this.topFailureReasons = topFailureReasons;
|
||||||
|
}
|
||||||
|
}
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
package cn.craftlabs.platform.api.web.dto;
|
||||||
|
|
||||||
|
public class ContractSnReportRow {
|
||||||
|
|
||||||
|
private Long contractId;
|
||||||
|
private String contractTitle;
|
||||||
|
private String customerName;
|
||||||
|
private String lineItemName;
|
||||||
|
private int expectedCount;
|
||||||
|
private int issuedCount;
|
||||||
|
private int activatedCount;
|
||||||
|
private int gapCount;
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
public Long getContractId() {
|
||||||
|
return contractId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContractId(Long contractId) {
|
||||||
|
this.contractId = contractId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContractTitle() {
|
||||||
|
return contractTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContractTitle(String contractTitle) {
|
||||||
|
this.contractTitle = contractTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCustomerName() {
|
||||||
|
return customerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomerName(String customerName) {
|
||||||
|
this.customerName = customerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLineItemName() {
|
||||||
|
return lineItemName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineItemName(String lineItemName) {
|
||||||
|
this.lineItemName = lineItemName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExpectedCount() {
|
||||||
|
return expectedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpectedCount(int expectedCount) {
|
||||||
|
this.expectedCount = expectedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIssuedCount() {
|
||||||
|
return issuedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIssuedCount(int issuedCount) {
|
||||||
|
this.issuedCount = issuedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getActivatedCount() {
|
||||||
|
return activatedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivatedCount(int activatedCount) {
|
||||||
|
this.activatedCount = activatedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGapCount() {
|
||||||
|
return gapCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGapCount(int gapCount) {
|
||||||
|
this.gapCount = gapCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package cn.craftlabs.platform.api.web.dto;
|
||||||
|
|
||||||
|
public class ProjectHealthRow {
|
||||||
|
|
||||||
|
private Long projectId;
|
||||||
|
private String projectName;
|
||||||
|
private double deliveryRate;
|
||||||
|
private double snIssuedRate;
|
||||||
|
private double activationRate;
|
||||||
|
private String healthLevel;
|
||||||
|
|
||||||
|
public Long getProjectId() {
|
||||||
|
return projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProjectId(Long projectId) {
|
||||||
|
this.projectId = projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProjectName() {
|
||||||
|
return projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProjectName(String projectName) {
|
||||||
|
this.projectName = projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getDeliveryRate() {
|
||||||
|
return deliveryRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeliveryRate(double deliveryRate) {
|
||||||
|
this.deliveryRate = deliveryRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSnIssuedRate() {
|
||||||
|
return snIssuedRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSnIssuedRate(double snIssuedRate) {
|
||||||
|
this.snIssuedRate = snIssuedRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getActivationRate() {
|
||||||
|
return activationRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivationRate(double activationRate) {
|
||||||
|
this.activationRate = activationRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHealthLevel() {
|
||||||
|
return healthLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHealthLevel(String healthLevel) {
|
||||||
|
this.healthLevel = healthLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user