This commit is contained in:
2026-08-13 09:49:55 +08:00
parent f3366cb2fa
commit 95849f248f
69 changed files with 1224 additions and 221 deletions
@@ -6,7 +6,11 @@ import com.baiyue.finance.dto.FinanceSettlementDtos.CreateReceivableSettlementRe
import com.baiyue.finance.dto.FinanceSettlementDtos.CreateSettlementPaymentRequest;
import com.baiyue.finance.dto.FinanceSettlementDtos.SettlementDetail;
import com.baiyue.finance.dto.FinanceSettlementDtos.SettlementDetailEnvelope;
import com.baiyue.finance.dto.FinanceSettlementDtos.SettlementListEnvelope;
import com.baiyue.finance.dto.FinanceSettlementDtos.SettlementSummary;
import com.baiyue.finance.service.FinanceSettlementService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.validation.Valid;
import org.slf4j.MDC;
import org.springframework.security.access.AccessDeniedException;
@@ -19,9 +23,11 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
@RestController
@@ -33,6 +39,24 @@ public class FinanceSettlementController {
this.service = service;
}
@GetMapping("/receivable-settlements")
@PreAuthorize("hasAuthority('platform:finance:settlement-ar:view')")
@Operation(summary = "查询正式应收结算单")
public SettlementListEnvelope receivableSettlements(
@Parameter(description = "可选客户筛选;省略时查询全部客户")
@RequestParam(required = false) Long customerId) {
return success(service.listSettlements("RECEIVABLE", customerId));
}
@GetMapping("/payable-settlements")
@PreAuthorize("hasAuthority('platform:finance:settlement-ap:view')")
@Operation(summary = "查询正式应付结算单")
public SettlementListEnvelope payableSettlements(
@Parameter(description = "可选客户筛选;省略时查询全部客户")
@RequestParam(required = false) Long customerId) {
return success(service.listSettlements("PAYABLE", customerId));
}
@PostMapping("/receivable-settlements")
@PreAuthorize("hasAuthority('platform:finance:settlement-ar:create')")
public SettlementDetailEnvelope createReceivableSettlement(
@@ -82,6 +106,14 @@ public class FinanceSettlementController {
return new SettlementDetailEnvelope("200", "success", detail, requestId, traceId, Instant.now());
}
private static SettlementListEnvelope success(List<SettlementSummary> summaries) {
String requestId = first(MDC.get("requestId"), MDC.get("request_id"));
if (!StringUtils.hasText(requestId)) requestId = UUID.randomUUID().toString();
String traceId = first(MDC.get("traceId"), MDC.get("trace_id"));
if (!StringUtils.hasText(traceId)) traceId = requestId;
return new SettlementListEnvelope("200", "success", summaries, requestId, traceId, Instant.now());
}
private static String first(String first, String second) {
return StringUtils.hasText(first) ? first : second;
}
@@ -70,24 +70,6 @@ public class PlatformFinanceController {
return FinanceResponses.success(queryService.statements(customerId, false));
}
@GetMapping("/receivable-settlements")
@PreAuthorize("hasAuthority('platform:finance:bill:view')")
@Operation(summary = "结算单应收")
public ApiResponse<?> receivableSettlements(
@Parameter(description = "可选客户筛选;省略时查询全部客户")
@RequestParam(required = false) Long customerId) {
return FinanceResponses.success(queryService.receivableSettlements(customerId, false));
}
@GetMapping("/payable-settlements")
@PreAuthorize("hasAuthority('platform:finance:cost:view')")
@Operation(summary = "结算单应付")
public ApiResponse<?> payableSettlements(
@Parameter(description = "可选客户筛选;省略时查询全部客户")
@RequestParam(required = false) Long customerId) {
return FinanceResponses.success(queryService.payableSettlements(customerId));
}
@PostMapping(value = "/vouchers", consumes = "multipart/form-data")
@PreAuthorize("hasAnyAuthority('platform:finance:receipt:create','platform:finance:cost:create')")
public ApiResponse<FinanceFileClient.Metadata> uploadVoucher(@AuthenticationPrincipal AuthenticatedUser user,
@@ -42,6 +42,8 @@ public final class FinanceSettlementDtos {
public record SettlementDetail(@JsonUnwrapped SettlementSummary summary, List<SettlementLine> lines,
List<SettlementTransaction> transactions,
List<SettlementRevision> revisions) {}
public record SettlementListEnvelope(String code, String message, List<SettlementSummary> data,
String requestId, String traceId, Instant timestamp) {}
public record SettlementDetailEnvelope(String code, String message, SettlementDetail data,
String requestId, String traceId, Instant timestamp) {}
}
@@ -193,6 +193,27 @@ public class FinanceSettlementService {
return new SettlementDetail(summary, lines, transactions, List.copyOf(revisions));
}
public List<SettlementSummary> listSettlements(String direction, Long customerId) {
if (!Set.of("RECEIVABLE", "PAYABLE").contains(direction)) {
throw error("FIN_400", "结算单方向无效");
}
if (customerId != null && customerId <= 0) {
throw error("FIN_400", "客户范围无效");
}
String sql = "SELECT id,tenant_id,settlement_no,direction,customer_name_snapshot,supplier_id," +
"supplier_name_snapshot,reconciliation_statement_id,business_period,currency_code,total_amount," +
"paid_amount,outstanding_amount,generated_date,due_date,payment_status,status,version " +
"FROM fin_settlement WHERE direction=?";
List<Object> args = new ArrayList<>();
args.add(direction);
if (customerId != null) {
sql += " AND tenant_id=?";
args.add(customerId);
}
sql += " ORDER BY generated_date DESC,id DESC";
return jdbc.queryForList(sql, args.toArray()).stream().map(this::summary).toList();
}
@Transactional
public SettlementDetail createSettlementPayment(long settlementId, long operatorId, String key,
CreateSettlementPaymentRequest request) {