Test #1

Merged
admin merged 1726 commits from test into main 2026-09-17 11:52:45 +08:00
7 changed files with 39 additions and 19 deletions
Showing only changes of commit f2877df697 - Show all commits
@@ -114,6 +114,7 @@ public class AuthService {
.subject(account.getId().toString())
.claim("user_id", account.getId())
.claim("username", account.getUsername())
.claim("display_name", account.getDisplayName() == null ? "" : account.getDisplayName())
.claim("tenant_id", account.getDefaultTenantId())
.claim("operator_tenant_id", account.getOperatorTenantId())
.claim("membership_id", account.getDefaultMembershipId())
@@ -176,7 +177,7 @@ public class AuthService {
JwtClaimsSet claims = JwtClaimsSet.builder().issuer(properties.issuer())
.audience(List.of(properties.audience())).id(jwtId)
.issuedAt(issuedAt).expiresAt(expiresAt).subject(account.getId().toString())
.claim("user_id", account.getId()).claim("username", account.getUsername())
.claim("user_id", account.getId()).claim("username", account.getUsername()).claim("display_name", account.getDisplayName() == null ? "" : account.getDisplayName())
.claim("tenant_id", account.getDefaultTenantId()).claim("operator_tenant_id", account.getOperatorTenantId())
.claim("membership_id", account.getDefaultMembershipId()).claim("app_code", "MERCHANT")
.claim("client_type", authorization.getClientType()).claim("token_version", account.getTokenVersion())
@@ -7,12 +7,12 @@ import java.util.Set;
* 统一认证用户主体,携带用户、租户、成员身份、应用端、客户端类型及权限信息。
*/
public record AuthenticatedUser(Long userId, Long tenantId, Long operatorTenantId, Long membershipId,
String username, String appCode, String clientType,
String username, String displayName, String appCode, String clientType,
Set<String> permissions, boolean impersonated, Long actorUserId,
Long actorMembershipId, boolean passwordChangeRequired) implements Principal {
public AuthenticatedUser(Long userId, Long tenantId, Long operatorTenantId, Long membershipId,
String username, String appCode, String clientType, Set<String> permissions) {
this(userId, tenantId, operatorTenantId, membershipId, username, appCode, clientType,
this(userId, tenantId, operatorTenantId, membershipId, username, null, appCode, clientType,
permissions, false, null, null, false);
}
public AuthenticatedUser {
@@ -37,6 +37,7 @@ public class JwtClaimsMapper {
longClaim(jwt, "operator_tenant_id"),
longClaim(jwt, "membership_id"),
username,
firstNonBlankNullable(jwt.getClaimAsString("displayName"), jwt.getClaimAsString("display_name")),
appCode,
jwt.getClaimAsString("client_type"),
permissions,
@@ -86,4 +87,9 @@ public class JwtClaimsMapper {
for (String value : values) if (value != null && !value.isBlank()) return value;
return "unknown";
}
private String firstNonBlankNullable(String... values) {
for (String value : values) if (value != null && !value.isBlank()) return value.trim();
return null;
}
}
@@ -13,8 +13,8 @@ final class FinanceOperatorSnapshot {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof AuthenticatedUser user
&& user.userId() != null && user.userId() == operatorId
&& StringUtils.hasText(user.username())) {
return user.username().trim();
&& (StringUtils.hasText(user.displayName()) || StringUtils.hasText(user.username()))) {
return StringUtils.hasText(user.displayName()) ? user.displayName().trim() : user.username().trim();
}
return null;
}
@@ -41,23 +41,26 @@ public class ReceivableStatisticsService {
LocalDate from = month.atDay(1);
LocalDate to = month.plusMonths(1).atDay(1);
StringBuilder sql = new StringBuilder("""
SELECT tenant_id, customer_name_snapshot,
SUM(total_amount) total_receivable,
SUM(paid_amount) total_received,
SUM(outstanding_amount) total_outstanding
FROM fin_settlement
WHERE direction='RECEIVABLE'
AND status<>'VOIDED'
AND currency_code='CNY'
AND generated_date>=?
AND generated_date<?
SELECT s.tenant_id,
COALESCE(p.customer_name_snapshot, MAX(s.customer_name_snapshot)) customer_name_snapshot,
SUM(s.total_amount) total_receivable,
SUM(s.paid_amount) total_received,
SUM(s.outstanding_amount) total_outstanding
FROM fin_settlement s
LEFT JOIN fin_customer_settlement_profile p
ON p.tenant_id=s.tenant_id AND p.status='ACTIVE'
WHERE s.direction='RECEIVABLE'
AND s.status<>'VOIDED'
AND s.currency_code='CNY'
AND s.generated_date>=?
AND s.generated_date<?
""");
List<Object> args = new ArrayList<>(List.of(from, to));
if (customerId != null) {
sql.append(" AND tenant_id=?");
sql.append(" AND s.tenant_id=?");
args.add(customerId);
}
sql.append(" GROUP BY tenant_id,customer_name_snapshot ORDER BY customer_name_snapshot,tenant_id");
sql.append(" GROUP BY s.tenant_id,p.customer_name_snapshot ORDER BY customer_name_snapshot,s.tenant_id");
return jdbc.query(sql.toString(), (rs, rowNum) -> checked(new ReceivableStatisticsRow(
rs.getLong("tenant_id"), rs.getString("customer_name_snapshot"), CURRENCY,
rs.getBigDecimal("total_receivable"), rs.getBigDecimal("total_received"),
@@ -40,8 +40,8 @@ class ReceivableStatisticsServiceTest {
assertThat(result.records()).containsExactly(rows.get(0));
var sql = org.mockito.ArgumentCaptor.forClass(String.class);
verify(jdbc).query(sql.capture(), any(RowMapper.class), any(Object[].class));
assertThat(sql.getValue()).contains("direction='RECEIVABLE'", "status<>'VOIDED'", "currency_code='CNY'",
"generated_date>=?", "generated_date<?", "GROUP BY tenant_id,customer_name_snapshot");
assertThat(sql.getValue()).contains("s.direction='RECEIVABLE'", "s.status<>'VOIDED'", "s.currency_code='CNY'",
"s.generated_date>=?", "s.generated_date<?", "fin_customer_settlement_profile", "GROUP BY s.tenant_id,p.customer_name_snapshot");
}
@Test
@@ -28,6 +28,16 @@ class FinanceOperatorSnapshotTest {
assertThat(FinanceOperatorSnapshot.currentName(72L)).isNull();
}
@Test
void prefersAuthenticatedDisplayNameOverLoginUsername() {
AuthenticatedUser user = new AuthenticatedUser(71L, null, null, null,
"12555214478", "廖万昌", "MERCHANT", "WEB", Set.of(), false, null, null, false);
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(user, null));
assertThat(FinanceOperatorSnapshot.currentName(71L)).isEqualTo("廖万昌");
}
@Test
void labelsSystemGeneratedEntriesWithoutInventingAnOperator() {
assertThat(FinanceOperatorSnapshot.currentName(0L)).isEqualTo("系统");